数据结构与算法(9)—— 平衡二叉树

平衡二叉树

为何要使用AVL树?
二叉搜索树的搜索效率与其树的深度相关,而二叉搜索树的组成又与其插入序列相关,在极端情况下,二叉搜索树退化为一条单链(比如插入序列是 1 2 3 … n),使得搜索效率大大降低,为了避免这种情况出现,我们采用二叉平衡树对插入结点进行调整,使得树的深度尽可能小

定义
平衡因子
BF(T) = hL - hR,其中 hL 、hR 分别是左右子树的高度

  • 平衡二叉树(AVL 树)
  • 空树,或者任一结点左、右子树高度差的绝对值不超过 1,即 |BF(T)|≤1 的树
    在这里插入图片描述

平衡二叉树的调整

遵循原则
从离插入结点最近的结点调整
RR 单旋
当"插入结点"(BR)是"被破坏平衡结点"(A)右子树的右子树时,即 RR 插入时,采用 RR 旋转调整
在这里插入图片描述
其基本思路是把 B 的左子树腾出来挂到 A 的右子树上,返回 B 作为当前子树的根
示意图:
在这里插入图片描述

AVLTree RRRotation(AVLTree A){
	AVLTree B = A->right;   // B 为 A 的右子树  
	A->right = B->left;    // B 的左子树挂在 A 的右子树上 
	B->left = A;   //  A 挂在 B 的左子树上 
	return B;  // 此时 B 为根结点了   
}

LL 单旋

当"插入结点"(BL)是"被破坏平衡结点"(A)左子树的左子树时,即 LL 插入,采用 RR 旋转调整
在这里插入图片描述
其基本思路是把 B 的右子树腾出来挂到 A 的左子树上,返回 B 作为当前子树的根
示意图:

在这里插入图片描述

AVLTree LLRotation(AVLTree A){
	// 此时根节点是 A 
	AVLTree B = A->left;  // B 为 A 的左子树  
	A->left = B->right;   // B 的右子树挂在 A 的左子树上 
	B->right = A;     //  A 挂在 B 的右子树上 
	return B;  // 此时 B 为根结点了 
}

LR 双旋

当"插入结点"(CL 或者 CR)是"被破坏平衡结点"(A)左子树的右子树时,即 LR 插入,采用 LR 旋转调整
在这里插入图片描述
基本思想是先将 B 作为根结点进行 RR 单旋转化为 LL 插入,再将 A 作为根结点进行 LL 单旋(先 RR 再 LL)
示意图:
在这里插入图片描述

AVLTree LRRotation(AVLTree A){
	// 先 RR 单旋
	A->left = RRRotation(A->left);
	// 再 LL 单旋 
	return LLRotation(A);
}

总结:叫 LR 双旋是从上到下看,而实际先 RR 单旋再 LL 单旋是从下往上的过程

  1. RL 双旋
    当"插入结点"(CL 或者 CR)是"被破坏平衡结点"(A)右子树的左子树时,即 RL 插入,采用 RL 旋转调整
    在这里插入图片描述
    基本思想是先将 B 作为根结点进行 LL 单旋转化为 RR 插入,再将 A 作为根结点进行 RR单旋(先 LL 再 RR)
    示意图:
    在这里插入图片描述
    == 总结:叫 RL 双旋是从上到下看,而实际先 LL 单旋再 RR 单旋是从下往上的过程==
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值