数据结构与算法面试题80道(9)
第9题
判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
开始把题看错了,打算建一颗二叉树,后续遍历,然后比较。。。
后来发现原来是判断一个数组能不能是一个二叉树的后续遍历的结果。
想想后序遍历的特点,先遍历左子树,再遍历右子树,最后遍历结点,说明什么?!
数组应该是由比根小的数+比跟大的数+根的值组成。
树的子树的后序遍历的数组有什么特点?!数组应该是由比根小的数+比跟大的数+根的值组成。
没错,可以用递归,只要所有的子树都满足,那么它就可以是一个二叉树的后序数组。
#include<cstdio> #include<iostream> using namespace std; //是否是其中的一段 bool has(const int data[],int length){ int i,j; if(data==NULL||length<=0) return false; int root=data[length-1]; for(i=0;i<length-1;i++)//找到第一个大于root的结点 if(data[i]>root) break; for(j=i;j<length-1;j++)//如果存在比root小的则不是后序遍历 if(data[j]<root) return false;
//运行到这里,说明从整个树看来他是可以成为后序数组的。下面就要分左右开检测是否也能成为后序//数组。 //如果符合要求,则分别在查找树的左右子树查找。 bool left=true; if(i>0) left=has(data,i); bool right=true; if(i<length-1) right=has(data+i,length-i-1); //所有的左右子树上都符合要求,那么是它可以构成一个二叉树的后续遍历数组 return (left&&right); } int main(){
//测试 int s1[]={5,7,6,9,11,10,8}; int s2[]={7,4,6,5,8}; int length1=sizeof(s1)/sizeof(int); int length2=sizeof(s2)/sizeof(int); if(has(s1,length1)) printf("yes,s1 is the post-order traversal.\n"); else printf("no,s1 is not the post-order traversal.\n"); if(has(s2,length2)) printf("yes,s2 is the post-order traversal.\n"); else printf("no,s2 is not the post-order traversal.\n"); return 0; }