现在的位置: 首页 > 综合 > 正文

红黑树的C++实现–根据《算法导论》中的算法实现

2012年10月21日 ⁄ 综合 ⁄ 共 9237字 ⁄ 字号 评论关闭

  红黑树是一种有序的平衡二叉树,STL中的map和set容器的底层实现就是红黑树,在《STL源码剖析》中有另一种实现方式。不过STL中的实现相对来说晦涩难懂,而《算法导论》中的算法则比较清晰易懂。这里的这份实现就是《算法导论》中STL算法的一种C++实现。关于红色树的特性以及规则这里还有这里都有详细描述。下面就是我的实现代码:

  1 #ifndef        __RBTREE_H__
  2 #define        __RBTREE_H__
  3 
  4 #include <iostream>
  5 const int RED = 0;
  6 const int BLACK = 1;
  7 
  8 struct RBTreeNode
  9 {
 10     RBTreeNode* left;
 11     RBTreeNode* right;
 12     RBTreeNode* parent;
 13     int nData;
 14     int color;//RED=0,BLACK=1
 15 };
 16 
 17 class RBTree
 18 {
 19 
 20 public:
 21     RBTree();
 22     ~RBTree();
 23 public:
 24     bool Insert(const int nData);
 25     bool Delete(const int nData);
 26     RBTreeNode* Find(const int nData);
 27     void Display() 
 28     {
 29         PrintTree(root);
 30     }
 31 private:
 32     void RotateLeft(RBTreeNode* pNode);
 33     void RotateRight(RBTreeNode* pNode);
 34     void InsertFixup(RBTreeNode* pNode);
 35     void DeleteFixup(RBTreeNode* pNode);
 36 
 37     RBTreeNode* CreateNode(int nData);
 38     RBTreeNode* DeleteNode(RBTreeNode* pNode);
 39     RBTreeNode* FindNode(const int nData);
 40     RBTreeNode* Maximum(RBTreeNode* pNode);
 41     RBTreeNode* Minimum(RBTreeNode* pNode);
 42     RBTreeNode* Successor(RBTreeNode* pNode);
 43 
 44     void DeleteTree(RBTreeNode* pNode);
 45     void PrintTree(RBTreeNode* pNode) const;
 46 private:
 47     RBTreeNode* root;
 48     RBTreeNode* nil;
 49     int    node_count;
 50 };
 51 
 52 RBTree::RBTree()
 53 {
 54     nil = new RBTreeNode();
 55 
 56     nil->left = NULL;
 57     nil->right = NULL;
 58     nil->parent = NULL;
 59     nil->nData = 0;
 60     nil->color = BLACK;
 61 
 62     root = nil;
 63 }
 64 
 65 RBTree::~RBTree()
 66 {
 67     DeleteTree(root);
 68     delete nil;
 69     root = NULL;
 70     nil = NULL;
 71 }
 72 
 73 RBTreeNode* RBTree::CreateNode(int nData)
 74 {
 75     RBTreeNode* pTempNode = new RBTreeNode();
 76 
 77     pTempNode->left = nil;
 78     pTempNode->right = nil;
 79     pTempNode->parent = nil;
 80     pTempNode->nData = nData;
 81     pTempNode->color = RED;
 82 
 83     return pTempNode;
 84 }
 85 
 86 void RBTree::DeleteTree(RBTreeNode* pNode)
 87 {
 88     if(pNode == nil)
 89         return;
 90 
 91     DeleteTree(pNode->left);
 92     DeleteTree(pNode->right);
 93 
 94     delete pNode;
 95     pNode = NULL;
 96 }
 97 
 98 //左旋转
 99 void RBTree::RotateLeft(RBTreeNode* pNode)
