好久没更新了,发一道水题。
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
逻辑分析:这道题表面上看,难度貌似挺大的,不过经过细心分析后,就会发现,根本就是纸老虎。
1、首先考虑后序遍历特点,后序遍历得到的数组,最后一个元素一定是根。
2、但凡是树的问题,一般都是首先考虑递归,因为树本身就是递归定义的。
3、既然a[n-1]是根节点,根据二叉查找树的特点,右子树大于根,左子树小于根,所以,只需要固定a[n-1],然后从头划分左子树区域,判定右子树区域是否满足二叉查找树的特点即可达成目的。
4、简单的来说,比如5、7、6、9、11、10、8,根节点是8,那么我们从a[0]开始,可以遍历出5 7 6是左子树部分,那么后面的所有元素就要满足是右子树的条件,9 11 10显然大于8,那么初步判定有效,继续递归判断左子树右子树。
下面给出源码实现:
/************************************************************************/
/*
判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/
\
6
10
/
\ / \
5
7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
思路:后序遍历结果数组的最后一个元素为根节点。
根节点的左子树全部小于根节点
根节点的右子树全部大于根节点
递归遍历左右子树是否二叉树
*/
/************************************************************************/
#include
<iostream>
using
namespace
std;
bool
isResultOfBST(
int
*
array,
int
length);
int
main()
{
int
array[7]={5,7,6,9,11,10,8};
if
(isResultOfBST(array,7))
{
cout<<
"yes"
<<endl;
}
else
{
cout<<
"no"
<<endl;
}
}
bool
isResultOfBST(
int
*
array,
int
length)
{
if
(array==NULL||length==0)
{
return
false
;
}
bool
result=
true
;
int
root=array[length-1];
int
i=0;
for
(;i<length-1;i++)
{
if
(array[i]>root)
{
break
;
}
}
int
j=i;
//根节点左右子树分界点
for
(;j<length-1;j++)
{
if
(array[j]<root)
{
return
false
;
}
}
//递归遍历
bool
lReult=
true
,rResult=
true
;
if
(i>0)
{
lReult=isResultOfBST(array,i);
}
if
(i<length-1)
{
rResult=isResultOfBST(array+i,length-i-1);
}
return
(lReult&&rResult);
}
再附上两个版本,根据自己逻辑风格,进行选择:
#include<iostream>
using namespace std;
void test(const int data[],int start,int node,bool &flag){
if(flag&&start<node){ // 判断条件,注意start<node
int left=start;
while(data[node]>data[left]){ //取得其左子树
left++;
}
for(int j=left;j<node;j++){ //判断是否为其右子树
if(data[j]<data[node]) {flag=false; return;} //若
}
test(data,0,left-1,flag); //递归
test(data,left,node-1,flag);
}
}
int main(void){
bool flag=true;
int a[]={5,7,6,9,11,10,8};
test(a,0,6,flag);
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
int b[]={7,4,6,5};
test(b,0,3,flag);
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
system("pause");
return 0;
}
#include<iostream>
using namespace std;
bool test(const int data[],int start,int node)
{
if(start<node)
{
int left=start;
while(data[node]>data[left])
left++;
for(int j=left;j<node;j++)
{
if(data[j]<data[node])
{
printf("不行1!\n");
return false;
}
}
if(!test(data,0,left-1))
{
printf("不行2!\n");
return false;
}
else if(!test(data,left,node-1))
{
printf("不行3!\n");
return false;
}
else
return true;
}
return true;
}
int main(){
bool flag;
int a[]={5,7,6,9,11,10,8};
flag = test(a,0,6);
if(flag)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
int b[]={7,4,6,5};
flag = test(b,0,3);
if(flag)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
system("pause");
return 0;
}