pat 天梯 L2-4. 这是二叉搜索树吗?

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

输入格式:

输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。

输出格式:

如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。

输入样例1:
7
8 6 5 7 10 8 11
输出样例1:
YES
5 7 6 8 11 10 8
输入样例2:
7
8 10 11 8 6 7 5
输出样例2:
YES
11 8 10 7 5 6 8
输入样例3:
7
8 6 8 5 10 9 11
输出样例3:
NO
我的思路是 假设它是二叉排序树成立,我就按照二叉排序树的规则以及题目给的先序顺序,利用栈来模拟建树的过程,这里用到了两个栈 s1 和s2;
s1是用来实现 把相应的数插入正确的位置,s2则是和s1同步插入 但是实现模拟树的后序遍历的过程,并且把遍历结果存到队列中;
这里有个mark变量,mark是一个标记 
以本体为例,以先序的顺序 插入结点, 最开始 栈里只有一个结点 就是先序的第一个点,把先序下一个点p和s1栈顶比较 如果小于他就放在左边,否则执行while循环 一直pop s1 直到s1栈顶大于 p,在此过程中s2 不是执行pop 而是给相应元素做个标记 temp 意思是 这个元素左子树已经遍历完了 等其右子树遍历完重新pop到这个元素,就是发现已经被标记过一次,就把他放入队列 再pop,实际s2上就是用栈后序遍历的过程;

#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<stdio.h>
using namespace std;

class node{
public:int d;
int temp;
};

//com在这为比较函数,用来区别处理镜像和本体的情况
bool com(int a,int b,int t){
   if(t) return a>=b;
   else return a<b;
}

int n;
int *v;

int fun1(int t){
    stack<int> s1;
    stack<node> s2;
    node nn;
    queue<int> q;

    int mark;
    if(t) mark=-9;
    else mark=999999;
    
    s1.push(v[0]);
    nn.d=v[0];nn.temp=0;
    s2.push(nn);
    for(int i=1;i<n;i++)
    {//这里有com比较,把结点放到小于等于他的最大节点的右边(本体情况)镜像类推;
        while(!s1.empty()&&com(v[i],s1.top(),t))
        {
          mark=s1.top();
            s1.pop();
        //把其被标记的父节点放入输出队列,并删掉
          while(s2.top().temp){
            q.push(s2.top().d);
             s2.pop();
          }
            nn=s2.top();s2.pop();nn.temp=1;
              s2.push(nn);
        }
        //这里有com比较 
        if(com(v[i],mark,!t)) {return 0;}
        s1.push(v[i]);
        nn.d=v[i],nn.temp=0,s2.push(nn);
    }
while(!s2.empty()){
   nn=s2.top();
   q.push(nn.d);
   s2.pop();
}
cout<<"YES"<<endl;
cout<<q.front();q.pop();
while(!q.empty())
{
    cout<<" "<<q.front();
    q.pop();
}
return 1;

}

int main(){

//freopen("F:\\1.txt","r",stdin);
cin>>n;
v=new int[n];

for(int i=0;i<n;i++)
    cin>>v[i];

    if(!fun1(1)) if(!fun1(0))cout<<"NO" ;
    
//fclose(stdin);
}


猜你喜欢

转载自blog.csdn.net/var1994/article/details/51396350
今日推荐