爲了讓這片博客看起來更有養分一些,我仍是在添加一些紅黑樹的設計原理吧?node
Q:爲何要爲葉節點加入終止節點NIL?ios
A:其實這個NIL的假如本省沒有什麼,可是當規定完NIL的顏色爲Black時,他的做用就顯現出來了,但他的顏色爲Black時不管是Insert仍是delete,均可以起到輔佐判斷的做用例:算法
假如向上面這種狀況,插入節點爲C那麼咱們就能夠經過判斷其叔節點的顏色,也就是NIL的顏色把其對應於正確的case2中去。數組
不知道是我買的是盜版的緣由仍是自己書中就有這個問題《算法導論》中文翻譯第三版的179頁的關於RB-INSERT-FLXUP的操做中對於case3沒有加else,這應該是錯誤的,應該是在case2後加上case3,而後再加上在else裏寫上case3。數據結構
下面是算法導論紅黑樹部分的代碼實現,其中大部分代碼是根據算法導論的二叉樹的部分改編過來的,因此會看到一些有些過於單純的二叉樹操做還請見諒!spa
重點強調了紅黑樹的插入和刪除部分的代碼!!翻譯
這個代碼仍是寫了很多的,可是爲何會有紅黑樹這種數據結構,換句話說經過導論引理13.1的證實,這中操做後能保證搜索二叉樹的高度小於lg(n+1),但若是僅從這個角度產生的對於搜索的代價來看的話紅黑樹的優點顯然不如AVL,那麼爲何要用紅黑樹呢?設計
代碼:code
1 #include<iostream> 2 #include<stack> 3 4 using namespace std; 5 6 #define Red 1 7 #define Black 0 8 9 typedef struct node 10 { 11 int key; 12 node* left; 13 node* right; 14 node* parent; 15 int color; // 紅黑樹的節點顏色標識,選取Red-1,Black-0; 16 }Node; 17 18 int visited; 19 int colorFlag; 20 Node* NIL; 21 Node* Root; 22 23 // 建立二叉樹,數據來控制檯。按中序遍歷的方式輸入。 24 void CreatBinaryTree(Node &node) 25 { 26 cout << "輸入" << node.key << "的左兒子" << endl; 27 int x; 28 cin >> x; 29 if (x != -1) 30 { 31 Node *lnode = new Node(); 32 lnode->key = x; 33 node.left = lnode; 34 lnode->parent = &node; 35 CreatBinaryTree(*lnode); 36 } 37 else 38 { 39 node.left = NULL; 40 } 41 cout << "輸入" << node.key << "的右兒子" << endl; 42 int y; 43 cin >> y; 44 if (y != -1) 45 { 46 Node *rnode = new Node(); 47 rnode->key = y; 48 node.right = rnode; 49 rnode->parent = &node; 50 CreatBinaryTree(*rnode); 51 } 52 else 53 { 54 node.right = NULL; 55 } 56 } 57 58 // 按照中序訪問創建二叉樹,數組要求爲先序遍歷返回結果,且左兒子,右兒子爲空設定起等於-1; 59 void CreateBinaryTreeByArray(Node *root, int a[]) 60 { 61 //輸入root的key 62 root->key = a[visited]; 63 visited++; 64 if (a[visited] == -1) 65 { 66 root->left = NULL; 67 visited++; 68 } 69 else 70 { 71 root->left = new Node(); 72 root->left->parent = root; 73 CreateBinaryTreeByArray(root->left, a); 74 } 75 if (a[visited] == -1) 76 { 77 root->right = NULL; 78 visited++; 79 } 80 else 81 { 82 root->right = new Node(); 83 root->right->parent = root; 84 CreateBinaryTreeByArray(root->right, a); 85 } 86 } 87 88 // 遞歸法中序訪問二叉樹 89 void Traverse(Node *root) 90 { 91 if (root != NULL) 92 { 93 Traverse(root->left); 94 cout << root->key << " " << endl; 95 Traverse(root->right); 96 } 97 } 98 99 100 // 非遞歸借用棧迭代中序遍歷二叉樹。 101 void NonRecursionTraverse(Node *root) 102 { 103 stack<Node*> treeStack; 104 Node *p = root->left; 105 treeStack.push(root); 106 while (!(treeStack.empty() && p == NULL)) 107 { 108 while (p != NULL) 109 { 110 treeStack.push(p); 111 p = p->left; 112 } 113 Node *top = treeStack.top(); 114 cout << top->key << " "; 115 treeStack.pop(); 116 p = top->right; 117 } 118 } 119 120 121 // 遞歸二叉樹搜索樹的搜索 122 Node* TreeSearch(Node *root, int x) 123 { 124 if (root == NULL || x == root->key) 125 return root; 126 if (x < root->key) 127 return TreeSearch(root->left, x); 128 else 129 return TreeSearch(root->right, x); 130 } 131 132 133 // 非遞歸二叉搜索樹的搜索 134 Node* InteractiveTreeSearch(Node* root, int x) 135 { 136 while (root != NULL && root->key != x) 137 { 138 if (x < root->key) 139 root = root->left; 140 else 141 root = root->right; 142 } 143 return root; 144 } 145 146 147 // 返回二叉搜索樹中關鍵字最小的元素 148 Node *TreeMinimum(Node* root) 149 { 150 while (root->left != NULL) 151 root = root->left; 152 return root; 153 } 154 155 Node* RecursionTreeMinimun(Node* root) 156 { 157 if (root->left == NULL) 158 return root; 159 return RecursionTreeMinimun(root->left); 160 } 161 162 // 返回二叉搜索樹中關鍵字最大的元素 163 Node *TreeMaxmum(Node* root) 164 { 165 while (root->right != NULL) 166 root = root->right; 167 return root; 168 } 169 170 171 // 返回指定節點的後繼(後繼的定義見算法導論) 172 Node *TreeSuccessor(Node *root) 173 { 174 if (root->right != NULL) 175 return TreeMinimum(root->right); 176 Node* tempParent = root->parent; 177 while (tempParent != NULL&&tempParent->left != root) 178 { 179 root = tempParent; 180 tempParent = tempParent->parent; 181 } 182 return tempParent; 183 } 184 185 // 爲一顆紅黑樹節點設置顏色值; 186 187 void SetNodeColor(Node * root) 188 { 189 if (root != NIL) 190 { 191 cout << root->key << "顏色" << endl; 192 cin >> root->color; 193 SetNodeColor(root->left); 194 SetNodeColor(root->right); 195 } 196 } 197 198 // 按照中序訪問創建紅黑樹但不涉及節點的顏色 199 void CreateRBTreeByArray(Node *root, int a[]) 200 { 201 //輸入root的key 202 root->key = a[visited]; 203 visited++; 204 if (a[visited] == -1) 205 { 206 root->left = NIL; 207 visited++; 208 } 209 else 210 { 211 root->left = new Node(); 212 root->left->parent = root; 213 CreateRBTreeByArray(root->left, a); 214 } 215 if (a[visited] == -1) 216 { 217 root->right = NIL; 218 visited++; 219 } 220 else 221 { 222 root->right = new Node(); 223 root->right->parent = root; 224 CreateRBTreeByArray(root->right, a); 225 } 226 } 227 // 遍歷一顆紅黑樹 228 void TraverseRBTree(Node *root) 229 { 230 if (root != NIL) 231 { 232 TraverseRBTree(root->left); 233 cout << root->key << "顏色:"; 234 if (root->color == 1) 235 cout << "Red" << endl; 236 else 237 cout << "Black" << endl; 238 TraverseRBTree(root->right); 239 } 240 } 241 242 void SetRBTreeColorByArray(Node *root, int a[]) 243 { 244 if (root != NIL) 245 { 246 SetRBTreeColorByArray(root->left, a); 247 root->color = a[colorFlag]; 248 colorFlag++; 249 SetRBTreeColorByArray(root->right, a); 250 } 251 } 252 253 // 做爲普通二叉樹的插入操做,但仍須要進一步調整 254 void RBInsert(Node *root, Node *z) 255 { 256 Node* x = root; 257 Node* y = x->parent; 258 while (x != NIL) 259 { 260 y = x; 261 if (z->key < x->key) 262 { 263 x = x->left; 264 } 265 else 266 { 267 x = x->right; 268 } 269 } 270 z->parent = y; 271 if (z->key < y->key) 272 y->left = z; 273 else 274 y->right = z; 275 z->left = NIL; 276 z->right = NIL; 277 z->color = Red; 278 } 279 280 void LeftRotate(Node* root, Node *x) 281 { 282 Node *y = x->right; 283 x->right = y->left; 284 if (y->left != NIL) 285 y->left->parent = x; 286 y->parent = x->parent; 287 if (x->parent == NIL) 288 Root = y; 289 if (x == x->parent->left) 290 x->parent->left = y; 291 else 292 x->parent->right = y; 293 y->left = x; 294 x->parent = y; 295 } 296 297 void RightRotate(Node *root, Node *y) 298 { 299 Node *x = y->left; 300 y->left = x->right; 301 if (x->right!=NIL) 302 y->left->parent = x; 303 x->parent = y->parent; 304 if (x->parent == NIL) 305 Root = x; 306 if (y == y->parent->left) 307 y->parent->left = x; 308 else 309 y->parent->right = x; 310 x->right = y; 311 y->parent = x; 312 } 313 314 void RBFixup(Node *root, Node *z) 315 { 316 while (z->parent->color == Red) 317 { 318 if (z->parent == z->parent->parent->left) 319 { 320 Node *y = z->parent->parent->right; 321 if (y->color == Red) 322 { 323 y->color = Black; 324 z->parent->color = Black; 325 y->parent->color = Red; 326 z = y->parent; 327 } 328 else if (z == z->parent->right) 329 { 330 z = z->parent; 331 LeftRotate(Root, z); 332 333 z->parent->color = Black; 334 z->parent->parent->color = Red; 335 RightRotate(Root, z->parent->parent); 336 } 337 else 338 { 339 z->parent->color = Black; 340 z->parent->color = Red; 341 RightRotate(root, z->parent->parent); 342 } 343 } 344 else 345 { 346 347 } 348 } 349 Root->color = Black; 350 } 351 352 int main() 353 { 354 // 創建NIL 355 NIL = new Node(); 356 NIL->key = -1; // 規定NIL的key等於-1; 357 358 int a[] = {11, 2, 1, -1, -1, 7, 5, -1, -1, 8, -1, -1, 14, -1, 15, -1, -1 }; 359 int color[] = { Black, Red, Red, Black, Red, Black, Black, Red}; 360 Node *treeroot = new Node(); 361 treeroot->key = 15; 362 treeroot->parent = NIL; 363 Root = treeroot; 364 visited = 0; 365 colorFlag = 0; 366 CreateRBTreeByArray(treeroot, a); 367 /*SetNodeColor(treeroot);*/ 368 SetRBTreeColorByArray(treeroot, color); 369 TraverseRBTree(treeroot); 370 Node* Insert = new Node(); 371 Insert->key = 6; 372 RBInsert(treeroot, Insert); 373 cout << TreeSearch(Root, 11)->color << endl; 374 RBFixup(treeroot, Insert); 375 cout << TreeSearch(Root, 11)->color << endl; 376 TraverseRBTree(Root); 377 cout << TreeSearch(Root, 11)->color << endl; 378 return 0; 379 }