平衡树实现

•定义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\n", 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语言实现

posted @ 2015-12-07 23:06  樱风凛  阅读(272)  评论(0编辑  收藏  举报