红黑树(RBTREE)之上-------构造红黑树

Posted 今夜星光灿烂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树(RBTREE)之上-------构造红黑树相关的知识,希望对你有一定的参考价值。

该怎么说呢,现在写代码的速度还是很快的,很高兴,o(^▽^)o。

光棍节到了,早上没忍住,手贱了一般,看到*D的优惠,买了个机械键盘,晚上就到了,敲着还是很舒服的,和老婆炫耀了一把哈哈。

光棍节再去*mall买个,带着上班用。

正题,构造红黑树,就是节点的插入与调整,具体的理论我就不说了,图我也不画了,别人画的很好,我在纸上画的我自己都不想看。

 

贴几个网址作为参考吧:

 

参考的文档:1.http://www.cnblogs.com/zhb-php/p/5504481.html (推荐)
2.http://www.cnblogs.com/skywang12345/p/3245399.html 参考,写的太详细了,反而不适合当文档
3.http://blog.csdn.net/v_july_v/article/details/6284050 这个刚好作为测试的参考图
这次的变量命名基本注意了,不过有些以前写的拿过来改改,懒得去把所有的都改了,写这个好像没有什么收获,好像数据结构基本的一些常用的都写了,还有个hash表下次写。
最近工作应该算是忙吧,但是做的都是偏测试的,更希望去写代码来锻炼自己。另一方面,解决问题感觉啥事都要靠自己啊,别人还是不靠谱的,以后尽量能不问别人就别去问了,感觉自己都烦了,问了别人解决不了
,浪费大家的时间最后还是要靠自己去解决。不爽。。。
环境:qt5
语言:c
代码:head_file:rb_func.h
 1 #ifndef RB_MAIN
 2 #define RB_MAIN
 3 
 4 #define DEBUG 1
 5 #define  RED   1
 6 #define  BLACK   0
 7 #define R RED
 8 #define  B BLACK
 9 #define OK 0
10 #define ERR -1
11 
12 #if 1
13 #define Left 1
14 #define Right -1
15 #endif
16 #ifndef NULL
17     #define NULL 0
18 #endif
19 #define PRINTTREEINIT(a)\\
20         printf("------------------init Tree begin-------------\\n");\\
21         PrintBTree(a);\\
22         printf("------------------init Tree end-------------\\n");
23 #define PRINTTREEAVL(a)\\
24         printf("------------------AVL Tree begin-------------\\n");\\
25         PrintBTree(a);\\
26         printf("------------------AVL Tree end-------------\\n");
27 
28 #define PRINTTREEDEL(a)\\
29         printf("------------------after del node Tree begin-------------\\n");\\
30         PrintBTree(a);\\
31         printf("------------------after del nodeTree end-------------\\n");
32 
33 #define PRINTTREEADJ(a)\\
34         printf("------------------after adjust  Tree begin-------------\\n");\\
35         PrintBTree(a);\\
36         printf("------------------after adjust Tree end-------------\\n");
37 typedef int  DATATYPE;
38 
39 typedef struct treenode
40 {
41     DATATYPE data;
42     struct treenode *parent;
43     struct treenode *lchild;
44     struct treenode *rchild;
45     unsigned int  color;
46 }TreeNode;
47 
48 
49 typedef TreeNode* RBTREE;
50 void PrintBTree(RBTREE* btree);
51 void PrintTreeNode(TreeNode* );
52 void PrintViewTreeNode(TreeNode* treeNode, int num);
53 void PrintNTab(int i);
54 /*
55 TreeNode* InitRBTree(DATATYPE oriData[],  int size);
56 */
57 RBTREE* InitRBTree(DATATYPE oriData[],  int size);
58 
59 TreeNode *GetFixNode(RBTREE *pRBTree, DATATYPE data);
60 TreeNode * InitRootNode(DATATYPE data, TreeNode* pNewTreeNode);
61 TreeNode *InsertNode(TreeNode* pParNode, DATATYPE data);
62 int AdjustNode(TreeNode* pParNode, RBTREE* pRBTree);
63 int IsLChild(TreeNode* pSonNode);
64 TreeNode* Spinning(TreeNode *pCurNode,unsigned int iOp, RBTREE* pRBTree);
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 #endif // RB_MAIN
head_file_code

