详细剖析平衡二叉树的四种旋转(附C++代码)
2022/2/10 17:12:56
本文主要是介绍详细剖析平衡二叉树的四种旋转(附C++代码),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
经过一天的学习,笔者发现网上少有人剖析平衡二叉树为何要分为四种旋转情况(尤其是LR型和RL型旋转),学习起来感觉云里雾里。查阅相关资料后,笔者整理了以下几种解释,其中夹杂着笔者自己的理解(笔者也是初学,水平不足,如有缺漏错误的地方,望读者指出)。
一.单向右旋(RR)和左旋(LL)
1.
这个很好理解,可以把节点3的位置看作一个定滑轮(支点),滑轮左边的绳子较长,无法平衡,那么就把1-2-3绳子往右拉,则节点2就被拉到了支点处,左右两边绳子长度相等,重量均匀,则保持平衡。看下面一种情况:
有初学者可能会想为何不是转换成下面这种情况:
这是因为,插入节点后,需要找到离被插入节点最近的那个平衡因子>1或<-1的节点。以上图为例,插入节点5后,离5最近的且平衡因子<-1的为节点3,而不是节点2 。所以节点3位置看作定滑轮,把3-4-5这根绳子向左拉(左旋),节点4便到达支点处,绳子平衡。
2.
再来看另一种情况:
还有人可能会问,为什么平衡后,节点3变成了节点2的右子树?怎么不能是其他位置?这是因为节点4是2的右子树,而3是4的左子树,这就一定会产生一个结果:节点3的值位于节点2和节点4之间(在上图中,节点序号和值相同) 所以调整平衡后,节点3一定是节点2的右子树!
从以上情况可以知道,平衡因子为负则左旋,为正则右旋。
二.双向旋转(LR与RL)
那么,我们来看最后一种情况:
上左图加入节点9后,节点7处失衡,我们首先会想到左旋。然而左旋后出现了虚线中的情况,显然这是不符合二叉排序树的定义的!那该怎么处理这种情况呢?首先我们需要明白为什么出现此情况。从前两种情况我们可以发现:进行旋转时,位于支点的节点的平衡因子和与它处于同一条绳子上的下一个节点的平衡因子的符号是相同的。 而上图中,节点7和节点10的平衡因子符号并不相同!所以我们需要先调整符号,方法如下:
即先将10-9这条绳子向右拉(局部右旋),则节点7和节点9的符号统一,可以整体左旋了,如下:
关于为何要进行双向旋转,本人也只能用上文的符号统一来解释了(此解释引用于《大话数据结构》)。其本质原因不必太过深究,类比即可,毕竟这个算法是俄罗斯的两位数学家想出来的,肯定是比较难以理解的。
RL与LR相同,就不具体阐述了。
三.代码解释
个人感觉此算法的代码实现比其抽象出来的过程更难懂,所以附上代码的详细解释。
main函数:
最后附上链接:平衡二叉树(AVL树)及C语言实现 (biancheng.net)
这篇关于详细剖析平衡二叉树的四种旋转(附C++代码)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享