算法導論 第13章 紅黑樹

爲了讓這片博客看起來更有養分一些,我仍是在添加一些紅黑樹的設計原理吧?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 }
相關文章
相關標籤/搜索