7-28 搜索树判断(25 分)

对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。

现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。

输入格式:

输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。

输出格式:

输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。

输入样例1:

7
8 6 5 7 10 8 11

输出样例1:

YES
5 7 6 8 11 10 8

输入样例2:

7
8 6 8 5 10 9 11

输出样例2:

NO

解题思路:1.首先是判断是否是二叉搜索树,给出先序遍历,因而先序的第一个数字是根结点,
找到第一个大于等于根节点的数字,从这个数字开始为右子树,若右子树中有小于根结点的数
那么它不是二叉搜索树; 镜像结点判断条件相反即可
2、倘若是二叉搜索树则一边递归一边生成二叉树,最后返回根节点
3、对二叉搜索树进行后序遍历

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 typedef struct TNode *tree;
  6 struct TNode
  7 {
  8     int data;
  9     tree lchild;
 10     tree rchild;
 11 };
 12 int flag = 0;   //控制最后一个输出后面没有空格
 13 int flag1 ;     //如果不是二叉搜索树返回1
 14 int flag2 ;     //如果不是二叉镜像搜索树返回1
 15 
 16 void Print( tree t);
 17 tree Find ( int pre[],int len);
 18 tree FindMirror( int pre[],int len);
 19 
 20 int main()
 21 {
 22     int len;
 23     int pre[1005];
 24     int i;
 25     tree t,tm;
 26 
 27     scanf("%d",&len);
 28     for( i=0; i<len; i++)
 29     {
 30         scanf("%d",&pre[i]);
 31     }
 32 
 33     t = Find( pre,len);
 34     tm = FindMirror( pre,len );
 35     if( t && !flag1)
 36     {
 37         //树不为空并且是二叉搜索树
 38         printf("YES\n");
 39         Print( t );
 40         printf("\n");
 41     }
 42     else if( tm && !flag2)
 43     {
 44         //树不为空并且是二叉镜像搜索树
 45         printf("YES\n");
 46         Print( tm );
 47         printf("\n");
 48     }
 49     else printf("NO\n");
 50 
 51     return 0;
 52 }
 53 
 54 
 55 tree Find ( int pre[],int len)
 56 {
 57     int i,j;
 58 
 59     if( !len ) return NULL;
 60     tree temp = (tree) malloc( sizeof( struct TNode));
 61     temp->data = *pre;
 62 
 63     for( i=1; i<len; i++)
 64     {
 65         if( pre[i] >= temp->data)
 66             //寻找右子树
 67             break;
 68     }
 69     for( j=i; j<len; j++)
 70     {
 71         if( pre[j] < temp->data)
 72         {
 73             //右子树中有小于根结点的值,不是二叉搜索树
 74             flag1 = 1;
 75             return NULL;
 76         }
 77     }
 78     temp->lchild = Find( pre+1, i-1);
 79     temp->rchild = Find( pre+i, len-i);
 80     return temp;
 81 }
 82 tree FindMirror( int pre[],int len)
 83 {
 84     //镜像树,左子树大于根大于右子树
 85     int i,j;
 86 
 87     if( !len ) return NULL;
 88     tree temp = (tree) malloc( sizeof( struct TNode));
 89     temp->data = *pre;
 90 
 91     for( i=1; i<len; i++)
 92     {
 93         if( pre[i] < temp->data)
 94             //寻找右子树
 95             break;
 96     }
 97     for( j=i; j<len; j++)
 98     {
 99         if( pre[j] >= temp->data)
100         {
101             //右子树中有大于等于根结点的值,不是二叉搜索树
102             flag2 = 1;
103             return NULL;
104         }
105     }
106     temp->lchild = FindMirror( pre+1, i-1);
107     temp->rchild = FindMirror( pre+i, len-i);
108     return temp;
109 }
110 
111 void Print( tree t)
112 {
113 
114     if( t )
115     {
116         //后序遍历
117         Print(t->lchild);
118         Print(t->rchild);
119         if( !flag ) flag = 1;
120         else printf(" ");
121         printf("%d",t->data);
122     }
123 }

 


posted @ 2018-02-05 10:11  yuxiaoba  阅读(2578)  评论(0编辑  收藏  举报