平衡二叉树(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(二叉平衡树)底层实现

AVLTree(二叉平衡树)底层实现

AVLTree(二叉平衡树)底层实现

Python采用平衡二叉树实现一个字典类Dict | 附源码+视频

STL源码笔记(18)—平衡二叉树AVL(C++封装+模板)

二叉平衡树的实现(c语言编程)