《剑指Offer》面试题24:二叉搜索树的后序遍历序列
知识点
二叉搜索树遍历
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是返回true,否则返回false。假设输入的数组的任意两个数字互不相同。
解题思路
要明确两个概念:
1. 二叉搜索树的特点,就是如果有对任何一个非空结点,假如左子树存在,那么左子树的中任意一个结点都比该根结点小,假如右子树存在,那么右子树中的任何一个节点都比该根结点大。
2.二叉树的后序遍历,也就是 左→右→根 的遍历顺序。
然后根据一个具体的实例模拟一下过程:
例如输入数组{5、7、6、9、11、10、8}
因为是后序遍历,所以最后一个数字8一定是整棵树的根结点。所以其他数字为8的子结点,从前往后遍历数组,5,7,6都小于8,所以这三个数字应该组成了8的左子树,同理9、11、10组成了8的右子树。
又如输入数组{7、4、6、5},5是根结点,从前往后遍历数组,5应该是没有左子树,7、4、6组成了5的右子树,而4 < 5,所以,4不能在5的右子树中,相互矛盾,所以这不能是一个后序遍历序列。
以上这些是判断条件,而下面一步是利用递归来判断整棵树了。
测试用例
代码(原书)
/*《剑指Offer——名企面试官精讲典型编程题》代码
著作权所有者:何海涛*/
#include "stdio.h"
#include <cstdlib>
// BST:Binary Search Tree,二叉搜索树
bool VerifySquenceOfBST(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 = VerifySquenceOfBST(sequence, i);
// 判断右子树是不是二叉搜索树
bool right = true;
if (i < length - 1)
right = VerifySquenceOfBST(sequence + i, length - i - 1);
return (left && right);
}
// ====================测试代码====================
void Test(char* testName, int sequence[], int length, bool expected)
{
if (testName != NULL)
printf("%s begins: ", testName);
if (VerifySquenceOfBST(sequence, length) == expected)
printf("passed.\n");
else
printf("failed.\n");
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
void Test1()
{
int data[] = { 4, 8, 6, 12, 16, 14, 10 };
Test("Test1", data, sizeof(data) / sizeof(int), true);
}
// 5
// / \
// 4 7
// /
// 6
void Test2()
{
int data[] = { 4, 6, 7, 5 };
Test("Test2", data, sizeof(data) / sizeof(int), true);
}
// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
void Test3()
{
int data[] = { 1, 2, 3, 4, 5 };
Test("Test3", data, sizeof(data) / sizeof(int), true);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test4()
{
int data[] = { 5, 4, 3, 2, 1 };
Test("Test4", data, sizeof(data) / sizeof(int), true);
}
// 树中只有1个结点
void Test5()
{
int data[] = { 5 };
Test("Test5", data, sizeof(data) / sizeof(int), true);
}
void Test6()
{
int data[] = { 7, 4, 6, 5 };
Test("Test6", data, sizeof(data) / sizeof(int), false);
}
void Test7()
{
int data[] = { 4, 6, 12, 8, 16, 14, 10 };
Test("Test7", data, sizeof(data) / sizeof(int), false);
}
void Test8()
{
Test("Test8", NULL, 0, false);
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
system("pause");
return 0;
}
代码(牛客网)
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if(sequence.empty())
return false;
int length = sequence.size();
int root = sequence[length-1];
int i, j, p, q;
for( i = 0; i < length -1; i++)
{
if(sequence[i] > root)
break;
}
for(j = i; j < length-1; j++)
{
if(sequence[j] < root)
return false;
}
bool left = true;
if(i > 0)
{
vector<int> seqLeft;
for(p = 0; p < i; p++)
{
seqLeft.push_back(sequence[p]);
}
left = VerifySquenceOfBST(seqLeft);
}
bool right = true;
if(j < length-1)
{
vector<int> seqRight;
for(q = i; q <= j; q++)
{
seqRight.push_back(sequence[q]);
}
right = VerifySquenceOfBST(seqRight);
}
return left && right;
}
}
相关题目
举一反三