zoukankan      html  css  js  c++  java
  • 面试100题系列之12判断序列是不是查找二叉树的后序编列

    题目描述:判断整数序列是不是二元查找树的后序遍历结果
    输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
    如果是返回true,否则返回false。
    例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
    8
    / \
    6 10
    / \ / \
    5 7 9 11 因此返回true。
    如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
    思路分析:
    查找二叉树的特点就是左子树中的节点一定比根节点小,右子树中的节点一定比根节点大。OK,那用根节点就可以将数组分成两部分。步骤如下:
    *从前往后遍历,找到第一个大于根节点的数。
    *从这个数往后,判断是不是所有的在根节点以前的数都大于根节点,如果不是,那就不可能是查找二叉树的后序遍历结果。
    *如果前面两个步骤都没问题,那就分别再判断左子树和右子树是否合法。
    题目扩展:其实这道题考的就是树的重建。另一种方式就是利用树的前序遍历和中序遍历,重建二叉树,最后输出树的后序遍历。
    1、首先给出递归的解法,如果是递归的话,找到左子树和右子树之后,就改变参数就可以了。参考代码如下:

    //给出递归的解法
    bool PostOrderToBst(int *arr, int nLen)
    {
    	if(!arr || nLen < 1)
    		return false;
    	int i;
    	for(i = 0; i < nLen - 1; ++i)
    	{
    		if(arr[i] > arr[nLen - 1])
    			break;
    	}
    	for(int j = i + 1; j < nLen - 1; ++j)
    	{
    		if(arr[j] < arr[nLen - 1])
    			return false;
    	}
    	bool Left = true;
    	bool Right = true;
    	if(i > 1)//i为左子树节点的个数,小于2可以忽略
    		Left = PostOrderToBst(arr, i);
    	if(nLen - i > 1)//nLen-i为右子树节点的个数,小于2可以忽略
    		Right = PostOrderToBst(arr, nLen - i);
    	return Left && Right;
    }

    2、如果用非递归来做,那么就用一个辅助栈来保存中间的结果,然后解决的思路不变,参考代码如下:

    //利用辅助栈完成判断
    const int N = 30;
    bool JudgePostOrder(int *arr, int nLen)
    {
    	if(!arr || nLen < 1)
    		return false;
    	int stack[N][2];
    	int top = 0;
    	int Begin, End,i,j;
    	stack[0][0] = 0;
    	stack[0][1] = nLen - 1;
    	while(top > -1)
    	{
    		Begin = stack[top][0];
    		End = stack[top][1];
    		--top;
    		for(i = Begin; i < End; ++i)
    		{
    			if(arr[i] > arr[End])
    				break;
    		}
    		for(j = i + 1; j < End; ++j)
    		{
    			if(arr[j] < arr[End])
    				return false;
    		}
    		//i - Begin为左子树节点的个数,小于2可以忽略
    		if(i - Begin > 1)
    		{
    			stack[++top][0] = Begin;
    			stack[top][1] = i - 1;
    		}
    		//End - Begin + 1 - i为右子树节点的个数,小于2可以忽略
    		if(End - Begin > i)
    		{
    			stack[++top][0] = i;
    			stack[top][1] = End - 1;
    		}
    	}//end while
    	return true;
    }

    3、最后给出main函数的调用方法,不需要的可以直接pass。

    #include<stdio.h>
    int main()
    {
    	int arr[N];
    	int n,i;
    	bool IsPostOrder;
    	while(scanf("%d", &n) != EOF)
    	{
    		for(i = 0; i < n; ++i)
    			scanf("%d", &arr[i]);
    		IsPostOrder = PostOrderToBst(arr, n);
    		if(IsPostOrder)
    			printf("递归:Yes\n");
    		else
    			printf("递归:No\n");
    		IsPostOrder = JudgePostOrder(arr, n);
    		if(IsPostOrder)
    			printf("非递归:Yse\n");
    		else
    			printf("非递归:No\n");
    	}
    }




  • 相关阅读:
    Nginx+keepalived高可用配置
    kubespahere安装kubenetes
    Fastdfs原理及集群搭建
    Spark 3.0.3集群安装文档
    Mybatis Plus 代码生成器
    redis集群方案
    Go 语言并发之道
    重构-改善即有代码的设计
    QT线程
    QT中的cout
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3052924.html
Copyright © 2011-2022 走看看