![458eb42e14beabed080dc15f24e24bb8.png](https://img-blog.csdnimg.cn/img_convert/458eb42e14beabed080dc15f24e24bb8.png)
平衡二叉树是一种二叉排序树,其中每个结点的左子树和右子树的高度差至多等于1。是两位俄罗斯数学家(G.M,Adelons-V.MLandis)共同发明的一种解决平衡二叉树的算法,也称之为AVL树。
高度平衡:要么是一颗空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1;将二叉树上结点的左子树深度减去右子树深度值称之为平衡因子BF(Balance Factor)。
最小不平衡树:距离插入点最近的,且平衡因子的绝对值大于1的结点为根结点的子树。
平衡二叉树构建基本思想:在构建平衡二叉树的过程中,每当插入一个结点时,先检查是否因插入而破坏的平衡性,若是,则找到最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之称为新的平衡子树。
平衡二叉树构建的模拟:
将数组a[10] = {3,2,1,4,5,6,7,10,9,8}构建二叉排序树。
1.插入结点3,2,1
![efe43813e5cd71bdd33bbd9e9174c76d.png](https://img-blog.csdnimg.cn/img_convert/efe43813e5cd71bdd33bbd9e9174c76d.png)
因平衡因子超过了1,需要进行调整
![7aa6f488c1af5831e9f1794f08c2fe09.png](https://img-blog.csdnimg.cn/img_convert/7aa6f488c1af5831e9f1794f08c2fe09.png)
2.插入结点4
![110491170d8223f5b81af1bef7325829.png](https://img-blog.csdnimg.cn/img_convert/110491170d8223f5b81af1bef7325829.png)
3.插入结点5
![5c5be0c340f17e4ae168a248f464a1c9.png](https://img-blog.csdnimg.cn/img_convert/5c5be0c340f17e4ae168a248f464a1c9.png)
调整后
![ccb29d0b3b135b1e9ea8537339f65aeb.png](https://img-blog.csdnimg.cn/img_convert/ccb29d0b3b135b1e9ea8537339f65aeb.png)
4.插入6
![a8f663ca4992b507839f843a57c17e6a.png](https://img-blog.csdnimg.cn/img_convert/a8f663ca4992b507839f843a57c17e6a.png)
调整后
![c23cb05adf39fe81dd4d0b01f1f5b6f9.png](https://img-blog.csdnimg.cn/img_convert/c23cb05adf39fe81dd4d0b01f1f5b6f9.png)
5.插入结点7
![7fbea633c4558da2d90ad97220291209.png](https://img-blog.csdnimg.cn/img_convert/7fbea633c4558da2d90ad97220291209.png)
调整后
![78c7de5503818ffb1627e4a2d9c2dc15.png](https://img-blog.csdnimg.cn/img_convert/78c7de5503818ffb1627e4a2d9c2dc15.png)
6.插入结点10
![32169057e3ec7ecc397dfad03d4bcf89.png](https://img-blog.csdnimg.cn/img_convert/32169057e3ec7ecc397dfad03d4bcf89.png)
7.插入结点9
![d3d386a3f237c9d2c39a7a77fb319921.png](https://img-blog.csdnimg.cn/img_convert/d3d386a3f237c9d2c39a7a77fb319921.png)
调整后
![387818137b73885832dd176ad5c1dd54.png](https://img-blog.csdnimg.cn/img_convert/387818137b73885832dd176ad5c1dd54.png)
但是9比10小不能称为10的右子树
![66f051794ed21cc38f902f00ba2abcc1.png](https://img-blog.csdnimg.cn/img_convert/66f051794ed21cc38f902f00ba2abcc1.png)
8.插入结点8
![481ab8c18f90b85551adc02febd2d618.png](https://img-blog.csdnimg.cn/img_convert/481ab8c18f90b85551adc02febd2d618.png)
调整后
![6d087b1974fb09d631641629f4750064.png](https://img-blog.csdnimg.cn/img_convert/6d087b1974fb09d631641629f4750064.png)
代码实现
创建平衡二叉树
1.定义结点
//二叉树的二叉链表结点结构定义
2.右旋
对以p为根的二叉排序树作右旋处理;处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点;
void
3.左旋
对以P为根的二叉排序树作左旋处理,处理之后P指向新的树根结点,即旋转处理之前的右子树的根结点
void
4.平衡⼆叉树结点左平衡旋转
三个常量:
LH
对指针T所指结点为根的二叉树作左平衡旋转处理,算法结束后,指针T指向平衡处理后新的根结点
#define LH +1
5.右平衡树失衡处理
对以指针T所指结点为根的二叉树作右平衡旋转处理,本算法结束时,指针T指向新的根结点
void
平衡二叉树插入实现
若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树失去平衡,则作平衡旋转处理,布尔变量taller反映T长高与否。
思路:
- 如果T为空时,则创建一个新结点;
- 如果T不为空,判断是否存在相同的结点.如果二叉树中存在相同结点,则不需要插入;
- 如果新结点值e小于T的根结点值,则在T的左子树查找;
- -如果能在左子树中查找到,则不插入进去.返回False; 如果没有找到,则插入
- -插入成功taller为TRUE,说明新结点e已经插入进去; 此时需要判断T的平衡因子;
- -如果平衡因子是1,则说明左子树高于右子树,那么需要调用leftBalance进行左平衡旋转处理;
- -如果为0或者-1,则说明新插入的结点没有让整颗二叉排序树失去平衡性,只需要修改BF值即可;
- 如果新结点值e大于T的根结点值,则在T的右子树查找;
- -如果能在右子树中查找到,则不插入进去.返回False; 如果没有找到,则插入
- -插入成功taller为TRUE,说明新结点e已经插入进去; 此时需要判断T的平衡因子;
- -如果平衡因子是-1,则说明右子树高于左子树,那么需要调用RightBalance进行右平衡旋转处理;
- -如果为0或者1,则说明新插入的结点没有让整颗二叉排序树失去平衡性,只需要修改BF值即可;
Status
二叉排序树查找
/*二叉排序树查找*/
使用和打印
int
![cf2e337cd7c46fa8c2fcdfdaf5bad6bd.png](https://img-blog.csdnimg.cn/img_convert/cf2e337cd7c46fa8c2fcdfdaf5bad6bd.png)