process_file:rb_func.c

  1 #include "rb_func.h"
  2 
  3 
  4 
  5 void PrintNTab(int num)
  6 {
  7     int i = 0;
  8 
  9     while(i<num)
 10     {
 11        printf("    ");
 12        i++;
 13     }
 14 }
 15 
 16 void PrintViewTreeNode(TreeNode* treeNode, int num)
 17 {
 18     num++;
 19     char cColor;
 20     if(RED == treeNode->color ) cColor = \'R\';
 21     if(BLACK == treeNode->color ) cColor = \'B\';
 22     printf("%d %c", treeNode->data, cColor);
 23     if(treeNode->lchild == NULL)
 24     {
 25         printf("\\n");
 26         PrintNTab(num);
 27         printf("*");
 28     }
 29     else
 30     {    printf("\\n");
 31          PrintNTab(num);
 32          PrintViewTreeNode(treeNode->lchild, num);
 33     }
 34     if(treeNode->rchild == NULL)
 35     {
 36         printf("\\n");
 37         PrintNTab(num);
 38         printf("&");
 39 
 40     }
 41     else
 42     {
 43         printf("\\n");
 44         PrintNTab(num);
 45         PrintViewTreeNode(treeNode->rchild, num);
 46 
 47     }
 48 
 49 
 50 }
 51 
 52 /*这个看不出来树的结构了,需要重新写打印方法。*/
 53 void PrintTreeNode(TreeNode* treeNode)
 54 {
 55     if((treeNode->lchild == NULL)
 56             &&(treeNode->rchild == NULL))
 57     {
 58        printf("%d\\n", treeNode->data);
 59     }
 60     else
 61     {
 62         if((treeNode->lchild != NULL)
 63                 || (treeNode->rchild != NULL))
 64         {
 65             printf("%d ", treeNode->data);
 66             if(treeNode->lchild != NULL)
 67             {
 68                 printf("--->");
 69                 PrintTreeNode(treeNode->lchild);
 70             }
 71             printf("%d ", treeNode->data);
 72             if(treeNode->rchild != NULL)
 73             {
 74                 printf("===>");
 75                 PrintTreeNode(treeNode->rchild);
 76             }
 77         }
 78     }
 79     return ;
 80 }
 81 
 82 void PrintBTree(RBTREE* btree)
 83 {
 84     int num = 0;
 85     if(btree==NULL)
 86     {
 87         printf("empty tree.\\n");
 88     }
 89     #if 0
 90     printf("TreeView Rule---若一个节点有左右孩子节点,则父节点一行一列,左右孩子不同行同一列,若无做孩子,则打印的数据用*代替,如果无有孩子则打印的数据用&代替"
 91            "另外树的层次用4个空格来体现,比如第1列代表第一层,第5列代表第二层。\\n"
 92            );
 93     #endif
 94     printf("***********TREE View BEGIN***********\\n");
 95     PrintViewTreeNode(*btree, num);
 96     printf("\\n");
 97     printf("***********TREE View END ***********\\n");
 98     printf("\\n");
 99 }
