码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构【查找】—平衡二叉树AVL

时间:2019-03-24 18:51:03      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:inf   原理   插入   span   失败   构建   数据   alt   若是   

/*自己看了半天也没看懂代码,下次再补充说明*/

解释:

  平衡二叉树(Self-Balancing Binary Search Tree 或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。

 

实现原理:

  平衡二叉树构建的基本思想就是在构建二又排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二又排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

 

右旋:

  技术图片

左旋:

  技术图片

左旋、右旋:

  技术图片

代码实现:

  

  1 #include "000库函数.h"
  2 
  3 #define MAXSIZE 100//
  4 #define EH 0
  5 #define LH +1  //左高
  6 #define RH -1  //右高  
  7 
  8 //二叉树的结构
  9 struct BiTree
 10 {
 11     int data;
 12     int bf;//AVL的平衡因子
 13     BiTree *lchild, *rchild;
 14 };
 15 
 16 bool L_Rotate(BiTree* &T) {//对T的左子树作左旋平衡处理
 17     BiTree *R;
 18     R = T->rchild;
 19     T->rchild = R->lchild;//R的左子树挂接为T的右子树
 20     R->lchild = T;
 21     T = R;
 22     return true;
 23 }
 24 
 25 bool R_Rotate(BiTree* &T) {//对T做右旋处理
 26     BiTree *L;
 27     L = T->lchild;
 28     T->lchild = L->rchild;
 29     L->rchild = T;
 30     T = L;
 31     return true;
 32 }
 33 
 34 
 35 
 36 
 37 //判断再加入左子树会不会打破平衡
 38 bool LeftBalace(BiTree* &T) {//如今再添加进左边就应该添加后判断是否打破了平衡
 39     BiTree *L, *Lr;
 40     L = T->lchild;
 41     switch (L->bf)//判断左子树的平衡因子
 42     {
 43     case LH://原为左增,现再增加就打破平衡了,故需要做右旋处理
 44         T->bf = L->bf = EH;
 45         R_Rotate(T);
 46         break;
 47     case RH://原节点为右增,再增加左节点(深度+1),就打破平衡了,故作双旋处理
 48         Lr = L->rchild;
 49         switch (Lr->bf)
 50         {
 51         case LH:
 52             T->bf = RH;
 53             L->bf = EH;
 54             break;
 55         case EH:
 56             T->bf = L->bf = EH;
 57             break;
 58         case RH:
 59             T->bf = EH;
 60             L->bf = LH;
 61             break;
 62         default:
 63             break;
 64         }
 65         Lr->bf = EH;
 66         L_Rotate(T->lchild);//对T的左子树作左旋平衡处理
 67         R_Rotate(T);//对T做右旋处理
 68         break;
 69     default:
 70         break;
 71     }
 72     return true;
 73 }
 74 
 75 //判断再加入右子树会不会打破平衡
 76 bool RightBalace(BiTree* &T) {//如今再添加进右边就应该添加后判断是否打破了平衡
 77     BiTree *R, *Rl;
 78     R = T->rchild;
 79     switch (R->bf)//判断右子树的平衡因子
 80     {
 81     case LH://原节点为左增,再增加右节点(深度+1),就打破平衡了,故作双旋处理        
 82         Rl = R->lchild;
 83         switch (Rl->bf)
 84         {
 85         case LH:
 86             T->bf = EH;
 87             R->bf = RH;
 88             break;
 89         case EH:
 90             T->bf = R->bf = EH;
 91             break;
 92         case RH:
 93             T->bf = LH;
 94             R->bf = EH;
 95             break;
 96         default:
 97             break;
 98         }
 99         Rl->bf = EH;
100         R_Rotate(T->rchild);//对T的左子树作左旋平衡处理
101         L_Rotate(T);//对T做右旋处理
102         break;
103     case RH://原为右增,现再增加就打破平衡了,故需要做左旋处理        
104         T->bf = R->bf = EH;
105         L_Rotate(T);
106         break;         
107     default:
108         break;
109     }
110     return true;
111 }
112 
113 //AVL创建
114 /*  若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个 */
115 /*  数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树 */
116 /*  失去平衡,则作平衡旋转处理,布尔变量taller反映T长高与否。 */
117 bool InsertAVL(BiTree * &T, int elem, bool &n) {
118     if (T == NULL) {
119         BiTree *p;
120         p = new BiTree;
121         p->data = elem;
122         p->bf = EH;
123         p->lchild = NULL;
124         p->rchild = NULL;
125         T = p;
126         n = true;
127         return true;
128     }
129     if (T->data == elem) {//数据已存在,不需要再添加
130         n = false;
131         return false;
132     }
133     if (elem < T->data) {
134         if (!(InsertAVL(T->lchild, elem, n)))//应当继续在左子树中继续查找
135             return false;//添加失败
136         if (n) {//添加成功
137             switch (T->bf)//检查AVL的平衡因子
138             {
139             case LH://原树左边高
140                 LeftBalace(T);//如今再添加进左边就应该添加后判断是否打破了平衡
141                 n = false;
142                 break;
143             case EH://原树左等高度,那就加入其左边,让其增高
144                 T->bf = LH;
145                 n = true;
146                 break;
147             case RH://原树右端高,那就加入左端,抵消有右边的高度
148                 T->bf = EH;
149                 n = false;
150                 break;
151             default:
152                 break;
153             }
154         }            
155     }
156     else {
157         if (!(InsertAVL(T->rchild, elem, n)))//应当继续在右子树中继续查找
158             return false;//添加失败
159         if (n) {//添加成功
160             switch (T->bf)//检查AVL的平衡因子
161             {
162             case LH://原树左边高
163                 T->bf = EH;//加入右端,抵消有左边的高度
164                 n = false;
165                 break;
166             case EH://原树左等高度,那就加入其右边,让其增高
167                 T->bf = LH;
168                 n = true;
169                 break;
170             case RH://原树右端高
171                 RightBalace(T);//如今再添加进右边就应该添加后判断是否打破了平衡
172                 n = false;
173                 break;
174             default:
175                 break;
176             }
177         }
178     }
179 
180 
181 }
182 //遍历AVL
183 void ShowTree(BiTree *T) {
184     //进行中序浏览
185     if (T) {
186         ShowTree(T->lchild);
187         cout << T->data << "—>";
188         ShowTree(T->rchild);
189     }
190 }
191 
192 int T033(void)
193 {
194     int i;
195     int a[10] = { 3,2,1,4,5,6,7,10,9,8 };
196     BiTree *T = new BiTree;
197     T = NULL;
198     bool taller;//用来判断AVL是否增加了深度
199     BiTree *p;
200     for (i = 0; i < 10; i++)    {
201         InsertAVL(T, a[i], taller);
202         if (i == 0)p = T;//记住头结点
203     }
204     ShowTree(T);
205     cout << endl;
206     return 0;
207 }

 

 

 

 

  

数据结构【查找】—平衡二叉树AVL

标签:inf   原理   插入   span   失败   构建   数据   alt   若是   

原文地址:https://www.cnblogs.com/zzw1024/p/10589445.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!