这是我参与更文挑战的第4天,活动详情查看: 更文挑战
hello 艾瑞巴得,坚持四篇啦!!!这篇文章的代价是一把头发,这把头发小编先掉为敬!
前言:
在数据结构中树、图是数据结构标志性产物,我们今天讲的二叉树是一种比较有用的折中方案。数组的搜索比较方便,可以直接用下标,但删除或者插入某些元素就比较麻烦。链表与之相反,删除和插入元素很快,但查找很慢。二叉树就既有链表的好处,也有数组的好处。在处理大批量的动态的数据是比较有用。在某种场景下,使用树结构会更加方便因为树结构是非线性,可以表示一对多,比如文件的目录结构等;
我们都知道对于二叉查找树和二叉树的各种遍历,但是其查找效率不稳定会出现“斜树”的情况,这个时候二叉平衡树就应运而生了,二叉平衡树的用途更多,查找相比之下也更稳定;这个大家可以想象一下Mysql的搜索引擎:MyISAM和InnoDB;
平衡二叉树
平衡二叉树条件:
二叉树的每一个节点的左右子树的深度差不超过1。
平衡二叉树如何实现自平衡:
然而当出现“斜树”的情况的时候,平衡二叉树会通过通过旋转,来保持树的平衡,旋转分为以下四种类型:
以下图片:由 A、B、C、E、F表示树的节点,节点旁边的数字表示当前节点左右子树的深度,图画的比较潦草,给大家详细的介绍一下,大家可以跟着我的思路走一遍,相信大家就能理解了
- LL型(右旋):在左子树的左孩子上添加新的节点
从左向右
- 图1当前树结构是平衡的,他的每一个节点的左右子树深度,最大为1,满足平衡树条件
- 图2向
左树的左孩节点添加一个新的节点F这个时候可以看到,我们的跟节点的左右子树的深度为2,这个时候不满足平衡树条件了,这么办呢?我们的重点出来了,接着向下看👇 - 图3是我们经过右旋的之后的实现平衡的二叉树,我们可以看到原来的子节点
B向右旋转成为跟节点,A节点也向右旋转成为B节点的子节点,原来B节点的右子节点也向右旋转成为A节点的左子节点,这个时候完成旋转,可以看到这次每个节点左右子树的深度最大为C节点为1,满足条件,实现自平衡;
给大家网上找了一个生动的 右旋 动图,可以看着理解一下
2、RR型(左旋):在右子树的右孩子上添加新的节点
从左向右
- 图1当前树结构是平衡的,他的每一个节点的左右子树深度,最大为1,满足平衡树条件
- 图2向
右树的右孩节点添加一个新的节点F这个时候可以看到,我们的跟节点的左右子树的深度为2,这个时候便不满足平衡树条件了; - 图3是我们经过左旋的之后的实现平衡的二叉树,卖个关子,大家可以自己思考一下,通过是这么通过左旋实现的,想到了可以写到评论区哦!哈哈哈~嗝~ 让大家体验一下社会的险恶😁
3、LR型(先左旋(失衡子树)再右旋):在左子树的右孩子上添加新节点
从左向右
- 图1当前树结构是平衡的,他的每一个节点的左右子树深度,最大为1,满足平衡树条件
- 图2向左树的右孩节点添加一个新的节点
F这个时候可以看到,我们的跟节点的左右子树的深度为2,这个时候便不满足平衡树条件了; - 图3是我们图里画圈的那个
局部的树结构经过左旋的之后的形成一个LL形的树结构; - 图4是我们进过初步左旋得到的LL形树结构 在通过一次 右旋(同上面第一个例子),从而实现自平衡;
4、RL型(先右旋(失衡子树)再左旋):在右子树的左孩子上添加新节点
从左向右
- 图1当前树结构是平衡的,他的每一个节点的左右子树深度,最大为1,满足平衡树条件
- 图2向右树的左孩节点添加一个新的节点
F这个时候可以看到,我们的跟节点的左右子树的深度为2,这个时候便不满足平衡树条件了; - 图3是我们图里画圈的那个
局部的树结构经过右旋的之后的形成一个LL形的树结构; - 图4是我们进过初步右旋得到的LL形树结构 在通过一次 左旋(同上面第二个例子),从而实现自平衡;
当然,除了插入,AVL还有删除等其他操作,(原理相似。删除后平衡)有兴趣可以一起研究
AVL树:
AVL树是带有平衡条件的二叉查找树,左右子树树高不超过1,AVL树是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。因此它也被称为高度平衡树。
ok!文章到此就结束了,AVL的理解需要时间,当然笔者的AVL自己写的可能有些疏漏,希望可以对大家有帮助,让大家少走一些弯路,有不对的地方希望大家可以提出来的,共同成长;
细节之中只有天地,整洁成就卓越代码