ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AVL树

2020-10-14 12:32:09  阅读:241  来源: 互联网

标签:结点 Right getHeight AVLTree AVL 单旋 Left


定义

平衡因子(Balance Factor ,简称BF ): BF(T) = hL -hR ,其中 h和 和 h为 分别为 T 的左、右子树的高度     平衡二叉树又称为AVL树,其定义如下:         空树,或者任一节点左右子树高度差的绝对值不超过1的二叉搜索树,即|BF(T)| ≤ 1。    

AVL树的插入(旋转)

(1) LL旋转:产生问题的结点在发现问题结点的左子树的左子树上。   (2) RR旋转:产生问题的结点在发现问题结点的右子树的右子树上。   (3) LR旋转:产生问题的结点在发现问题结点的左子树的右子树上。   LR旋转相当于先对以B为根结点的子树做了一次右单旋(RR),再对以A为根结点的子树做了一次左单旋(LL),是两次单旋的合成结果。     (4) RL旋转:产生问题的结点在发现问题结点的右子树的左子树上。 同理,RL旋转相当于先对以B为根结点的子树做了一次左单旋(LL),再对以A为根结点的子树做了一次右单旋(RR),是两次单旋的合成结果。  

代码实现

  1 typedef int ElementType;
  2 typedef struct AVLNode *Position;
  3 typedef Position AVLTree;    /* AVL树类型 */
  4 typedef struct AVLNode
  5 {
  6     ElementType Data;    /* 结点数据 */
  7     AVLTree Left;        /* 指向左子树 */
  8     AVLTree Right;        /* 指向右子树 */
  9     int Height;            /* 树的高度 */
 10 };
 11 
 12 /* 直接获取树的高度 */
 13 int getHeight(AVLTree A)
 14 {
 15     if (A != NULL)
 16         return A->Height;
 17     else
 18         return 0;
 19 }
 20 
 21 AVLTree LL(AVLTree A)
 22 {
 23     /* 注意:A必须有一个左子结点B */
 24     /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
 25 
 26     AVLTree B = A->Left;
 27     A->Left = B->Right;
 28     B->Right = A;
 29     A->Height = max(getHeight(A->Left), getHeight(A->Right)) + 1;
 30     B->Height = max(getHeight(B->Left), getHeight(B->Right)) + 1;
 31 
 32     return B;    /* 返回根结点 */
 33 }
 34 
 35 AVLTree RR(AVLTree A)
 36 {
 37     /* 注意:A必须有一个右子结点B */
 38     /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B */
 39 
 40     AVLTree B = A->Right;
 41     A->Right = B->Left;
 42     B->Left = A;
 43     A->Height = max(getHeight(A->Left), getHeight(A->Right)) + 1;
 44     B->Height = max(getHeight(B->Left), getHeight(B->Right)) + 1;
 45 
 46     return B;    /* 返回根结点 */
 47 }
 48 
 49 AVLTree LR(AVLTree A)
 50 {
 51     /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
 52     /* 将A、B与C做如图4.38所示的两次单旋,返回新的根结点C */
 53 
 54     /* 将B与C做右单旋,C被返回 */
 55     A->Left = RR(A->Left);
 56 
 57     /* 将A与C做左单旋,C被返回 */
 58     return LL(A);    
 59 }
 60 
 61 AVLTree RL(AVLTree A)
 62 {
 63     /* 注意:A必须有一个右子结点B,且B必须有一个左子结点C */
 64     
 65     /* 将B与C做左单旋,C被返回 */
 66     A->Right = LL(A->Right);
 67 
 68     /* 将A与C做右单旋,C被返回 */
 69     return RR(A);
 70 }
 71 
 72 
 73 /* 将X插入AVL树T中,并且返回调整后的AVL树 */
 74 AVLTree Insert(AVLTree T, ElementType X)
 75 {
 76     if (T == NULL)
 77     {
 78         /* 若插入空树,则新建包含一个结点的树 */
 79         T = (AVLTree)malloc(sizeof(struct AVLNode));
 80         T->Data = X;
 81         T->Height = 1;
 82         T->Left = T->Right = NULL;
 83     }
 84     else if (X < T->Data)
 85     {
 86         /* 插入T的左子树 */
 87         T->Left = Insert(T->Left, X);
 88         /* 如果需要左旋 */
 89         if (getHeight(T->Left) - getHeight(T->Right) == 2)
 90         {
 91             if (X < T->Left->Data)
 92                 T = LL(T);    /* 左单旋 */
 93             else
 94                 T = LR(T);    /* 左-右双旋 */
 95         }
 96     }
 97     else if (X > T->Data)
 98     {
 99         /* 插入T的右子树 */
100         T->Right = Insert(T->Right, X);
101         /* 如果需要右旋 */
102         if (getHeight(T->Left) - getHeight(T->Right) == -2)
103         {
104             if (X < T->Right->Data)
105                 T = RL(T);    /* 右-左双旋 */
106             else
107                 T = RR(T);    /* 右单旋 */
108         }
109     }
110 
111     /* else X == T->Data,无需插入 */
112 
113     /* 别忘了更新树高 */
114     T->Height = max(getHeight(T->Left), getHeight(T->Right)) + 1;
115 
116     return T;
117 
118 }

 

测试代码:

 1 void LevelTraverse(AVLTree T)
 2 {
 3     if (!T)
 4         return;
 5 
 6     queue<AVLTree> Q;
 7     Q.push(T);
 8     while (!Q.empty())
 9     {
10         AVLTree A = Q.front();
11         Q.pop();
12         printf("%d ", A->Data);
13         if (A->Left)
14             Q.push(A->Left);
15         if (A->Right)
16             Q.push(A->Right);
17     }
18 }
19 
20 int main()
21 {
22     AVLTree T = NULL;
23     T = Insert(T, 20);
24     T = Insert(T, 18);
25     T = Insert(T, 30);
26     T = Insert(T, 15);
27     T = Insert(T, 19);
28     T = Insert(T, 16);    //破坏平衡
29 
30     LevelTraverse(T);
31 
32     system("pause");
33     return 0;
34 }

 

参考

《 数据结构 (第2版) 》 - 陈越、何钦铭 中国大学MOOC中的浙江大学《数据结构》课程,陈越、何钦铭

 

 

标签:结点,Right,getHeight,AVLTree,AVL,单旋,Left
来源: https://www.cnblogs.com/FengZeng666/p/13814105.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有