对于二叉查找树而言,假设该二叉查找树是整数数组。其后序遍历需要满足以下三个特点:
- 数组最后一个数字是二叉查找树的根节点。
- 数组的前半部分是二叉查找树的左子树,它们的值都比该树的根节点小。
- 数组中靠后部分(除了最后一个元素外)是二叉查找树右子树结点的值,它们的值比根节点的值大。
而且以上三个特性对于一个二叉查找树而言,是递归的。
举例如下:
有一个二叉查找树,存储着字符‘A’,’B’,‘C’,’D’,‘E’,’F’,‘G’,’H’,下面哪个结果是后序树遍历的结果。
- A ADBCEGFH
- B BCAGEHFD
- C BCAEFDHG
- D BDACEFHG
这个问题答案是 C 。
解答:对于A而言:首先H是根节点,其左子树为(ADBCEGF),右子树为()。对于子树(ADBCEGF)而言,F是根节点,其左子树为(ADBCE),右子树为(G)。对于子树(ADBCE)而言,E是根节点,其左子树为(ADBC),右子树为()。对于子树(ADBC)而言,C是根节点,其左子树为(A),右子树为(DB),由于后序二叉树的右子树的元素都应该大于根节点。但是这里右子树(DB)中的B小于其根节点C,所以该选项错误。
对于B而言:首先D是根节点,(BCA)是左子树,(GEHF)是右子树。对于子树(GEHF)而言,F是根节点,其左子树为(),右子树为(GEH),但是E小于F,所以该选项错误(违反了特性三)。
对于C而言:首先G是根节点,(BCAEFD)是左子树,(H)是右子树。对于子树(BCAEFD)而言,D是根节点,(BCA)是左子树,(EF)是右子树。对于子树(BCA)而言,其左子树为(),右子树为(BC)。对于子树(EF)而言,根节点为F,左子树为(E),右子树为()。对于子树(BC)而言,根节点为C,左子树为(B),右子树为()。
对于D而言:首先G是根节点,其左子树为(BDACEF),右子树为(H)。对于子树(BDACEF)而言,根节点为F,其左子树为(BDACE),右子树为()。对于子树(BDACE)而言,E为根节点,(BDAC)是左子树,()为右子树。对于子树(BDAC)而言,C是根节点,其左子树为(B),右子树为(DA),但是A<根节点C,所以该树不是后序二叉树(违反了特性三)。
例题2: 输入一个整数数组,判断该数组是不是某二叉查找的后序遍历的结果
//
// main.cpp
// PostSequenceOfBST
// 输入一个整数数组,判断该数组是不是某二叉查找树的后序遍历的结果。假设该数组中的元素不重复
// Created by 胡士伟 on 16/6/10.
// Copyright © 2016年 胡士伟. All rights reserved.
//
#include <iostream>
using namespace std;
bool PostSequenceOfBST(int sequence[],int length)
{
if(sequence==NULL || length<=0)
return false;
int root=sequence[length-1];
int i=0;
for(;i<length-1;i++)
{
if(sequence[i]>root)
break;
}
//搜索右子树的节点
int j=i;
for(;j<length-1;++j)
{
if(sequence[j]<root)
{
return false;
}
}
//递归判断左子树是否为二叉查找树
bool left=true;
if(i>0)
{
left=PostSequenceOfBST(sequence, i);
}
//递归判断右子树是否为二叉查找树
bool right=true;
if(j<length-1)
{
right=PostSequenceOfBST(sequence+i, length-1-i);
}
return left&&right;
}
int main(int argc, const char * argv[]) {
// insert code here…
cout<<“请输入数组:“<<endl;
int s[7];
for(int i=0;i<7;i++)
{
cin>>s[i];
}
bool result=PostSequenceOfBST(s, 6);
if(result)
cout<<“该数组是二叉查找树的后序遍历“<<endl;
else
cout<<“该数组不是二叉查找树的后序遍历“<<endl;
return 0;
}
运行结果如下:
请输入数组:
5 7 6 9 11 10 8
该数组是二叉查找树的后序遍历
Program ended with exit code: 0