您的位置:首页 > 编程语言 > C语言/C++

算法—判断整数序列是不是二元查找树的后序遍历结果

2015-09-08 18:18 288 查看
BST性质:节点左子树的任意节点小于根节点,右子树的任意节点大于等于根节点

后序遍历顺序:左——右——根

这个顺序很重要。由这个可以得知。对于任何一棵BST来说,后续遍历序列的最后一个数就是根节点。除此之外,左子树的所有节点在序列的前部,右子树的所有节点在序列的右部。注意到了这个,问题就没那么复杂了。

来分析这个后序序列:5,7,6,9,11,10,8

假设它是个BST的后续遍历序列。那8就是这棵BST的根节点。左子树节点为:5,7,6。右子树节点为:9,11,10。

进一步分析左子树和右子树。

对于左子树:5,7,6。根节点为6,左子树为5。右子树为7。

对于右子树:9,11,10。根节点为10,左子树为9,右子树为11。

因此这个BST为:

                            8

                        ↙   ↘

                      6         10

                 ↙   ↘   ↙   ↘

               5         7  9        11

再来考虑后序序列:7,4,6,5。

同样假设它是一棵BST。那么5就是根节点。由于左子树节点都比根节点的小,且分布在序列前部。但是序列第一个节点为7,所以如果BST成立,则这棵BST的根节点没有左子树。因此右子树节点就是7,4,6。但是,由于右节点都大于或等于根节点。7,4,6明显不满足。因此这个序列不可能构成一棵BST。

总结一下。其实算法的思路就是:

1. 从初始序列开始,通过最后一个节点(根节点)将序列分割为左子树部分和右子树部分。

2. 判断左子树部分的所有节点是否都小于根节点,判断右子树的所有节点是否都大于或等于根节点。

3. 如果2成立,则对左右子树进行递归(和快排很像)。否则算法停止。

4. 如果递归到叶子节点,算法都未停止则返回true。表示这个序列是某一BST的后序遍历序列。

代码如下:

#include <iostream>
using namespace std;

template <class T>
bool isBST(T *array,int size);

template <class T>
int rightPartPos(T *array,int size);

int main()
{
int array1[7]={5,7,6,9,11,10,8};
cout<<isBST(array1,8)<<endl;
int array2[4]={7,4,6,5};
cout<<isBST(array2,4)<<endl;
return 0;
}

template <class T>
bool isBST(T *array,int size)
{
//递归到根节点
if(size<=1)
{
return true;
}
//没有递归到根节点
else
{
//分割左右子树,返回值为右子树部分开始的位置
int pos=rightPartPos(array,size);
//右子树部分的节点中存在小于根节点的节点
if(pos<0)
{
return false;
}
else
{
//遍历,检查左、右子树
return isBST(array,pos)&&isBST(array+pos,size-pos-1);
}
}
}

template <class T>
int rightPartPos(T *array,int size)
{
T root=*(array+size-1);
for(int i=0;i<size-1;i++)
{
//当遇到小于根节点的节点继续往后找
if(root>*(array+i))
{
continue;
}
//第一个大于或等于根节点的节点
//此时i位置的节点就是右子树部分的第一个节点
else
{
//判断右子树部分的节点是否大于或等于根节点
for(int j=i+1;j<size-1;j++)
{
//右子树部分节点中存在小于根节点的节点。BST不成立
if(*(array+j)<root)
{
return -1;
}
}
return i;	//返回右子树开始的位置
}
}
return size-1;	//表示没有右子树
}

如果是给出前序遍历的序列,其实就是根节点在最前面。算法的其他部分还是一样。至于给出中序遍历的序列,只要是递增的就行了~

如果有什么不对的地方欢迎指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 C++ 二叉树 遍历