100 
101 
102 TreeNode * InitRootNode(DATATYPE data, TreeNode* pNewTreeNode)
103 {
104     pNewTreeNode->data = data;
105     pNewTreeNode->parent = NULL;
106     pNewTreeNode->lchild = NULL;
107     pNewTreeNode->rchild = NULL;
108     pNewTreeNode->color = B;
109     return pNewTreeNode;
110 }
111 
112 
113 //查找合适的位置来插入新元素(find parent)
114 TreeNode *GetFixNode(RBTREE *pRBTree, DATATYPE data)
115 {
116      if((pRBTree == NULL ))
117      {
118          return NULL;
119      }
120 
121      if(((*pRBTree)->lchild == NULL)
122              &&((*pRBTree)->rchild == NULL))
123      {
124          printf("insert under root \\n");
125          return *pRBTree;
126      }
127      TreeNode* pCurTreeNode = *pRBTree;
128      while( (pCurTreeNode->lchild != NULL)
129            ||(pCurTreeNode->rchild !=NULL) )
130      {
131          if(data > pCurTreeNode->data)
132          {
133              //printf("insert R \\n");
134              printf(" data=[%d] curData=[%d] insert R \\n", data, pCurTreeNode->data);
135              if(pCurTreeNode->rchild != NULL)
136              {
137                  printf("pCurTreeNode->rchild != NULL rchild[%d]\\n", pCurTreeNode->rchild->data);
138                  pCurTreeNode = pCurTreeNode->rchild;
139 
140              }else{
141 
142                  break;
143              }
144          }
145          else if(data < pCurTreeNode->data)
146          {
147              printf(" data=[%d] curData=[%d] insert L \\n", data, pCurTreeNode->data);
148              if(pCurTreeNode->lchild != NULL)
149              {
150                  pCurTreeNode = pCurTreeNode->lchild;
151              }else{
152                  break;
153              }
154          }
155          else
156          {
157              printf("invaild elem here at line %d.\\n", __LINE__);
158              return NULL;
159          }
160      }
161      return pCurTreeNode;
162 }
163 
164 //将一个值插入节点的L/R子树上
165 TreeNode *InsertNode(TreeNode* pParNode, DATATYPE data)
166 {
167 #if DEBUG
168     /*这里要处理相等的情况*/
169     if(data == pParNode->data)
170     {
171         printf("invaild data %d\\n", data);
172         printf("invaild para here at line %d.\\n", __LINE__);
173         return NULL;
174     }
175 #endif
176     TreeNode* pSonTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
177     pSonTreeNode->data = data;
178     pSonTreeNode->lchild = NULL;
179     pSonTreeNode->rchild = NULL;
180     pSonTreeNode->color = RED;
181     pSonTreeNode->parent = pParNode;
182     if(data < pParNode->data)
183     {
184          pParNode->lchild = pSonTreeNode;
185     }
186     else{
187         pParNode->rchild = pSonTreeNode;
188     }
189     return pSonTreeNode;
190 }
191 TreeNode* Spinning(TreeNode *pCurNode,unsigned int iOp, RBTREE* pRBTree)
192 {
193     TreeNode *pLChild = NULL;
194     TreeNode *pRChild = NULL;
195     TreeNode *pParent = NULL;
196 
197     //TreeNode *pA = NULL;
198     int iIsLChild = IsLChild(pCurNode);
199     if(NULL == pCurNode) return NULL;
200     if(Left == iOp)
201     {
202         //左旋
203         if(NULL == pCurNode->rchild) return NULL;
204         pLChild = pCurNode->rchild->lchild;/*z的左孩子*/
205         pRChild = pCurNode->rchild;
206         if(-1 != iIsLChild){
207             pParent = pCurNode->parent;
208         }
209         else
210         {
211             *pRBTree = pRChild;
212         }
213         if(NULL != pLChild)
214         {
215             pLChild->parent = pCurNode;
216         }
217         pCurNode->rchild = pLChild;
218 
219         pRChild->lchild = pCurNode;
220         pCurNode->parent = pRChild;
221 
222         pRChild->parent = pParent;
223         if(-1 != iIsLChild)
224         {
225             if(1 == iIsLChild)
226             {
227                 pParent->lchild = pRChild;
228             }
229             else
230             {
231                 pParent->rchild = pRChild;
232             }
233         }
234         return pRChild;
235     }
236     else if(Right == iOp)
237     {
238           //右旋
239         if(NULL == pCurNode->lchild) return NULL;
240         pRChild = pCurNode->lchild->rchild;/*z的左孩子*/
241         pLChild = pCurNode->lchild;
242         if(-1 != iIsLChild){
243             pParent = pCurNode->parent;
244         }
245         else
246         {
247             *pRBTree = pLChild;
248         }
249         if(NULL != pRChild)
250         {
251             pRChild->parent = pCurNode;
252         }
253         pCurNode->lchild = pRChild;
254 
255         pLChild->rchild = pCurNode;
256         pCurNode->parent = pLChild;
257 
258         pLChild->parent = pParent;
259         if(-1 != iIsLChild)
260         {
261             if(1 == iIsLChild)
262             {
263                 pParent->lchild = pLChild;
264             }
265             else
266             {
267                 pParent->rchild = pLChild;
268             }
269         }
270         return pLChild;
271 
272     }
273 }
274 int AdjustNode(TreeNode* pCurNode, RBTREE* pRBTree)
275 {
276     if(NULL == pRBTree) goto err;
277     int LRFlag = 0;
278     int CurLRFlag = 0;
279 
280     if(BLACK == pCurNode->parent->color) return OK;
281     unsigned int iCase = 0;
282     TreeNode *pParNode = pCurNode->parent;
283     LRFlag = IsLChild(pParNode);
284     CurLRFlag = IsLChild(pCurNode);
285     if(LRFlag)
286     {
287   /*tsb*/
288         if((NULL != pParNode->parent->rchild)&&
289                 (RED == pParNode->parent->rchild->color))
290         {
291             iCase = 1;
292         }else
293         {
294             if(CurLRFlag)
295             { /*case 2:父节点是左孩子当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左孩子;        */
296                 /*cur in L*/
297                 iCase = 2;
298 
299             }
300             else
301             { /*case 3:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子;     */
302                 iCase = 3;
303             }
304 
305         }
306   /*tse*/
307 #if 0
308         if(NULL != pParNode->parent->rchild)
309         {
310             if(//(RED == pParNode->color)&&
311                 (RED == pParNode->parent->rchild->color))
312             { /*case 1:父节点是左孩子 如果当前结点的父结点是红色且祖父结点的另一个子结点(叔叔结点)是红色;        */
313                 iCase = 1;
314             }
315             else if(//(RED == pParNode->color)&&
316                   (B == pParNode->parent->rchild->color))
317             {
318                 if(CurLRFlag)
319                 { /*case 2:父节点是左孩子当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左孩子;        */
320                     /*cur in L*/
321                     iCase = 2;
322 
323                 }
324                 else
325                 { /*case 3:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子;     */
326                     iCase = 3;
327                 }
328             }
329         }
330         else
331         {
332             if(CurLRFlag)
333             { /*case 2:父节点是左孩子当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左孩子;        */
334                 /*cur in L*/
335                 iCase = 2;
336 
337             }
338             else
339             { /*case 3:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子; 

以上是关于红黑树(RBTREE)之上-------构造红黑树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树之红黑树(RBTree)

红黑树(RBTree)的简单操作

红黑树(未验证)

为啥 CFS 调度器使用红黑树?

C++ 泛型编程 实现红黑树RBTree

Nginx数据结构之红黑树ngx_rbtree_t