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

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

解释:

  平衡二叉树(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 }

  

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

时间: 2024-10-10 23:59:18

数据结构【查找】—平衡二叉树AVL的相关文章

数据结构快速回顾——平衡二叉树 AVL (转)

平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树.平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态.这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(

算法学习记录-查找——平衡二叉树(AVL)

排序二叉树对于我们寻找无序序列中的元素的效率有了大大的提高.查找的最差情况是树的高度.这里就有问题了,将无序数列转化为 二叉排序树的时候,树的结构是非常依赖无序序列的顺序,这样会出现极端的情况. [如图1]: 这样的一颗二叉排序树就是一颗比较极端的情况.我们在查找时候,效率依赖树的高度,所以不希望这样极端情况出现,而是希望元素比较均匀 的分布在根节点两端. 技术参考:fun4257.com/ 问题提出: 能不能有一种方法,使得我们的二叉排序树不依赖无序序列的顺序,也能使得我们得到的二叉排序树是比

图解平衡二叉树,AVL树(一)

图解平衡二叉树,AVL树(一) 学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建立的树如图2,才能够最大地体现二叉树的优点. 在上述的例子中,图2就是一棵平衡二叉树.科学家们提出平衡二叉树,就是为了让树的查找性能得到最大的体现(至少我是这样理解的,欢迎批评改正).下面进入今天的正题,平衡二叉树. AVL的定义 平衡二叉查找树:简称平衡二叉树.由前

平衡二叉树 AVL 的插入节点后旋转方法分析

平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1. 首先我们知道,当插入一个节点,从此插入点到树根节点路径上的所有节点的平衡都可能被打破,如何解决这个问题呢? 这里不讲大多数书上提的什么平衡因子,什么最小不平衡子树,实际上让人(me)更加费解.实际上你首要做的就是先找到第一个出现不平衡的节点,也就是高度最高的那个节点A,对以它为根的子树做一次旋转或者两次旋转,此时这个节点的平衡问题解决了,整个往

数据结构与算法分析-AVL树深入探讨

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-family: monospace; color: red } .done { font-family: monospace; color: green } .priority { font-fami

java数据结构与算法之平衡二叉树(AVL树)的设计与实现

[版权申明]未经博主同意,不允许转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53892797 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设

数据结构 平衡二叉树avl c++

平衡二叉树:一颗空树,或者是具有以下性质的二叉树 左子树和右子树都是平衡二叉树 左子树和右子树的深度只差不超过1 把二叉树节点的平衡因子BF(Balance Factor)定义为该节点的左子树深度减去右子树深度,则平衡二叉树所有结点的平衡因子只能是-1,0,1.只要有一个结点的平衡因子绝对值大于一就是不平衡的: 平衡二叉树的构造 对二叉树结点做一下定义,bf用来记录结点的平衡因子 1 typedef struct BSTNode{ 2 int val; 3 int bf; 4 struct BS

数据结构复习之平衡二叉树AVL删除

平衡二叉树的插入过程:http://www.cnblogs.com/hujunzheng/p/4665451.html 对于二叉平衡树的删除采用的是二叉排序树删除的思路: 假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论: ⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可. ⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可. ⑶ 若结点*p的左.右子树均非空,先找到*p的中序前趋结点*s(注意*s是*

数据结构之平衡二叉树(AVL)

一:平衡二叉树特点:平衡二叉树(Balanced binary tree)是由阿德尔森-维尔斯和兰迪斯(Adelson-Velskii and Landis)于1962年首先提出的,所以又称为AVL树.定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1;  (2)左右子树仍然为平衡二叉树.    平衡因子: BF=左子树深度-右子树深度.平衡二叉树每个结点的平衡因子只能是1,0,-1.若其绝对值超过1,则该二叉排序树就是不平衡的. 二.平衡二叉树算法思想