平衡二叉树(AVLTREE,双链表实现)
Posted 今夜星光灿烂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡二叉树(AVLTREE,双链表实现)相关的知识,希望对你有一定的参考价值。
首先说下好久没更新了,最近打游戏和工作都有点多,o(^▽^)o。
写这个AVL发现自己的代码风格好差,尤其是变量命名这块,后来意识到了,想去改,但是太多了,改了几个就不想改了,做这个是记录下自己的成长吧。
另外说下,调这个AVL真心有点烦了,前面写了一个,但是逻辑有点乱,基本的删除都测差不多ok了,发现一个bug,实在不想去看那代码,太乱了,后来强b这自己去重新写,花了1个多小时(当然是加班的时候理),理清了,晚上9点多回来,大概3个小时,把del这块从新改完了,写代码真的是一个时候一个思想,发现处理节点只有单个分支的时候,还是第一次的思想好,直接指针操作一下,逻辑很精简,具体可以看code708的那2段逻辑处理,在处理删除节点有2个孩子节点时,在思考用指针直接处理,还是用一个临时变量来操作,最后选择了临时变量节点来处理,具体为什么,因为简单,而且仔细想了想这样处理是没错的,node里data基本只是一个keyValue,用在avl里查找,删除,构造做参考的,这个地方也有考虑用指针,也实现了,基本没多大问题,后来出bug的时候在那理了半天,实在受不了,把他改造了。
另外printAVL的函数直接copy BTree的,这个没什么好说的,还有AVL查找,这个真的不用我写了。本文主要就实现任意的一个数组构造AVLTree,删除AVLTree的任意个节点,保证AVLTree的特性。
具体贴代码,如下,测试的例子,都ok的,具体的放开,还有千万一定要吐槽我的变量命名及注释及很多,我在改,下次写的时候一定注意。
/*运行环境QT C */
1 #include <stdio.h> 2 #define DEBUG 0 3 //参考图http://www.cnblogs.com/skywang12345/p/3577360.html 4 #define PRINTTREEINIT(a)\\ 5 printf("------------------init Tree begin-------------\\n");\\ 6 PrintBTree(a);\\ 7 printf("------------------init Tree end-------------\\n"); 8 #define PRINTTREEAVL(a)\\ 9 printf("------------------AVL Tree begin-------------\\n");\\ 10 PrintBTree(a);\\ 11 printf("------------------AVL Tree end-------------\\n"); 12 13 #define PRINTTREEDEL(a)\\ 14 printf("------------------after del node Tree begin-------------\\n");\\ 15 PrintBTree(a);\\ 16 printf("------------------after del nodeTree end-------------\\n"); 17 18 #define PRINTTREEADJ(a)\\ 19 printf("------------------after adjust Tree begin-------------\\n");\\ 20 PrintBTree(a);\\ 21 printf("------------------after adjust Tree end-------------\\n"); 22 #define L 1 23 #define R -1 24 #define BTREE AVLTree 25 typedef struct treenode 26 { 27 int data; 28 int hight; 29 struct treenode *parent; 30 struct treenode *lchild; 31 struct treenode *rchild; 32 } TreeNode; 33 typedef enum {LL=0,LR,RR,RL,RLR} TURNFLAG; 34 typedef TreeNode* AVLTree; 35 typedef int DATATYPE; 36 int IsLeafNode(TreeNode* Node); 37 //void DeleteNode(AVLTree* btree, DATATYPE delData); 38 void DeleteNode(AVLTree* btree, DATATYPE delData); 39 40 TreeNode* InitNode(int data); 41 void InitAVLTree(AVLTree *avlTree, TreeNode *root); 42 43 TreeNode *GetFixNode(AVLTree *btree, DATATYPE data); 44 int GetTreeHight(AVLTree *btree); 45 TreeNode *InsertNode(TreeNode* parNode, DATATYPE data); 46 int GetDiffHeight(TreeNode* rootNode); 47 int AdjustNode(TreeNode* posNode, AVLTree *avlTree); 48 int GetSymDiffHeight(TreeNode* rootNode); 49 int IsRoot(TreeNode* rootNode); 50 int IsLChild(TreeNode* rootNode); 51 TreeNode *GetMaxNode(TreeNode* rootNode); 52 TreeNode *GetMinNode(TreeNode* rootNode); 53 TreeNode* AdjustNodeByTurnFlag(TreeNode** Node,TURNFLAG a, AVLTree *avlTree); 54 void PrintNTab(int num); 55 void PrintBTree(BTREE* btree); 56 void PrintViewTreeNode(TreeNode* treeNode, int num); 57 TreeNode* GetPosByKeyValue(TreeNode* rootNode,int key); 58 int GetChildNum(TreeNode* rootNode); 59 int GetChildNum(TreeNode* curNode) 60 { 61 if((NULL != curNode->lchild)&&(NULL != curNode->rchild)) return 2; 62 if((NULL != curNode->lchild)&&(NULL == curNode->rchild)) return 1; 63 if((NULL == curNode->lchild)&&(NULL != curNode->rchild)) return -1; 64 if((NULL == curNode->lchild)&&(NULL == curNode->rchild)) return 0; 65 66 } 67 TreeNode *GetMaxNode(TreeNode* rootNode) 68 { 69 if(rootNode == NULL) return NULL; 70 if(NULL == rootNode->rchild) return rootNode; 71 TreeNode *curNode = rootNode; 72 while((NULL != curNode)&&(NULL != curNode->rchild)) 73 { 74 curNode = curNode->rchild; 75 } 76 return curNode; 77 } 78 79 TreeNode *GetMinNode(TreeNode* rootNode) 80 { 81 if(rootNode == NULL) return NULL; 82 if(NULL == rootNode->lchild) return rootNode; 83 TreeNode *curNode = rootNode; 84 while((NULL != curNode)&&(NULL != curNode->lchild)) 85 { 86 curNode = curNode->lchild; 87 } 88 return curNode; 89 } 90 91 TreeNode* GetPosByKeyValue(TreeNode* rootNode,int data) 92 { 93 if(rootNode == NULL) return NULL; 94 if(data == rootNode->data) return rootNode; 95 96 97 TreeNode* curTreeNode = rootNode; 98 99 while( NULL != curTreeNode ) 100 { 101 if(data > curTreeNode->data) 102 { 103 if(curTreeNode->rchild != NULL) 104 { 105 //printf("curTreeNode->rchild != NULL rchild[%d]\\n", curTreeNode->rchild->data); 106 curTreeNode = curTreeNode->rchild; 107 }else{ 108 curTreeNode = NULL; 109 break; 110 } 111 } 112 else if(data < curTreeNode->data) 113 { 114 if(curTreeNode->lchild != NULL) 115 { 116 curTreeNode = curTreeNode->lchild; 117 }else{ 118 curTreeNode = NULL; 119 break; 120 } 121 } 122 else 123 { 124 printf("find key.\\n", __LINE__); 125 return curTreeNode; 126 } 127 128 } 129 if(NULL == curTreeNode) 130 { 131 printf("Not find key.\\n", __LINE__); 132 return curTreeNode; 133 } 134 135 } 136 void PrintViewTreeNode(TreeNode* treeNode, int num) 137 { 138 if(NULL == treeNode) return ; 139 num++; 140 printf("%d", treeNode->data); 141 if(treeNode->lchild == NULL) 142 { 143 printf("\\n"); 144 PrintNTab(num); 145 printf("*"); 146 } 147 else 148 { printf("\\n"); 149 PrintNTab(num); 150 PrintViewTreeNode(treeNode->lchild, num); 151 } 152 if(treeNode->rchild == NULL) 153 { 154 printf("\\n"); 155 PrintNTab(num); 156 printf("&"); 157 158 } 159 else 160 { 161 printf("\\n"); 162 PrintNTab(num); 163 PrintViewTreeNode(treeNode->rchild, num); 164 165 } 166 167 168 } 169 void PrintBTree(BTREE* btree) 170 { 171 int num = 0; 172 if(btree==NULL) 173 { 174 printf("empty tree.\\n"); 175 } 176 177 printf("***********TREE View BEGIN***********\\n"); 178 //PrintTreeNode((*btree)); 179 PrintViewTreeNode(*btree, num); 180 printf("\\n"); 181 printf("***********TREE View END ***********\\n"); 182 printf("\\n"); 183 184 printf("\\n"); 185 186 187 } 188 void PrintNTab(int num) 189 { 190 int i = 0; 191 192 while(i<num) 193 { 194 printf(" "); 195 i++; 196 } 197 } 198 TreeNode* AdjustNodeByTurnFlag(TreeNode** node,TURNFLAG tFlag,AVLTree *avlTree) 199 {//* > ->优先级 200 TreeNode* nodeTmp = (TreeNode* )malloc(sizeof(TreeNode)); 201 TreeNode* freeNode = NULL; 202 int isRootNode = 0; 203 int sdh = 0; 204 int iRet = 0; 205 memset(nodeTmp, 0x00, sizeof(TreeNode)); 206 if(((tFlag>3) ||(tFlag <0)|| ((*node)==NULL))) return NULL; 207 switch (tFlag){ 208 case LL: 209 freeNode = *node; 210 memcpy(nodeTmp,(*node)->lchild,sizeof(TreeNode)); 211 *node = (*node)->lchild; 212 213 (*node)->parent = nodeTmp->parent; 214 iRet = IsLChild(freeNode); 215 if(iRet == -1) 216 { 217 //root 218 isRootNode = 1; 219 } 220 else if(1 == iRet) 221 { 222 //isLchild 223 freeNode->parent->lchild = *node; 224 } 225 else if(0 == iRet) 226 { 227 //isRchild 228 freeNode->parent->rchild = *node; 229 } 230 231 (*node)->rchild = freeNode; 232 freeNode->parent = *node; 233 234 freeNode->lchild = nodeTmp->rchild; 235 if(NULL != nodeTmp->rchild) 236 { 237 freeNode->lchild->parent = freeNode; 238 } 239 if(isRootNode) 240 { 241 *avlTree = *node; 242 } 243 free(nodeTmp); 244 break; 245 case LR: 246 freeNode = *node; 247 memcpy(nodeTmp,(*node)->lchild->rchild,sizeof(TreeNode)); 248 *node = (*node)->lchild->rchild; 249 (*node)->parent = freeNode->parent; 250 iRet = IsLChild(freeNode); 251 if(iRet == -1) 252 { 253 //root 254 isRootNode = 1; 255 } 256 else if(1 == iRet) 257 { 258 //isLchild 259 freeNode->parent->lchild = *node; 260 } 261 else if(0 == iRet) 262 { 263 //isRchild 264 freeNode->parent->rchild = *node; 265 266 } 267 (*node)->lchild = freeNode->lchild; 268 freeNode->lchild->parent = *(node); 269 freeNode->lchild->rchild = NULL; 270 freeNode->lchild = NULL; 271 272 (*node)->rchild = freeNode; 273 freeNode->parent = *(node); 274 275 freeNode->lchild = nodeTmp->rchild; 276 (*node)->lchild->rchild = nodeTmp->lchild; 277 if(NULL != nodeTmp->rchild) 278 { 279 nodeTmp->rchild->parent = freeNode; 280 } 281 if(NULL != nodeTmp->lchild) 282 { 283 nodeTmp->lchild->parent = (*node)->lchild; 284 } 285 286 if(isRootNode) 287 { 288 *avlTree = *node; 289 } 290 free(nodeTmp); 291 break; 292 293 case RR: 294 //直接改变指针,所以入参是二级指针 295 freeNode = *node; 296 memcpy(nodeTmp,*node,sizeof(TreeNode)); 297 *node=(*node)->rchild; 298 299 if(nodeTmp->parent != NULL) 300 { 301 if(IsLChild(nodeTmp)){nodeTmp->parent->lchild = *node;} 302 else {nodeTmp->parent->rchild = *node;} 303 } 304 else 305 { 306 //说明nodeTmp是根节点,要改变树的节点 307 isRootNode = 1; 308 } 309 310 if((*node)->lchild){ 311 nodeTmp->rchild = (*node)->lchild; 312 (*node)->lchild->parent = nodeTmp; 313 } 314 (*node)->parent = nodeTmp->parent; 315 (*node)->lchild = nodeTmp; 316 nodeTmp->parent = *node; 317 if(isRootNode) 318 { 319 *avlTree = *node; 320 } 321 free(freeNode); 322 //树的根节点被改了,这里要注意,刚好玩玩二级指针 323 break; 324 case RL: 325 freeNode = *node; 326 memcpy(nodeTmp,(*node)->rchild->lchild,sizeof(TreeNode)); 327 *node = (*node)->rchild->lchild; 328 (*node)->parent = freeNode->parent; 329 iRet = IsLChild(freeNode); 330 if(iRet == -1) 331 { 332 //root 333 isRootNode = 1; 334 } 335 else if(1 == iRet) 336 { 337 //isLchild 338 freeNode->parent->lchild = *node; 339 } 340 else if(0 == iRet) 341 { 342 //isRchild 343 freeNode->parent->rchild = *node; 344 345 } 346 (*node)->rchild = freeNode->rchild; 347 freeNode->rchild->parent = *(node); 348 freeNode->rchild->lchild = NULL; 349 freeNode->rchild = NULL; 350 351 (*node)->lchild = freeNode; 352 freeNode->parent = *(node); 353 354 freeNode->rchild = nodeTmp->lchild; 355 (*node)->rchild->lchild = nodeTmp->rchild; 356 if(NULL != nodeTmp->lchild) 357 { 358 nodeTmp->lchild->parent = freeNode; 359 } 360 if(NULL != nodeTmp->rchild) 361 { 362 nodeTmp->rchild->parent = (*node)->rchild; 363 } 364 365 if(isRootNode) 366 { 367 *avlTree = *node; 368 } 369 free(nodeTmp); 370 break; 371 default: 372 break; 373 } 374 return *node; 375 376 } 377 378 //1->is 379 int IsLChild(TreeNode* sonNode) 380 { 381 if(sonNode->parent ==NULL)return -1; 382 return ((sonNode->parent->lchild == sonNode)?1:0); 383 } 384 385 386 //1->is 387 int IsRoot(TreeNode* rootNode) 388 { 389 return(rootNode->parent == NULL); 390 } 391 int GetDiffHeight(TreeNode* rootNode) 392 { 393 394 int lh=GetTreeHight((AVLTree*)&(rootNode->lchild));//L 395 int rh=GetTreeHight((AVLTree*)&(rootNode->rchild));//R 396 return ((lh>rh)?(lh-rh):(rh-lh)); 397 } 398 399 int GetSymDiffHeight(TreeNode* rootNode) 400 { 401 int lh=GetTreeHight((AVLTree*)&(rootNode->lchild));//L 402 int rh=GetTreeHight((AVLTree*)&(rootNode->rchild));//L 403 return (lh-rh); 404 } 405 406 int AdjustNode(TreeNode* posNode, AVLTree* avlTree) 407 {//这个函数写的有点问题,如果传入的posNode dh = 2时候,而起父节点平衡了,就会少调整一部分,所以入posNode尽量用son 408 AVLTree(二叉平衡树)底层实现Python采用平衡二叉树实现一个字典类Dict | 附源码+视频