您的位置:首页 > 职场人生

《剑指Offer》面试题:判读数组是否是某二叉搜索树的后序遍历

2015-10-07 10:30 399 查看
题目描述:

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

思路

/*

注意两点

1)二叉搜索树的特点: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

2)而后续遍历是根据 “左右根节点”的顺序来得到的;因此后序遍历中的最后一个元素就是根节点

因此:从以上两点我们可以得到:当判断该数组是不是某二叉搜索树的后序遍历的结果时,

只需要先判断该数组的最后一个元素(即根节点)是否满足二叉搜索树的性质(即上面提到的注意点1)。如果不满足,则说明此数组不是某二叉搜索树的后序遍历

如果满足,则在数组中找出根节点的左右子数的分界点将其分为两个子数组继续进行判断,即采用递归来完成即可。

*/

实现代码如下:

/*

输入:
每个测试案例包括2行:

第一行为1个整数n(1<=n<=10000),表示数组的长度。

第二行包含n个整数,表示这个数组,数组中的数的范围是[0,100000000]。

输出:
对应每个测试案例,如果输入数组是某二叉搜索树的后序遍历的结果输出Yes,否则输出No。

样例输入:
7
5 7 6 9 11 10 8
4
7 4 6 5
样例输出:
Yes
No*/

#include<stdio.h>
#include<stdlib.h>
/*
参数的说明
@param arr:数组的指针,保存着一串序列
@param len:数组的长度
*/
bool isPost_traversal(int *arr,int len ){
//首先判断此数组是否有效
if(arr==NULL||len<=0){
return false;
}

//判断此数组是否满足二叉搜索树的性质
int root=arr[len-1];//根节点的值

//第一步:先找到第一个大于root节点值的位置
int i=0;
for(;i<len-1;i++){
if(arr[i]>root){//即找到左右子树的分界点的下标
break;
}
}
//保存右子树的下标
int rightStartIndex=i;

//第二步:然后继续判断分界点后面是否全部大于此根节点,若大于,则根据分界点i将数组为分为两个子数组继续递归,否则可以判断此数组不是某二叉搜索树的后序遍历
for(int j=i+1;j<len-1;j++){
if(arr[j]<root){
return false;
}
}
//第三步:继续递归
bool left=true;
if(rightStartIndex>0){//只有右子树的起点大于0,此树才有左子树
left=isPost_traversal(arr,rightStartIndex);
}
bool right=true;
if(rightStartIndex<len-1){
right=isPost_traversal(arr+i,len-1-rightStartIndex) ;
}

return (left&&right);//只有当左右子树全部是true时,才返回true;

}

int main(void){
int n;
while(scanf("%d",&n)!=EOF){
if(n>0) {
int *arr=(int *)malloc(n*sizeof(int));
int val;
//接收n个数字并保存在数组中
for(int i=0;i<n;i++){
scanf("%d",&val);
arr[i]=val;
}

//判断该数组是否是某二叉搜索树的后序遍历

if(isPost_traversal(arr,n)) {
printf("YES");
}
else{
printf("NO");
}

}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: