题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。例如,输入数组{5,7,6,9,11,10,8},则返回true,因为这个整数序列是下图所示二叉树的后序遍历结果。如果输入的数组是{7,4,6,5},则没有哪棵二叉搜索树的后序遍历结果是这个序列,因此返回false。
思路:
二叉搜索树和二叉树相比,多了一个排序的特点,就是左子树节点的值都小于根节点,右子树节点的值都大于根节点。给定后序遍历序列,可以知道根节点的数值,这样从头开始遍历数组,找到第一个大于根节点的值,那个值开始到数组的末尾都是右子树的 节点,而根节点的前面的节点都是左子树的节点。这样就可以得到树的结构,如果右子树的节点存在小于根节点的值,那么这棵树就不会是二叉搜索树。如果满足左右子树都是二叉搜索树,那么这棵树就是二叉搜索树,用递归的方法,就可以得到结果。
代码:
bool VerifySquenceOfBST(int sequence[], int length)
{
if (sequence == nullptr || length <= 0)
return;
int root = sequence[length - 1];
//在二叉搜索树中左子树节点的值小于根节点的值
int i = 0;
for (; i < length; 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 = VerifySquenceOfBST(sequence, i);
//判断右子树是不是二叉搜索树
bool right = true;
if (i < length - 1)
right = VerifySquenceOfBST(sequence + i, length - i - 1);
return (left&&right);
}
复习:
根据二叉搜树的特点,递归地判断左右子树满不满足与根节点的大小关系,树的具体结构是无法判定的,但是它们满足的关系是可以验证的。这里判断左右子树是否存在的条件就是i的取值,这里要注意一下。
二刷代码:
bool VerifySquenceOfBST(int sequence[],int length)
{
if (sequence == nullptr || length <= 0)
return false;
int root = sequence[length - 1];
int i = 0;
for (; i<length; i++)
{
if (sequence[i] > root)
break;
}
int j = i;
for (; j < length - 1; j++)
{
if (sequence[i] < root)
return false;
}
bool left = true;
if (i > 0)
left = VerifySquenceOfBST(sequence, i);
bool right = true;
if (i < length - 1)
right = VerifySquenceOfBST(sequence + i, length - i - 1);
return (left&&right);
}