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 }
 
        

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM