zoukankan      html  css  js  c++  java
  • 平衡树实现

    •定义1(AVL树):An empty binary tree is height balanced.  If T is a nonempty binary tree with TL and TR as its left and right subtrees, then T is height balanced iff
    •    (1)  TL and TR are height balanced, and
    •    (2)  | hL - hR | £ 1 where  hL and hR are the heights of TL and TR , respectively.
    •定义2(平衡因子):The balance factor BF( node ) = hL - hR .  In an AVL tree, BF( node ) = -1, 0, or 1.
     
    AVL树的最少节点数
     
     
     
     
     
    •我们把必须重新平衡的节点叫做α,节点α的两棵子树的高度差为2。容易看出,这种不平衡可以出现在以下四种情况中:
    •1、对α的左儿子的左子树进行一次插入。
    •2、对α的左儿子的右子树进行一次插入。
    •3、对α的右儿子的左子树进行一次插入。
    •4、对α的右儿子的右子树进行一次插入。
    •情况1和4是关于α对称的,情况2和3也是关于α对称的。
     
     
     
     1 static Position
     2         SingleRotateWithLeft( Position K2 )
     3         {
     4             Position K1;
     5 
     6             K1 = K2->Left;
     7             K2->Left = K1->Right;
     8             K1->Right = K2;
     9 
    10             K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
    11             K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;
    12 
    13             return K1;  /* New root */
    14         }
    SingleRotateWithLeft单旋转例程


    1 static Position
    2         DoubleRotateWithLeft( Position K3 )
    3         {
    4             /* Rotate between K1 and K2 */
    5             K3->Left = SingleRotateWithRight( K3->Left );
    6 
    7             /* Rotate between K3 and K2 */
    8             return SingleRotateWithLeft( K3 );
    9         }
     DoubleRotateWithLeft双旋转例程
    
    
     
     
    avltree.h
     1         /*平衡树的声明*/
     2         typedef int ElementType;
     3 
     4 /* START: fig4_35.txt */
     5         #ifndef _AvlTree_H
     6         #define _AvlTree_H
     7 
     8         struct AvlNode;
     9         typedef struct AvlNode *Position;
    10         typedef struct AvlNode *AvlTree;
    11 
    12         AvlTree MakeEmpty( AvlTree T );
    13         Position Find( ElementType X, AvlTree T );
    14         Position FindMin( AvlTree T );
    15         Position FindMax( AvlTree T );
    16         AvlTree Insert( ElementType X, AvlTree T );
    17         AvlTree Delete( ElementType X, AvlTree T );
    18         ElementType Retrieve( Position P );
    19 
    20         //以下是补充
    21         void PrintTree(AvlTree T);
    22         AvlTree Remove(const ElementType X, AvlTree T);
    23         AvlTree Remove( ElementType X, AvlTree T );
    24 
    25         #endif  /* _AvlTree_H */
    26 /* END */
    avltree.c
     
      1         #include "avltree.h"
      2         #include <stdlib.h>
      3         #include "fatal.h"
      4 
      5         struct AvlNode
      6         {
      7             ElementType Element;
      8             AvlTree  Left;
      9             AvlTree  Right;
     10             int      Height;
     11         };
     12 
     13         /*置空平衡树*/
     14         AvlTree
     15         MakeEmpty( AvlTree T )
     16         {
     17             if( T != NULL )
     18             {
     19                 MakeEmpty( T->Left );
     20                 MakeEmpty( T->Right );
     21                 free( T );
     22             }
     23             return NULL;
     24         }
     25 
     26         /*查找元素在平衡树中的位置*/
     27         Position
     28         Find( ElementType X, AvlTree T )
     29         {
     30             if( T == NULL )
     31                 return NULL;
     32             if( X < T->Element )
     33                 return Find( X, T->Left );
     34             else
     35             if( X > T->Element )
     36                 return Find( X, T->Right );
     37             else
     38                 return T;
     39         }
     40 
     41         /*找平衡树的最小元素,递归实现*/
     42         Position
     43         FindMin( AvlTree T )
     44         {
     45             if( T == NULL )
     46                 return NULL;
     47             else
     48             if( T->Left == NULL )
     49                 return T;
     50             else
     51                 return FindMin( T->Left );
     52         }
     53 
     54         /*找平衡树的最大元素,非递归实现*/
     55         Position
     56         FindMax( AvlTree T )
     57         {
     58             if( T != NULL )
     59                 while( T->Right != NULL )
     60                     T = T->Right;
     61 
     62             return T;
     63         }
     64 
     65 /* START: fig4_36.txt */
     66 
     67         /*返回节点的高度*/
     68         static int
     69         Height( Position P )
     70         {
     71             if( P == NULL )
     72                 return -1;
     73             else
     74                 return P->Height;
     75         }
     76 /* END */
     77 
     78         /*返回两个数的最大值*/
     79         static int
     80         Max( int Lhs, int Rhs )
     81         {
     82             return Lhs > Rhs ? Lhs : Rhs;
     83         }
     84 
     85 /* START: fig4_39.txt */
     86         /* This function can be called only if K2 has a left child */
     87         /* Perform a rotate between a node (K2) and its left child */
     88         /* Update heights, then return new root */
     89 
     90         /* 
     91         左左(LL)情况的右旋 
     92 
     93             K2
     94            /                k1
     95           K1      =>       /  
     96          /                k    k2
     97         k
     98 
     99         */
    100         static Position
    101         SingleRotateWithLeft( Position K2 )
    102         {
    103             Position K1;
    104 
    105             K1 = K2->Left;
    106             K2->Left = K1->Right;
    107             K1->Right = K2;
    108 
    109             K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
    110             K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;
    111 
    112             return K1;  /* New root */
    113         }
    114 /* END */
    115 
    116         /* This function can be called only if K1 has a right child */
    117         /* Perform a rotate between a node (K1) and its right child */
    118         /* Update heights, then return new root */
    119 
    120         /* 
    121         右右(RR)情况的左旋 
    122 
    123          k1
    124            
    125             k2      =>       k2
    126                            /  
    127                k           k1   k
    128 
    129 
    130         */
    131         static Position
    132         SingleRotateWithRight( Position K1 )
    133         {
    134             Position K2;
    135 
    136             K2 = K1->Right;
    137             K1->Right = K2->Left;
    138             K2->Left = K1;
    139 
    140             K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;
    141             K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;
    142 
    143             return K2;  /* New root */
    144         }
    145 
    146 /* START: fig4_41.txt */
    147         /* This function can be called only if K3 has a left */
    148         /* child and K3's left child has a right child */
    149         /* Do the left-right double rotation */
    150         /* Update heights, then return new root */
    151 
    152         /*
    153         
    154          左右(LR)情况的左右旋转
    155          
    156              k3             k3
    157             /              /
    158            k1    =>       k2    =>      k2
    159                          /            /  
    160               k2         k1           k1   k3
    161 
    162          */
    163         
    164         static Position
    165         DoubleRotateWithLeft( Position K3 )
    166         {
    167             /* Rotate between K1 and K2 */
    168             K3->Left = SingleRotateWithRight( K3->Left );
    169 
    170             /* Rotate between K3 and K2 */
    171             return SingleRotateWithLeft( K3 );
    172         }
    173 /* END */
    174 
    175         /* This function can be called only if K1 has a right */
    176         /* child and K1's right child has a left child */
    177         /* Do the right-left double rotation */
    178         /* Update heights, then return new root */
    179 
    180         /*
    181         
    182          右左(RL)情况的右左旋转
    183 
    184            k1         k1
    185                       
    186               k3   =>  k2     =>       k2
    187              /                       /  
    188            k2             k3         k1   k3
    189 
    190          */
    191         
    192         static Position
    193         DoubleRotateWithRight( Position K1 )
    194         {
    195             /* Rotate between K3 and K2 */
    196             K1->Right = SingleRotateWithLeft( K1->Right );
    197 
    198             /* Rotate between K1 and K2 */
    199             return SingleRotateWithRight( K1 );
    200         }
    201 
    202 
    203 /* START: fig4_37.txt */
    204         /*平衡树的插入*/
    205         AvlTree
    206         Insert( ElementType X, AvlTree T )
    207         {
    208             if( T == NULL )
    209             {
    210                 /* Create and return a one-node tree */
    211                 T = malloc( sizeof( struct AvlNode ) );
    212                 if( T == NULL )
    213                     FatalError( "Out of space!!!" );
    214                 else
    215                 {
    216                     T->Element = X; T->Height = 0;
    217                     T->Left = T->Right = NULL;
    218                 }
    219             }
    220             else
    221             if( X < T->Element )
    222             {
    223                 T->Left = Insert( X, T->Left );
    224                 if( Height( T->Left ) - Height( T->Right ) == 2 )
    225                     if( X < T->Left->Element )
    226                         T = SingleRotateWithLeft( T );
    227                     else
    228                         T = DoubleRotateWithLeft( T );
    229             }
    230             else
    231             if( X > T->Element )
    232             {
    233                 T->Right = Insert( X, T->Right );
    234                 if( Height( T->Right ) - Height( T->Left ) == 2 )
    235                     if( X > T->Right->Element )
    236                         T = SingleRotateWithRight( T );
    237                     else
    238                         T = DoubleRotateWithRight( T );
    239             }
    240             /* Else X is in the tree already; we'll do nothing */
    241 
    242             T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
    243             return T;
    244         }
    245 /* END */
    246 
    247         AvlTree
    248         Delete( ElementType X, AvlTree T )
    249         {
    250             printf( "Sorry; Delete is unimplemented; %d remains
    ", X );
    251             return T;
    252         }
    253   
    254         /*返回某节点的值*/
    255         ElementType
    256         Retrieve( Position P )
    257         {
    258             return P->Element;
    259         }
    260 
    261 
    262         //以下是补充
    263         //
    264         void PrintTree(AvlTree T)
    265         {
    266             if (T != NULL)
    267             {
    268                 PrintTree(T->Left);
    269                 printf("%3d", Retrieve(T));
    270                 PrintTree(T->Right);
    271             }
    272         }
    273 
    274         AvlTree Remove(ElementType X, AvlTree T)
    275         {
    276               if(T == NULL)
    277                   return NULL;//没有找到要删除的值,do nothing
    278               if(X < T->Element)
    279               {
    280                   T->Left = Remove(X, T->Left);
    281                   if(Height(T->Right)-Height(T->Left)==2)
    282                   {
    283                       //右子树比左子树高2,那么在删除操作之前右子树比左子树高1,
    284                      //也就是说T的右子树必然不为空,甚至必然有非空子树(高度至少为1).
    285                      AvlTree s = T->Right;
    286                      if(Height(s->Left)>Height(s->Right))
    287                          T = DoubleRotateWithRight(T);//右双旋转
    288                      else
    289                          T = SingleRotateWithRight(T);//右单旋转
    290                  }
    291                  else
    292                      //不需要调整就满足平衡条件的话,只需要重新计算其高度就好
    293                      T->Height=Max(Height(T->Left),Height(T->Right))+1;
    294              }
    295              else if(X>T->Element)
    296              {
    297 
    298                  T->Right = Remove(X,T->Right);
    299                  if(Height(T->Left)-Height(T->Right)==2)
    300                  {
    301                      AvlTree s=T->Left;
    302                      if(Height(s->Right)>Height(s->Left))
    303                          T = DoubleRotateWithLeft(T);//左双旋转
    304                      else
    305                          T = SingleRotateWithLeft(T);//左单旋转
    306                  }
    307                  else
    308                      T->Height=Max(Height(T->Left),Height(T->Right))+1;
    309              }
    310              else
    311              {
    312                  if(T->Left&&T->Right)         //T的左右子树都非空,把Remove操作转移到只有一个非空子树的结点或者叶子结点上去
    313                  {
    314                      if( Height(T->Left) > Height(T->Right) )
    315                      //把Remove操作往更高的那颗子树上转移
    316                      {
    317                          //左子树中的最大值
    318                          T->Element=FindMax(T->Left)->Element;
    319                          T->Left = Remove(T->Element,T->Left);
    320                      }
    321                      else
    322                      {
    323                          //右子树中的最小值
    324                          T->Element=FindMin(T->Right)->Element;
    325                          T->Right = Remove(T->Element,T->Right);
    326                      }
    327                  }
    328                  else
    329                  {
    330                      AvlTree oldnode = T;
    331                      T=T->Left?T->Left:T->Right;
    332                      free(oldnode);
    333                  }
    334              }
    335             return T;
    336         }

     参考资料:

    平衡二叉树的插入旋转

    平衡二叉树,AVL树之图解篇

    图解数据结构树之AVL树

    数据结构&&AVL树原理、插入操作详解及实现

    AVL树C语言实现

    AVL树及其C语言实现

  • 相关阅读:
    python ping监控
    MongoDB中一些命令
    进制转换(十进制转十六进制 十六进制转十进制)
    通过ssh建立点对点的隧道,实现两个子网通信
    linux环境下的各种后台执行
    python requests请求指定IP的域名
    不需要修改/etc/hosts,curl直接解析ip请求域名
    MongoDB数据update的坑
    windows平台使用Microsoft Visual C++ Compiler for Python 2.7编译python扩展
    rabbitmq问题之HTTP access denied: user 'guest'
  • 原文地址:https://www.cnblogs.com/fazero/p/5027818.html
Copyright © 2011-2022 走看看