红黑树(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
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)之上-------构造红黑树的主要内容,如果未能解决你的问题,请参考以下文章