数据结构(八)平衡二叉树

平衡二叉树

0. 为何要使用AVL树?

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

1. 定义

  • 平衡因子
    BF(T) = h L _L L - h R _R R,其中 h L _L L、h R _R R 分别是左右子树的高度
  • 平衡二叉树(AVL 树)
    空树,或者任一结点左、右子树高度差的绝对值不超过 1,即 |BF(T)|≤1 的树

2. 平衡二叉树的调整

0. 遵循原则
  • 从离插入结点最近的结点调整
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 为根结点了   
}
2. 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 为根结点了 
}
3. 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 单旋是从下往上的过程

4. RL 双旋

当"插入结点"(CL 或者 CR)是"被破坏平衡结点"(A)右子树左子树时,即 RL 插入,采用 RL 旋转调整

基本思想是先将 B 作为根结点进行 LL 单旋转化为 RR 插入,再将 A 作为根结点进行 RR单旋(先 LL 再 RR)

示意图:

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

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

练手题

Root of AVL Tree

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值