100 {
101     RBTreeNode* pRNode = pNode->right;
102     pNode->right = pRNode->left;
103 
104     if(pRNode->left != nil)
105     {
106         pRNode->left->parent = pNode;
107         pRNode->parent = pNode->parent;
108     }
109 
110     if(pNode->parent == nil)
111     {
112         root = pRNode;
113     }
114     else if(pNode->parent->left == pNode)
115     {
116         pNode->parent->left = pRNode;
117     }
118     else
119     {
120         pNode->parent->right = pRNode;
121     }
122 
123     pRNode->left = pNode;
124     pNode->parent = pRNode;
125 }
126 
127 //右旋转
128 void RBTree::RotateRight(RBTreeNode* pNode)
129 {
130     RBTreeNode* pLNode = pNode->left;
131     pNode->left = pLNode->right;
132 
133     if(pLNode->right != nil)
134     {
135         pLNode->right->parent = pNode;
136         pLNode->parent = pNode->parent;
137     }
138 
139     if(pNode->parent == nil)
140     {
141         root = pLNode;
142     }
143     else if(pNode->parent->left == pNode)
144     {
145         pNode->parent->left = pLNode;
146     }
147     else
148     {
149         pNode->parent->right = pLNode;
150     }
151 
152     pLNode->right = pNode;
153     pNode->parent = pLNode;
154 }
155 
156 RBTreeNode* RBTree::Maximum(RBTreeNode* pNode)
157 {
158     while(pNode->right != nil)
159         pNode = pNode->right;
160 
161     return pNode;
162 }
163 
164 RBTreeNode* RBTree::Minimum(RBTreeNode* pNode)
165 {
166     while(pNode->left != nil)
167         pNode = pNode->left;
168 
169     return pNode;
170 }
171 
172 RBTreeNode* RBTree::Successor(RBTreeNode* pNode)
173 {
174     if(pNode->right != nil)
175         return Minimum(pNode->right);
176     
177     RBTreeNode* pPNode = pNode->parent;
178     while(pPNode != nil && pNode == pPNode->right)
179     {
180         pNode = pPNode;
181         pPNode = pNode->parent;
182     }
183 
184     return pPNode;
185 }
186 
187 bool RBTree::Insert(const int nData)
188 {
189     RBTreeNode* pNewNode = CreateNode(nData);
190     RBTreeNode* pPNewNode = nil;
191     RBTreeNode* pTemp = root;
192 
193     while( pTemp != nil)
194     {
195         pPNewNode = pTemp;
196 
197         if(nData < pTemp->nData)
198             pTemp = pTemp->left;
199         else
200             pTemp = pTemp->right;
201     }
202 
203     pNewNode->parent = pPNewNode;
204 
205     if(pPNewNode == nil)
206         root = pNewNode;
207     else if(nData < pPNewNode->nData)
208         pPNewNode->left = pNewNode;
209     else
210         pPNewNode->right = pNewNode;
211 
212     InsertFixup(pNewNode);
213 
214     return true;
215 }
216 
217 void RBTree::InsertFixup(RBTreeNode* pNode)
218 {
219     while(pNode->parent->color == RED)
220     {
221         if(pNode->parent == pNode->parent->parent->left)
222         {
223             RBTreeNode* pUNode = pNode->parent->parent->right;//pNode的叔父节点
224             
225             if(pUNode->color == RED)//case 1
226             {
227                 pNode->parent->color = BLACK;
228                 pUNode->color = BLACK;
229                 pNode->parent->parent->color = RED;
230 
231                 pNode = pNode->parent->parent;
232             }
233             else if(pNode == pNode->parent->right)//case 2
234             {
235                 pNode = pNode->parent;
236                 RotateLeft(pNode);
237             }
238             else//case 3
239             {
240                 pNode->parent->color = BLACK;
241                 pNode->parent->parent->color = RED;
242                 RotateRight(pNode->parent->parent);
243             }
244         }//pNode的父节点是其父节点的左子节点
245         else
246         {
247             RBTreeNode* pUNode = pNode->parent->parent->left;//pNode的叔父节点
248             
249             if(pUNode->color == RED)//case 1
250             {
251                 pNode->parent->color = BLACK;
252                 pUNode->color = BLACK;
253                 pNode->parent->parent->color = RED;
254 
255                 pNode = pNode->parent->parent;
256             }
257             else if(pNode == pNode->parent->left)//case 2
258             {
259                 pNode = pNode->parent;
260                 RotateRight(pNode);
261             }
262             else//case 3
263             {
264                 pNode->parent->color = BLACK;
265                 pNode->parent->parent->color = RED;
266                 RotateLeft(pNode->parent->parent);
267             }        
268         }//pNode的父节点是其父节点的右子节点
269     }//while(pNode->parent->color == RED)
270 
271     root->color = BLACK;
272 }
273 
274 bool RBTree::Delete(const int nData)
275 {
276     RBTreeNode* pDeleteNode = FindNode(nData);
277 
278     if(pDeleteNode == nil)
279     {
280         std::cout << "no data" << std::endl;
281         return false;
282     }
283 
284     DeleteNode(pDeleteNode);
285 
286     return true;
287 }
288 
289 RBTreeNode* RBTree::FindNode(const int nData)
290 {
291     RBTreeNode* pTemp = root;
292 
293     while(pTemp != nil)
294     {
295         if(nData < pTemp->nData)
296             pTemp = pTemp->left;
297         else if(nData > pTemp->nData)
298             pTemp = pTemp->right;
299         else
300             return pTemp;
301     }
302 
303     return nil;
304 }
305 
306 RBTreeNode* RBTree::DeleteNode(RBTreeNode* pNode)
307 {
308     RBTreeNode* pDeleteNode = nil;//删除节点
309     RBTreeNode* pCDeleteNode = nil;//删除节点的子节点
310 
311     if(pNode->left == nil || pNode->right == nil)
312         pDeleteNode = pNode;
313     else
314         pDeleteNode = Successor(pNode);
315     
316     if(pDeleteNode->left != nil)
317         pCDeleteNode = pDeleteNode->left;
318     else
319         pCDeleteNode = pDeleteNode->right;
320 
321     if(pDeleteNode->parent == nil)
322         root = pCDeleteNode;
323     else if(pDeleteNode == pDeleteNode->parent->left)
324         pDeleteNode->parent->left = pCDeleteNode;
325     else
326         pDeleteNode->parent->right = pCDeleteNode;
327 
328     if(pDeleteNode != pNode)
329         pNode->nData = pDeleteNode->nData;
330 
331     pCDeleteNode->parent = pDeleteNode->parent;
332 
333     if(pDeleteNode->color == BLACK)
334         DeleteFixup(pCDeleteNode);
335 
336     return pDeleteNode;
337 }
338 
339 void RBTree::DeleteFixup(RBTreeNode* pNode)
340 {
341     while(pNode != root && pNode->color == BLACK)
342     {
343         if(pNode == pNode->parent->left)
344         {
345             RBTreeNode* pBNode = pNode->parent->right;//pNode的兄弟节点
346 
347             if(pBNode->color = RED)//case 1
348             {
349                 pBNode->color = BLACK;
350                 pNode->parent->color = RED;
351 
352                 RotateLeft(pNode->parent);
353                 pBNode = pNode->parent->right;
354             }
355 
356             if(pBNode->left->color == BLACK && pBNode->right->color == BLACK)//case 2
357             {
358                 pBNode->color = RED;
359                 pNode = pNode->parent;
360             }
361             else if(pBNode->right->color == BLACK)//case 3
362             {
363                 pBNode->left->color = BLACK;
364                 pBNode->color = RED;
365 
366                 RotateRight(pBNode);
367                 pBNode = pNode->parent->right;
368             }
369             else//case 4
370             {
371                 pBNode->color = pNode->parent->color;
372                 pNode->parent->color = BLACK;
373                 pBNode->right->color = BLACK;
374 
375                 RotateLeft(pNode->parent);
376                 pNode = root;
377             }
378         }
379         else
380         {
381             RBTreeNode* pBNode = pNode->parent->left;//pNode的兄弟节点
382 
383             if(pBNode->color = RED)//case 1
384             {
385                 pBNode->color = BLACK;
386                 pNode->parent->color = RED;
387 
388                 RotateLeft(pNode->parent);
389                 pBNode = pNode->parent->left;
390             }
391 
392             if(pBNode->left->color == BLACK && pBNode->right->color == BLACK)//case 2
393             {
394                 pBNode->color = RED;
395                 pNode = pNode->parent;
396             }
397             else if(pBNode->left->color == BLACK)//case 3
398             {
399                 pBNode->right->color = BLACK;
400                 pBNode->color = RED;
401 
402                 RotateRight(pBNode);
403                 pBNode = pNode->parent->left;
404             }
405             else//case 4
406             {
407                 pBNode->color = pNode->parent->color;
408                 pNode->parent->color = BLACK;
409                 pBNode->left->color = BLACK;
410 
411                 RotateLeft(pNode->parent);
412                 pNode = root;
413             }        
414         }//if(pNode == pNode->parent->left)
415     }//while(pNode != root && pNode->color == BLACK)
416 
417     pNode->color = BLACK;
418 }
419 
420 void RBTree::PrintTree(RBTreeNode* pNode) const
421 {
422     if (NULL == root)
423         return;
424 
425     if (nil == pNode)
426     {
427         return;
428     }
429 
430     static int n = 0;
431     
432     if(pNode == root)
433     {
434         std::cout << "[" << ++n << "]nData = " << pNode->nData << ",nParentData= 0 ,";
435 
436         if(pNode->left)
437             std::cout << "nLeftData= " << pNode->left->nData << " ,";
438         if(pNode->right)
439             std::cout << "nRightData= " << pNode->right->nData << " ,";
440 
441         std::cout << "color = " << pNode->color << std::endl;
442     }
443     else
444     {
445         std::cout << "[" << ++n << "]nData = " << pNode->nData << ",nParentData= " << pNode->parent->nData << " ,";
446 
447         if(pNode->left)
448             std::cout << "nLeftData= " << pNode->left->nData << " ,";
449         if(pNode->right)
450             std::cout << "nRightData= " << pNode->right->nData << " ,";
451 
452         std::cout << "color = " << pNode->color << std::endl;
453     }
454     PrintTree(pNode->left);
455     PrintTree(pNode->right);
456 }
457 
458 #endif        //__RBTREE_H__

  将上面的代码复制粘贴到同一个文件中,文件名RBTree.h。下面是测试程序复制到文件Test.cpp中。

 1 #include "RBTree.h"
 2 #include <iostream>
 3 #include <exception>
 4 
 5 int main()
 6 {
 7     try
 8     {
 9         RBTree rbt;
10         for(int i = 1; i < 10; i++)
11         {
12             rbt.Insert(i);
13         }
14         rbt.Delete(4);
15         rbt.Display();
16     }
17     catch (std::exception& e)
18     {
19         std::cout << e.what() << std::endl;
20     }
21 }

  然后用g++ -o Test Test.cpp该命令进行编译。执行结果如下:

 1 [kiven@localhost Test]$ g++ -o Test Test.cpp
 2 [kiven@localhost Test]$ ls
 3 RBTree.h  Test  Test.cpp
 4 [kiven@localhost Test]$ ./Test
 5 [1]nData = 2,nParentData= 0 ,nLeftData= 1 ,nRightData= 5 ,color = 1
 6 [2]nData = 1,nParentData= 2 ,nLeftData= 0 ,nRightData= 0 ,color = 1
 7 [3]nData = 5,nParentData= 3 ,nLeftData= 3 ,nRightData= 6 ,color = 0
 8 [4]nData = 3,nParentData= 5 ,nLeftData= 0 ,nRightData= 0 ,color = 1
 9 [5]nData = 6,nParentData= 8 ,nLeftData= 0 ,nRightData= 7 ,color = 1
10 [6]nData = 7,nParentData= 6 ,nLeftData= 0 ,nRightData= 0 ,color = 0
11 [kiven@localhost Test]$

  上面的实现也仅仅是实现了数据结构本身,所以整个都比较粗糙,节点中的数据也用最简单的整形来代替,但是基本功能不缺。

抱歉!评论已关闭.