算法(6) —— AVL树

AVL树二叉查找树的一种,所以其操作和二叉查找树的很多操作是相同的。

1. 

 1 #ifndef AVLTREE_H
 2 #define AVLTREE_H
 3 
 4 struct AvlNode;
 5 typedef struct AvlNode *Position;
 6 typedef struct AvlNode *AvlTree;
 7 
 8 typedef int ElementType;
 9 
10 
11 AvlTree MakeEmpty( AvlTree T );
12 Position Find( ElementType X, AvlTree T );
13 Position FindMin( AvlTree T );
14 Position FindMax( AvlTree T );
15 AvlTree Insert( ElementType X, AvlTree T );
16 AvlTree Delete( ElementType X, AvlTree T );
17 ElementType Retrieve( Position P );
18 
19 #endif 
avltree.h

2.

  1 #include "avltree.h"
  2 #include <stdlib.h>
  3 #include "fatal.h"
  4 
  5 struct AvlNode  {
  6     ElementType Element;
  7     AvlTree  Left;
  8     AvlTree  Right;
  9     int      Height;
 10 };
 11 
 12 AvlTree  MakeEmpty( AvlTree T )   {
 13     if( T != NULL )
 14     {
 15         MakeEmpty( T->Left );
 16         MakeEmpty( T->Right );
 17         free( T );
 18     }
 19     return NULL;
 20 }
 21 
 22 Position  Find( ElementType X, AvlTree T )  {
 23     if( T == NULL )
 24         return NULL;
 25     if( X < T->Element )
 26         return Find( X, T->Left );
 27     else if( X > T->Element )
 28         return Find( X, T->Right );
 29     else
 30         return T;
 31 }
 32 
 33 Position  FindMin( AvlTree T )  {
 34     if( T == NULL )
 35         return NULL;
 36     else if( T->Left == NULL )
 37         return T;
 38     else return FindMin( T->Left );
 39 }
 40 
 41 Position  FindMax( AvlTree T )  {
 42     if( T != NULL )
 43         while( T->Right != NULL )
 44             T = T->Right;
 45 
 46     return T;
 47 }
 48 
 49 /* START: fig4_36.txt */
 50 static int  Height( Position P )  {
 51     if( P == NULL )
 52         return -1;
 53     else
 54         return P->Height;
 55 }
 56 /* END */
 57 
 58 static int  Max( int Lhs, int Rhs )  {
 59     return Lhs > Rhs ? Lhs : Rhs;
 60 }
 61 
 62 /* START: fig4_39.txt */
 63 /* This function can be called only if K2 has a left child K1 */
 64 /* Perform a rotate between a node (K2) and its left child */
 65 /* Update heights, then return new root k1*/
 66 
 67 static Position
 68 SingleRotateWithLeft( Position K2 )  {
 69     Position K1;
 70 
 71     K1 = K2->Left;
 72     K2->Left = K1->Right;
 73     K1->Right = K2;
 74 
 75     K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
 76     K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;
 77 
 78     return K1;  /* New root */
 79 }
 80 /* END */
 81 
 82 /* This function can be called only if K1 has a right child */
 83 /* Perform a rotate between a node (K1) and its right child */
 84 /* Update heights, then return new root */
 85 
 86 static Position  SingleRotateWithRight( Position K1 )  {
 87     Position K2;
 88 
 89     K2 = K1->Right;
 90     K1->Right = K2->Left;
 91     K2->Left = K1;
 92 
 93     K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;
 94     K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;
 95 
 96     return K2;  /* New root */
 97 }
 98 
 99 /* START: fig4_41.txt */
