劍指Offer_面試題24_二叉搜索樹的後序遍歷序列

題目描述

輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則返回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;
}

效果:

總結:
主要是找規律,注意遞歸結束條件。舉一反三,前序序列同樣可以做
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章