给定一个序列,判断是否是某二叉搜索树的后续遍历序列?
分析:
- 二叉搜索树,特点是一棵二叉树,左子树的结点值均小于根结点值,右子树的结点值均大于根结点值。查找时,和根结点比较,从而转向搜索左或右子树,类似于二分查找。
- 后续遍历是左-右-根。则最后一个数字为根结点值。前面小于根的为左子树,大于根的为右子树,递归仍符合该性质。
代码:
// offer-24-houxubianli.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
bool verity(int * a, int length)
{
if(a == nullptr || length <= 0)
return false;
// 当遇到一个结点时返回真
if(length == 1)
return true;
int root = a[length - 1];
// 找到左子树序列
int i = 0;
for(; i < length-1; ++i)
{
if(a[i] > root)
break;
}
// 剩下的为右子树,遍历若有小于根的,直接返回假
int j = i;
for(; j < length-1; ++j)
{
if(a[j] < root)
return false;
}
// 跑到这里说明根结点一层符合,需要看左右子树
// 当i=0即左子树为空时,返回真
// 否则递归处理左子树
bool left = true;
if(i>0)
left = verity(a, i);
// 当j=length-1即右子树为空,返回真
// 否则递归处理右子树
bool right = true;
if(j<length-1)
right = verity(a+i, length-i-1);
// 返回左右子树的并
return left && right;
}
// 测试
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {5,7,6,9,11,10,8};
cout << verity(a, 7) << endl; // true
int b[] = {8,5,6,8,7};
cout << verity(b, 5) << endl; // false
return 0;
}