Defs
首先给出平衡二叉树问题的研究意义: 由于 平衡二叉树(AVL) 的形态在二叉排序树中查找效率最高, 故需要研究如何在插入新节点后, 保持二叉树的平衡
AVLのdefs:
又因为, 当插入新节点时, 对其祖先节点的balance值都会产生影响, 故我们选择从小问题入手, 只要调整最小不平衡子树即可
熟悉了相关想想后, 我们开始本篇文章最重要的思考部分, 即调整最小不平衡子树的旋转问题
首先给出调整的分类:
LL
我们先使用王道的说法, 对LL(右单旋转)进行说明:
可以看到, 依照王道的思路, 要把B节点向右上方向旋转, 旋转成为A的父亲节点, 将A节点向右下旋转成为B的右子树的根节点, 然后更换B原来的右子树作为A的左子树
引发我思考的点在于: 我始终很难空间想象这种旋转的动态 (不知道有没有类似情况的道友, 也可能是我的空间想象能力较差吧)
对于一个摆, 与其想象它往高处摆动的动态, 我们在想象其在高处向下旋转的过程时会更加舒服
于是我们不妨这样来思考:
对LL情况, 将A节点以B为轴, 顺时针旋转到B的右子树上, B的原右子树作为A的左子树(A本来就有右子树), 不知道有没有同学这样进行空间想象的时候会更加舒服一点
更通俗地讲, 想象A是一个摆, 现在在最高处, 从高处往下摆, "啪嗒"一下撞掉了B的右子树, 此时把A固定在B的右子树的位置, 把B的右子树捡起来, 装上去, 但是A只有左子树才有空位置, 于是你把撞掉的分支装到A的左子树上, 就完成了LL操作
RR
类似地, 对于RR, 就是将A节点以B为轴, 逆时针旋转到B的左子树上, B的原左子树作为A的右子树, B作为新的根节点(A往下摆, "啪嗒"撞掉了B的左子树, 于是捡起来装到A的右子树上)
LR && RL
习惯了上述思维方式后, 对于LR和RL的分析也更为简单了
总结如下:
LR=RR+LL
RL=LL+RR
怎么解释呢?
LR:![在这里插入图片描述](https://img-blog.csdnimg.cn/2cc0f0ffb09c4e7c8c3c543e6b805f9e.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/481ed031d07c4850ad6bf3be1b372a3b.png)
首先, LR是对A的左子树B的右子树插入了新的节点, 为方便理解, 我们对B的右子树进行展开, 令C为B的右子树的根节点
- 首先对B-C树进行分析(上图左), 发现其当前形态就是RR操作的形态, 于是进行RR操作: 将B节点以C为轴, 逆时针旋转到C的左子树上, C的原左子树作为B的右子树, C作为新的根节点, 替代掉B的位置(B摆下来, "啪嗒"撞掉了C的左子树, 布拉布拉布拉…), 然后就变成了上图中间的树的状态;
- 此时只看A-C树(上图中), 发现此形态即为LL操作的形态, 于是将A节点以C为轴, 顺时针旋转到C的右子树上, C的原右子树作为A的左子树(A本来就有右子树)(A摆下来, "啪嗒"撞掉了C的右子树, 布拉布拉布拉…)
从而不难看出, LR=RR+LL的思想成立
另外补充一下, 因为LR是对于B的右子树进行插入, 而插入到C的左右是不影响的, 都是两次旋转: 对于B的RR+对于A的LL, 即下图所示
类似地对RL也能进行同样的分析(RL=LL+RR), 这里给出图示, 留给读者来思考
提示:(1. B摆下来, "吧嗒"撞掉C的右子树, 捡起来装在B的左子树上; 2. A摆下来, "吧嗒"撞掉C的左子树, 捡起来装在C的右子树上)
当然, 这只是我在考研复习这里时, 对于自己难以想象的问题打上的一个小补丁, 如果帮助到了你, 就给我点个赞吧 😃, 如果你认为这种思路不如王道的旋转好理解, 那说明你的空间想象能力是要大大强过我了(羡慕).