题目:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false,假设输入的数组的任意两个数字都互不相同。
例如例如输入数组{5,7,6,9,11,10,8}则返回TRUE,因为这个整数序列式的二叉搜索树如图
如果输入数组是{7,4,6,5},那么就返回false,因为没有一个二叉搜索树的后序遍历是这个数组。
分析:
题意很清晰,那么下面我就要分析了,如果给我们一个二叉搜索树,我们是可以给出后序遍历的序列的,但是如果这么赶过来,让我们给出二叉搜索树,那就有些麻烦了。
但是我们可以从二叉搜索树的定义入手试试看
父节点比左孩子大,比右孩子小,并且它的后序遍历序列的最后一个数是这棵二叉搜索树的根。那么我们就可以很容易的分辨出:{5,7,6,9,11,10,8}这个序列中8为根节点,5,7,6为左孩子,9,11,10为右孩子。那么我们是不是还可以继续往下分析,像刚才一样,5,7,6这个序列中6为根,5为左孩子,7为右孩子。同理9,11,10也是一样的。我们很惊讶的发现了规律,这样一看是不是挺简单。那我们接下来分析一下那个错误的序列,看看能不能用这种方法来分析出来。首先在{7,4,6,5},这个序列中5为根,7是大于5的,所以这棵树没有左孩子,只有右孩子,继续往右看,我们发现4小于5,也就是说它应该出现在5的左边,所以很明显它是不合法的。
通过这样的分析我们就很清楚了,下面就可以写代码了:
bool VerfySquenceOfBST(int *num,int length)
{
if(num == NULL || length < 0)
return false;
int root = num[length - 1];
int i = 0;
while(i<length-1)
{
if(root < num[i])
break;
i++;
}
int j=i;
while(j<length-1)
{
if(num[j] < root)
return false;
j++;
}
bool left = true;
if(i>0)
left = VerfySquenceOfBST(num,i);
bool right = true;
if(i<length-1)
right = VerfySquenceOfBST(num+i,length-i-1);
return (left && right);
}
题目扩展:
如果给出的是一个线序遍历序列呢?
分析:
会了后序的那么线序的也就很简单了,只是他的根节点
bool VerfySquenceOfBST(int *num,int length)
{
if(num == NULL || length < 0)
return false;
int root = num[0];
int i=1;
while(i<length-1)
{
if(num[i]>root)
break;
i++;
}
int j=i;
while(j<length-1)
{
if(num[j]<root)
return false;
j++;
}
bool left = true;
if(j>1)
left = VerfySquenceOfBST(num+1,i-1);
bool right = true;
if(i<length-1)
right = VerfySquenceOfBST(num+i,length-i);
return (left && right);
}