1 #include <IOSTREAM> 2 #include <QUEUE> 3 using namespace std; 4 5 //結點的結構體 6 //內涵三個參數,關鍵字Key,左孩子指針,右孩子指針 7 typedef struct _NODE_ 8 { 9 int Key; 10 _NODE_* pLeft; 11 _NODE_* pRight; 12 }Node,*pNode; 13 14 //中序遍歷 15 void InOrderTraves(pNode T); 16 17 18 //層狀遍歷 19 void LevelTraves(pNode T); 20 21 //搜索結點 22 bool SearchNode(pNode T, int Key, pNode& f, pNode& p); 23 24 //插入結點 25 bool InsertNode(pNode& T,int Key); 26 27 //刪除結點 28 void DeleteNode(pNode& T,int Key); 29 30 //銷燬樹 31 void DestroyTree(pNode& T); 32 33 //測試函數 34 int main() 35 { 36 pNode BST = NULL; 37 int Key = 0; 38 cout<<"Create a BST: "; 39 cin>>Key; 40 while (Key != -1) 41 { 42 InsertNode(BST,Key); 43 cin>>Key; 44 } 45 46 InOrderTraves(BST); 47 cout<<endl; 48 LevelTraves(BST); 49 cout<<endl; 50 51 DestroyTree(BST); 52 return 0; 53 } 54 55 void InOrderTraves(pNode T) 56 { 57 if (T != NULL) 58 { 59 InOrderTraves(T->pLeft); 60 cout<<T->Key<<" "; 61 InOrderTraves(T->pRight); 62 } 63 } 64 65 //使用STL 的 queue隊列 66 void LevelTraves(pNode T) 67 { 68 if (T == NULL) 69 { 70 return; 71 } 72 73 pNode p = T; 74 75 queue<pNode> Que; 76 Que.push(p); 77 78 while (!Que.empty()) 79 { 80 p = Que.front(); 81 Que.pop(); 82 cout<<p->Key<<" "; 83 84 if (p->pLeft != NULL) 85 { 86 Que.push(p->pLeft); 87 } 88 if (p->pRight != NULL) 89 { 90 Que.push(p->pRight); 91 } 92 } 93 94 } 95 96 97 // 查找函數 98 // 參數: 99 // 樹根T, 待查找的關鍵字Key, 100 // 指針f(用於存放找到結點的父節點) 101 // 指針p(用於存放找到結點) 102 bool SearchNode(pNode T, int Key, pNode& f, pNode& p) 103 { 104 p = T; 105 if (p == NULL) 106 { 107 return false; 108 } 109 while (p!=NULL) 110 { 111 if (p->Key == Key) 112 { 113 return true; 114 } 115 if (p->Key > Key) 116 { 117 f = p; 118 p = p->pLeft; 119 } 120 if (p->Key < Key) 121 { 122 f = p; 123 p = p->pRight; 124 } 125 } 126 127 return false; 128 } 129 130 131 bool InsertNode(pNode& T,int Key) 132 { 133 134 //若是根結點不存在,動態申請內存空間 135 if (T == NULL) 136 { 137 T = (pNode)malloc(sizeof(Node)); 138 139 T->Key = Key; 140 T->pLeft = T->pRight = NULL; 141 142 return true; 143 } 144 //在保持BST的性質的狀況下進行插入 145 else 146 { 147 if (T->Key == Key) 148 { 149 cout<<"Error"<<endl; 150 return false; 151 } 152 if (T->Key > Key) 153 { 154 InsertNode(T->pLeft,Key); 155 } 156 else 157 { 158 InsertNode(T->pRight,Key); 159 } 160 } 161 162 return false; 163 } 164 165 166 //有四種狀況 167 168 /* 169 * 狀況一: 待刪結點爲葉子結點(無左孩子也無又孩子) 170 * 直接將其父節點的左(或者右)孩子的值賦爲空 171 * 172 * 狀況二: 待刪結點只有左子樹 173 * 將其父節點的左子樹賦爲待刪結點的左子樹 174 * 175 * 狀況三: 待刪結點只有右子樹 176 * 將其父節點的右子樹賦爲待刪結點的右子樹 177 * 178 * 狀況四: 待刪結點既有右子樹,右有左子樹 179 * 找到待刪結點的前驅結點,替換待刪結點。 180 */ 181 void DeleteNode(pNode& T,int Key) 182 { 183 184 pNode p = NULL; 185 pNode q = NULL; 186 pNode s = NULL; 187 pNode f = NULL; 188 189 if(SearchNode(T,Key,f,p)) 190 { 191 if (p->pLeft && p->pRight) 192 { 193 q = p; 194 //找到p的直接前驅 195 s = s->pLeft; 196 while (s->pRight != NULL) 197 { 198 q = s; 199 s = s->pRight; 200 } 201 202 //將值和直接前驅調換 203 p->Key = s->Key; 204 205 //這種狀況是通常狀況,q 和 p不相等 206 if (q != p) 207 { 208 q->pRight = s->pLeft; 209 } 210 //特殊狀況 211 else 212 { 213 q->pLeft =s->pLeft; 214 } 215 } 216 else if(p->pLeft == NULL && p->pRight == NULL) 217 { 218 if (f->pRight == p) 219 { 220 f->pRight = NULL; 221 } 222 else 223 { 224 f->pLeft = NULL; 225 } 226 } 227 else if (p->pLeft != NULL && p->pRight == NULL) 228 { 229 f->pLeft = p->pLeft; 230 } 231 else 232 { 233 f->pRight = p->pRight; 234 } 235 } 236 237 } 238 239 void DestroyTree(pNode& T) 240 { 241 if (T != NULL) 242 { 243 if (T->pLeft != NULL) 244 { 245 DestroyTree(T->pLeft); 246 } 247 if (T->pRight != NULL) 248 { 249 DestroyTree(T->pRight); 250 } 251 252 free(T); 253 } 254 }