6.平衡二叉查找树

 我来答
舒适还明净的海鸥i
2022-05-29 · TA获得超过1.7万个赞
知道小有建树答主
回答量:380
采纳率:0%
帮助的人:68.7万
展开全部

AVL树的定义:一种特殊的二叉搜索树,它能自动维持平衡
AVL是发明者的名字缩写:G.M. AdelsonVelskii and E.M. Landis

利用AVL树实现ADT Map,基本上与BST的实现相同,不同之处仅在于二叉树的生成与维护过程
AVL树的实现中,需要对每个节点跟踪“平衡因子balance factor”参数,平衡因子是根据节点的左右子树的高度来定义的,确切地说,是左右子树高度差:
balanceFactor = height(leftSubTree) − height(rightSubTree)
如果平衡因子大于0,称为“左倾left-heavy”,小于零称为“右倾right-heavy”平衡因子等于0,则称作平衡。
如果一个二叉查找树中每个节点的平衡因子都在-1,0,1之间,则把这个二叉搜索树称为平衡树

我们先看看限定平衡因子带来的结果。我们认为,保证树的平衡因子为–1、0 或 1,可以使关键操作获得更好的大O性能

观察上图h=1~4时,总节点数N的变化
h= 1, N= 1
h= 2, N= 2= 1+ 1
h= 3, N= 4= 1+ 1+ 2
h= 4, N= 7= 1+ 2+ 4

观察这个通式,很接近斐波那契数列
定义斐波那契数列
利用 重写

最多搜索次数h和规模N的关系,可以说AVL树的搜索时间复杂度为O(log n)

❖既然AVL平衡树确实能够改进BST树的性能,避免退化情形
❖我们来看看向AVL树插入一个新key,如何才能保持AVL树的平衡性质
❖首先,作为BST,新key必定以叶节点形式插入到AVL树中

叶节点的平衡因子是0,其本身无需重新平衡
但会影响其父节点的平衡因子:

这种影响可能随着其父节点到根节点的路径一直传递上去,直到传递到根节点为止;
或者某个父节点平衡因子被调整到0,不再影响上层节点的平衡因子为止。
• (无论从-1或者1调整到0,都不会改变子树高度)

重新定义_put方法,调整因子

UpdateBalance方法

rebalance重新平衡
主要手段:将不平衡的子树进行旋转rotation视“左倾”或者“右倾”进行不同方向的旋转
同时更新相关父节点引用,更新旋转后被影响节点的平衡因子

如图,是一个“右倾”子树A的左旋转(并保持BST性质)将右子节点B提升为子树的根,将旧根节点A作为新根节点B的左子节点,如果新根节点B原来有左子节点,则将此节点设
置为A的右子节点(A的右子节点一定有空)
更复杂一些的情况:如图的“左倾”子树右旋转,旋转后,新根节点将旧根节点作为右子节点,但是新根节点原来已有右子节点,需要将原有的右子节点重新定位!原有的右子节点D改到旧根节点E的左子节点,同样,E的左子节点在旋转后一定有空

如何调整平衡因子
看看左旋转对平衡因子的影响,保持了次序ABCDE,ACE的平衡因子不变,hA/hC/hE不变,主要看BD新旧关系

拓展 尝试计算树的高度
TreeNode类中添加高度方法

经过复杂的put方法,AVL树始终维持平衡,get方法也始终保持O(log n)高性能
将AVL树的put方法分为两个部分:
需要插入的新节点是叶节点,更新其所有父节点和祖先节点的代价最多为O(log n)
如果插入的新节点引发了不平衡,重新平衡最多需要2次旋转,但旋转的代价与问题规模无关,是常数O(1)所以整个put方法的时间复杂度还是O(log n)

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式