如果是返回 true,否则返回 false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回 true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false。
解答:后续遍历的最后一个点是根结点。有由于是排序树,左子树比根小,右子树比根大。根节点的值必定不是最值。
如5、7、6、9、11、10、8,最后一个是8,则可以分为左右子树:左子树:5,7,6 右子树:11,10,8
在左子树中,6是根结点,5<6因此是左子树,7>6因此是右子树,满足排序树的后续遍历。11,10,8同理。
而7、4、6、5中,由于7>5,因此7、4、6都是右子树,但是4<5不满足右子树的值大于根结点的值,因此不是排序树。
思路:
1、先根据根结点,把数组分成左右子树,怎么分呢,设一个指针k指向数组第0个元素,当该元素小于根结点的值,指针向后移动,直至指向的元素大于根结点。这样就分为了左右子树。如果没有分成功,即k要么仍指向首元素,要么指向最后一个元素,直接返回false;
2、当分成功后,如果右子树中出现比根结点值小的,不满足排序树条件,返回false;
3、分别对左右子树判断,递归实现,直至剩下一个或两个结点。
程序:
#include <iostream> using namespace std; //二叉排序树的后续遍历的最后一个是根,是中间值 int check(int a[],int first,int last) { int i=first; int j=last; //递归的结束条件:仅剩下两个/一个元素,就不需要遍历了。 if(j-i<=1) return 1; else { int k=i;//k用来指向右子树 while(k<j && a[k]<=a[j]) { k++; } cout<<"k i j "<<k<<i<<j<<endl; if(k==j || k==i)//根结点不是中间值 return 0; else { for(int t=k+1;t<j;t++) { if(a[t]<a[j])//在右子树中没有比根小的值 return 0; } } return check(a,i,k-1);//对左子树判断 return check(a,k,j-1);//对右子树判断 } } void main() { //int a[7]={5,7,6,9,11,10,8}; //int a[]={7,4,6,5}; int a[]={9,8,7,11,15,12,10}; int n=sizeof(a)/4; cout<<check(a,0,n-1)<<endl; system("pause"); }