判断整数序列是不是二元查找树的后序遍历结果

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回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 ;

}

       

原文地址:https://www.cnblogs.com/moor/p/1999109.html