100 /* This function can be called only if K3 has a left */
101 /* child and K3's left child has a right child */
102 /* Do the left-right double rotation */
103 /* Update heights, then return new root */
104 
105 static Position  DoubleRotateWithLeft( Position K3 )   {
106     /* Rotate between K1 and K2 */
107     K3->Left = SingleRotateWithRight( K3->Left );
108 
109     /* Rotate between K3 and K2 */
110     return SingleRotateWithLeft( K3 );
111 }
112 /* END */
113 
114 /* This function can be called only if K1 has a right */
115 /* child and K1's right child has a left child */
116 /* Do the right-left double rotation */
117 /* Update heights, then return new root */
118 
119 static Position  DoubleRotateWithRight( Position K1 )    {
120     /* Rotate between K3 and K2 */
121     K1->Right = SingleRotateWithLeft( K1->Right );
122 
123     /* Rotate between K1 and K2 */
124     return SingleRotateWithRight( K1 );
125 }
126 
127 
128 AvlTree  Insert( ElementType X, AvlTree T )  {
129     if( T == NULL )  {
130         T = malloc( sizeof( struct AvlNode ) );
131         if( T == NULL )
132             FatalError( "Out of space!!!" );
133         else     {
134             T->Element = X; T->Height = 0;
135             T->Left = T->Right = NULL;
136         }
137     }
138     else  if(X < T->Element )  {
139         T->Left = Insert( X, T->Left );
140         if( Height( T->Left ) - Height( T->Right ) == 2 )
141             if( X < T->Left->Element )
142                 T = SingleRotateWithLeft( T );
143             else
144                 T = DoubleRotateWithLeft( T );
145     }
146     else  if( X > T->Element )    {
147         T->Right = Insert( X, T->Right );
148         if( Height( T->Right ) - Height( T->Left ) == 2 )
149             if( X > T->Right->Element )
150                 T = SingleRotateWithRight( T );
151             else
152                 T = DoubleRotateWithRight( T );
153     }
154     T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
155     return T;
156 }
157 
158 AvlTree    Delete( ElementType X, AvlTree T )  {
159     printf( "Sorry; Delete is unimplemented; %d remains\n", X );
160     return T;
161 }
162 
163 ElementType Retrieve( Position P )  {
164     return P->Element;
165 }
avltree.c

3.

 1 #include "avltree.c"
 2 #include <stdio.h>
 3 
 4 void PrintTree( AvlTree T)  {
 5     if (T != NULL) {
 6         PrintTree (T -> Left);
 7     printf    ("%d\n",Retrieve (T));
 8         PrintTree (T -> Right);
 9     }
10 }
11 
12 
13 int main(int argc, char *argv[])  {
14     AvlTree T;
15     Position P;
16     int i;
17     int j = 0;
18 
19     T = MakeEmpty( NULL );
20     for( i = 0; i < 50; i += 5 )
21         T = Insert( i, T );
22     /*for( i = 0; i < 50; i++ )*/
23         /*if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )*/
24            /*printf( "Error at %d\n", i );*/
25 
26  /* for( i = 0; i < 50; i += 2 )
27         T = Delete( i, T );
28 
29     for( i = 1; i < 50; i += 2 )
30         if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
31             printf( "Error at %d\n", i );
32     for( i = 0; i < 50; i += 2 )
33         if( ( P = Find( i, T ) ) != NULL )
34             printf( "Error at %d\n", i );
35 */
36         PrintTree (T);
37 
38     printf( "Min is %d, Max is %d\n", Retrieve( FindMin( T ) ),
39                Retrieve( FindMax( T ) ) );
40 
41     return 0;
42 }
testavl.c

 

转载于:https://www.cnblogs.com/hanxinle/p/7486134.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是二叉? 二叉是一种形结构,其中每个节点最多有两个子节点。一个节点的左子节点比该节点小,右子节点比该节点大。二叉通常用于搜索和排序。 2. 二叉的遍历方法有哪些? 二叉的遍历方法包括前序遍历、中序遍历和后序遍历。前序遍历是从根节点开始遍历,先访问根节点,再访问左子,最后访问右子。中序遍历是从根节点开始遍历,先访问左子,再访问根节点,最后访问右子。后序遍历是从根节点开始遍历,先访问左子,再访问右子,最后访问根节点。 3. 二叉的查找方法有哪些? 二叉的查找方法包括递归查找和非递归查找。递归查找是从根节点开始查找,如果当前节点的值等于要查找的值,则返回当前节点。如果要查找的值比当前节点小,则继续在左子中查找;如果要查找的值比当前节点大,则继续在右子中查找。非递归查找可以使用栈或队列实现,从根节点开始,每次将当前节点的左右子节点入栈/队列,直到找到要查找的值或者栈/队列为空。 4. 二叉的插入与删除操作如何实现? 二叉的插入操作是将要插入的节点与当前节点的值进行比较,如果小于当前节点的值,则继续在左子中插入;如果大于当前节点的值,则继续在右子中插入。当找到一个空节点时,就将要插入的节点作为该空节点的子节点。删除操作需要分为三种情况:删除叶子节点、删除只有一个子节点的节点和删除有两个子节点的节点。删除叶子节点很简单,只需要将其父节点的对应子节点置为空即可。删除只有一个子节点的节点,需要将其子节点替换为该节点的位置。删除有两个子节点的节点,则可以找到该节点的后继节点(即右子中最小的节点),将其替换为该节点,然后删除后继节点。 5. 什么是平衡二叉? 平衡二叉是一种特殊的二叉,它保证左右子的高度差不超过1。这种平衡可以确保二叉的查找、插入和删除操作的时间复杂度都是O(logn)。常见的平衡二叉包括红黑AVL

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值