4-12 二叉搜索樹的操作集 (30分)


4-12 二叉搜索樹的操作集   (30分)

本題要求實現給定二叉搜索樹的5種常用操作。

函數接口定義:

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

其中BinTree結構定義如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};
  • 函數InsertX插入二叉搜索樹BST並返回結果樹的根結點指針;
  • 函數DeleteX從二叉搜索樹BST中刪除,並返回結果樹的根結點指針;如果X不在樹中,則打印一行Not Found並返回原樹的根結點指針;
  • 函數Find在二叉搜索樹BST中找到X,返回該結點的指針;如果找不到則返回空指針;
  • 函數FindMin返回二叉搜索樹BST中最小元結點的指針;
  • 函數FindMax返回二叉搜索樹BST中最大元結點的指針;

 

輸入樣例:

10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3

輸出樣例:

Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9
  在實現過程中,感覺難度最大的時刪除操作,所以在這里詳細的說一下刪除操作的思路
    二叉查找樹重要性質:

                                            (1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

                                            (2)若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;

                                            (3)左、右子樹也分別為二叉排序樹;

    現有,如下一棵二叉查找樹。

                             

                                                                      (圖1)

    現在,若要刪除圖1中,任意節點,需要考慮如下三種情況:

    (1)需要刪除的節點下並沒有其他子節點。

    (2)需要刪除的節點下有一個子節點(左或右)。

    (3)需要刪除的節點下有兩個子節點(既左右節點都存在)。

    第一種情況直接刪除即可,下面,直接討論第二種情況。

    若我們要刪除的是3號節點,由圖1可以看到,它下面還有一個4號子節點。由下圖2,可以看出,對於這種辦法,我們只需要想辦法,讓5號節點的左子樹的指針指向4就可以了。

                                        

                                                                       (圖2)

    第三種情況,既我們要刪除的節點下,有2個子節點。如圖3,我們先在需要刪除的節點的右子樹中,找到一個最小的值(因為右子樹中的節點的值一定大於根節點)。然后,用找到的最小的值與需要刪除的節點的值替換。然后,再將最小值的原節點進行刪除(圖4)。

                                          

                                                                          (圖3)

                                           

 

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 typedef int ElementType;
  5 typedef struct TNode *Position;
  6 typedef Position BinTree;
  7 struct TNode{
  8     ElementType Data;
  9     BinTree Left;
 10     BinTree Right;
 11 };
 12 
 13 void PreorderTraversal( BinTree BT ); /* 先序遍歷,由裁判實現,細節不表 */
 14 void InorderTraversal( BinTree BT );  /* 中序遍歷,由裁判實現,細節不表 */
 15 BinTree Insert( BinTree BST, ElementType X );
 16 BinTree Delete( BinTree BST, ElementType X );
 17 Position Find( BinTree BST, ElementType X );
 18 Position FindMin( BinTree BST );
 19 Position FindMax( BinTree BST );
 20 int main()
 21 {
 22     BinTree BST, MinP, MaxP, Tmp;
 23     ElementType X;
 24     int N, i;
 25     BST = NULL;
 26     scanf("%d", &N);
 27     for ( i=0; i<N; i++ ) {
 28         scanf("%d", &X);
 29         BST = Insert(BST, X);
 30     }
 31     printf("Preorder:"); PreorderTraversal(BST); printf("\n");
 32     MinP = FindMin(BST);
 33     MaxP = FindMax(BST);
 34     scanf("%d", &N);
 35     for( i=0; i<N; i++ ) {
 36         scanf("%d", &X);
 37         Tmp = Find(BST, X);
 38         if (Tmp == NULL) printf("%d is not found\n", X);
 39         else {
 40             printf("%d is found\n", Tmp->Data);
 41             if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
 42             if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
 43         }
 44     }
 45     scanf("%d", &N);
 46     for( i=0; i<N; i++ ) {
 47         scanf("%d", &X);
 48         BST = Delete(BST, X);
 49     }
 50     printf("Inorder:");
 51     InorderTraversal(BST);
 52     printf("\n");
 53     return 0;
 54 }
 55 /* 你的代碼將被嵌在這里 */
 56 void PreorderTraversal( BinTree BT )
 57 {
 58     if(BT==NULL) return;
 59     else{
 60     printf(" %c",BT->Data);
 61     PreorderTraversal(BT->Left);
 62         PreorderTraversal(BT->Right);
 63     }
 64 }
 65 void InorderTraversal( BinTree BT )
 66 {
 67     if(BT==NULL) return;
 68     else{
 69     InorderTraversal(BT->Left);
 70     printf(" %c",BT->Data);
 71     InorderTraversal(BT->Right);
 72     }
 73 }
 74 BinTree Insert( BinTree BST, ElementType X )
 75 {
 76     if(!BST)//如果BST為空的話,返回只有一個節點的樹
 77     {
 78         BST=(BinTree)malloc(sizeof(struct TNode));
 79         BST->Data=X;
 80         BST->Left=NULL;
 81         BST->Right=NULL;
 82     }
 83     else//如果BST不是為空的話
 84     {//開始尋找要插入的位置
 85         if(X<BST->Data)
 86             BST->Left=Insert(BST->Left,X);
 87         else if(X>BST ->Data)
 88             BST->Right=Insert(BST->Right,X);
 89     }
 90     return BST;
 91 }
 92 BinTree Delete( BinTree BST, ElementType X )
 93 {
 94     BinTree Tmp;
 95     if(!BST) printf("Not Found\n");
 96     else{
 97         if(X<BST->Data)
 98             BST->Left=Delete(BST->Left,X);
 99         else if(X>BST->Data)
100         {
101             BST->Right=Delete(BST->Right,X);
102         }
103         else//考慮如果找到這個位置,並且有左節點或者右節點或者沒有節點三種情況
104         {
105             if(BST->Left && BST->Right) {
106                 Tmp=FindMin(BST->Right);   /* 在右子樹中找到最小結點填充刪除結點 */
107                 BST->Data = Tmp ->Data;
108                 BST->Right=Delete(BST->Right,BST->Data);/* 遞歸刪除要刪除結點的右子樹中最小元素 */
109             }
110             else
111             {                                 /* 被刪除結點有一個或沒有子結點*/
112                 Tmp = BST;
113                 if(!BST->Left) BST = BST->Right;        /*有右孩子或者沒孩子*/
114                 else if(!BST->Right)    BST = BST->Left;/*有左孩子,一定要加else,不然BST可能是NULL,會段錯誤*/
115                 free(Tmp);                              /*如無左右孩子直接刪除*/
116             }
117        }
118     }
119     return BST;
120 }
121 Position Find( BinTree BST, ElementType X )
122 {
123     if(!BST) return NULL;
124     if(BST->Data==X) return BST;
125     else if(X<BST->Data) {
126         return Find(BST->Left,X);
127     }
128     else if(X>BST->Data)
129     {
130         return Find(BST->Right,X);
131     }
132     return BST;
133 }
134 Position FindMin( BinTree BST )
135 {
136     if(BST!=NULL)
137     {
138         while(BST->Left)
139             BST=BST->Left;
140     }
141     return BST;
142 }
143 Position FindMax( BinTree BST )
144 {
145     if(BST!=NULL)
146     {
147         while(BST->Right)
148              BST=BST->Right;
149     }
150     return BST;
151 }

 

 

                                                                             


免責聲明!

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



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