1. 程式人生 > >二叉搜索樹的查找、刪除、插入

二叉搜索樹的查找、刪除、插入

刪除節點 bsp span 空間 排序樹 第一個 include 什麽 del

  1 #include<iostream>
  2 
  3 using namespace std;
  4 
  5 //二叉搜索樹
  6 typedef struct BiNode
  7 {
  8     int data;
  9     struct BiNode *lchild; //這裏定義的是BiNode的指針類型
 10     struct BiNode *rchild;
 11 
 12 }BiNode ,*BiTree; //這裏面的BiTree前面有一個星星,表示這種結構的指針類型
 13 
 14 //sousuo
 15 //這裏的*T代表的是二叉排序樹,key表示的是要查找的值 ,f是指向*T的雙親,p是指向查找路線上的最後一個節點
16 int searchnum(BiTree *T,BiTree f, int key ,BiTree *p) //這裏的p一定要有指針或者引用,避免值傳遞 17 { 18 if(!T) 19 { 20 *p = *T ; 21 return 0; 22 } 23 else if(key == (*T)->data) 24 { 25 *p = *T; 26 return 1; 27 } 28 else if (key > (*T)->data)
29 { 30 searchnum(& ( (*T)->rchild) ,*T,key,p); //f是父節點,在這裏的賦值體現出來 31 32 } 33 else 34 { 35 searchnum(& ( (*T)->lchild) ,*T,key,p); 36 } 37 } 38 //插入操作 39 int insertnum(BiTree &T,int key) 40 { 41 BiTree *p = (BiTree *)malloc(sizeof(BiNode));
42 43 if(searchnum(&T,NULL,key,p) != 0 ) //已經有該關鍵字,不需要插入了 44 { 45 return 0; 46 } 47 else 48 { 49 BiTree s = (BiTree )malloc(sizeof(BiNode)); 50 s->data = key; 51 s->lchild = s->rchild = NULL; 52 53 if (!(*p))//這裏忘了一種情況那就是空樹的插入操作 54 { 55 T = s; 56 } 57 else if(key > (*p)->data) 58 { 59 (*p)->rchild = s; 60 } 61 else 62 { 63 (*p)->lchild = s; // 這裏不存在等於的那種情況,要不然當一個if就已經檢測出來了 64 } 65 //然後整個做完之後,看起來似乎無懈可擊,但是這樣子完全不對的,涉及值傳遞和址傳遞的過程 66 //上面的函數接口部分應該寫上函數的值或者引用,因為輸出的結果要造成T在整個函數運行後,只得到改變 67 //我這裏為了方便,不更改下面的代碼 直接加了一個引用 68 } 69 } 70 71 72 //00刪除操作 73 74 void Delete(BiTree *p) 75 { 76 77 BiTree s; 78 if((*p)->lchild == NULL) 79 { 80 s = (*p); 81 (*p) = (*p)->rchild; 82 free(s); 83 } 84 else if( (*p)->rchild == NULL) 85 { 86 s = (*p); 87 (*p) = (*p)->lchild; 88 free(s); 89 } 90 else //這種情況兩個孩子都不能空了 91 { 92 BiTree q,s; 93 q= (*p); 94 s= (*p)->lchild; // 這裏要取第一個做孩子,向右遍歷,到左右的孩子來替換刪除節點 95 while(s->rchild) 96 { 97 q = s; 98 s = s->rchild; 99 } 100 //這裏忘記了替換,找到刪除節點的 中序遍歷相鄰節點 要進行替換的。 101 (*p)->data = s->data ; //這裏容易寫成(*p)=s ,為什麽不能這麽寫呢,因為這麽寫就改變了他的結構了,左右孩子都變了。 102 //下面就分兩種情況了,就是q有沒有移動,換言之就是刪除節點的左孩紙有沒有節點。 103 //這一步是已經完成了刪除,剩下刪除的節點左子樹的爛攤子要收拾 104 if(q == (*p)) 105 { 106 (q)->lchild = s->lchild; 107 } 108 else 109 { 110 (q)->rchild = s->lchild; 111 } 112 113 free(s); 114 115 116 } 117 } 118 119 int deletenum(BiTree *T ,int key) 120 { 121 if(*T ) 122 { 123 return 0; 124 } 125 else 126 { 127 if(key == (*T)->data) 128 { 129 Delete(T); 130 } 131 else if(key >(*T)->data ) 132 { 133 deletenum(&(*T)->rchild ,key); 134 } 135 else 136 { 137 deletenum(&(*T)->lchild ,key); 138 } 139 } 140 } 141 142 int main() 143 { 144 system("pause"); 145 }

註意事項:

  • 註意值傳遞和址傳遞的情況,希望傳入的值有所改變,並且在調用函數外部依舊用到這個值,就用址傳遞,其他時候都可以了
  • 在刪除的時候,要釋放空間
  • 刪除操作的時候,刪除節點要賦值,註意有種情況是直接賦值的,而不是節點相等,賦值後,對之後改變的子樹進行操作。

二叉搜索樹的查找、刪除、插入