题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果.
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
解: 后序遍历的最后一个节点一定是根节点,从右往左倒着遍历一边这个序列即可得到结果。具体过程为:
假设序列保存在数组a中
1. 先创建一个区间 (负无穷,正无穷), 令i=1,为序列从右边数的第 i 个节点。
2. 判断a[i] 是否在区间中。
例如当i=1时,根节点8被加入区间,原区间被分成两个区间(负无穷,8),(8,正无穷),i的左子
树中的点必然落在第一个区间,i的右子树中的点必然在第二个区间中
然后取出第二个节点10,加入第二个区间,此时区间被分成了3个
(负无穷,8),(8,10),(10,正无穷)
然后取第3个节点11,得到4个区间
(负无穷,8),(8,10),(10,11)(11,正无穷)
然后取第4个节点9,显然9应放进第二个区间,舍掉后两个个区间(如果是合法的序列,序列前面不可能有
落在后面区间中的点),得到:
(负无穷,8),(8,9),(9,10)
如此下去,如果序列中每个点都可以插到栈中,那么数组是二元查找树的后序遍历的结果,否则返回false.
#include <iostream>
#include <climits>
using namespace std;
#define N 100
bool judge(int a[], int len)
{
int stk[N]={INT_MIN, INT_MAX};
int top=1; //栈顶指针
for(int i=len-1; i>=0; --i)
{
if (a[i]>=stk[top]) //如果不能插入到栈中,返回false
return false;
while (a[i]<stk[top]) //在栈中查找第一个不大于a[i]的数
{
--top;
}
if (a[i] == stk[top]) //如果啊a[i]与栈中元素相同返回false
return false;
// 把栈中比a[i]大的那个数向右移一个位置,把a[i]插到栈中
top += 2;
stk[top] = stk[top-1];
stk[top-1] = a[i];
}
return true;
}
int main()
{
int a[]={5, 7, 6, 9, 11, 10, 8};
//int a[]={7,4,6,5};
cout<<judge(a,7)<<endl ;
}