剑指Offer_面试题24_二叉搜索树的后序遍历序列

63 篇文章 1 订阅
40 篇文章 0 订阅

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都 互不相同
分析:二叉搜索树即二叉排序树,根节点左子树小于根,右子树大于根。以往和二叉树有关的题目都是设计前序、中序,或者中序后序,或者中序层序,因为要还原二叉树中序不可获取。但是二叉搜索树是比较特殊,因为其本身的性质,会导致后序、前序、中序有规律。
如:                         8
                     6                 10
             5            7       9            11
是一个标准的二叉排序树,后序序列为:5,7,6,9,11,10,8
判断过程为:
1.序列5 7 6 9 11 10 8,根结点为8,他的左子树比他小,右子树比他大,从左往右遍历序列找到第一个比8大的数,依此为分界分为左右子树
5 7 6 是左子树, 9 11 10 是右子树,判断一下9 11 10中是否有比8小的数字,如果有则返回false证明不是二叉搜索树。
2.接下来递归判断左子树、右子树是不是二叉搜索树,当都成立时才为真。递归终止条件是左子树为空则返回真,右子树为空返回真,否则返回递归的相与返回值。
原书代码:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;

bool VerifySquenceOfBST(int sequence[], int length)
{
	if (!sequence || length <= 0)
		return false;

	//遍历到左右子树分界点
	int *root = sequence + length - 1;
	int *right = sequence;
	while (*right < *root)
		++right;
	for (int *p = right; p < root; ++p)
	{
		if (*p < *root)
			return false;
	}

	//判断左子树
	bool bLeft = true;
	if (right > sequence)    //左子树不为空
		bLeft = VerifySquenceOfBST(sequence, right - sequence);
	//判断右子树
	bool bRight = true;
	if (right < root)     //右子树不为空
		bRight = VerifySquenceOfBST(right, root - right);

	return bLeft && bRight;
}


牛客网代码,因为原书代码我用了指针,这里我就直接改成迭代器了,很方便:
bool VerifySquenceOfBST(vector<int> sequence) {
	if (sequence.empty())
		return false;

	//遍历到左右子树分界点
	auto root = sequence.cend()- 1;
	auto right = sequence.cbegin();
	while (*right < *root)
		++right;
	for (auto p = right; p < root; ++p)
	{
		if (*p < *root)
			return false;
	}

	//判断左子树
	bool bLeft = true;
	if (right > sequence.cbegin())    //左子树不为空
	{
		vector<int> leftSeq(sequence.cbegin(), right);
		bLeft = VerifySquenceOfBST(leftSeq);
	}
	//判断右子树
	bool bRight = true;
	if (right < root)     //右子树不为空
	{
		vector<int> rightSeq(right, root);
		bRight = VerifySquenceOfBST(rightSeq);
	}

	return bLeft && bRight;
}
测试程序:
int main()
{
	int a[] = { 7,4,6,5 };
	if (VerifySquenceOfBST(a, 7))
		printf("true");
	else
		printf("false");
	printf("\n");

	vector<int>b = { 5,7,6,9,11,10,8};
	if (VerifySquenceOfBST(b))
		printf("true");
	else
		printf("false");
	printf("\n");

	getchar();

	return 0;
}

效果:

总结:
主要是找规律,注意递归结束条件。举一反三,前序序列同样可以做
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值