数据结构与算法学习笔记:AVL树


目录

平衡

理想平衡

如何改进二叉搜索树

平衡二叉搜索树(Balance Binary Search Tree)

AVL树

平衡对比

简单的继承结构

添加导致的失衡

LL 右旋转(单旋)

RR 左旋转(单旋)

LR - RR左旋转,LL右旋转(双旋)

RL - LL右旋转,RR左旋转(双旋)

afterAdd

计算平衡因子

更新高度

恢复平衡

旋转方向的判断

左旋转的实现

右旋转的实现

代码整合

测试

示例

统一旋转操作

删除导致失衡

LL 右旋转(单旋)

RR 左旋转(单旋)

LR - RR左旋转,LL右旋转(双旋)

RL - LL右旋转,RR左旋转(双旋)

afterRemove代码实现

总结


平衡

理想平衡

如何改进二叉搜索树

平衡二叉搜索树(Balance Binary Search Tree)

AVL树

平衡对比

简单的继承结构

添加导致的失衡

LL 右旋转(单旋)

  • 添加节点,g失去平衡

  • 拿到左子树的右子树,整体变左子树的右子树

RR 左旋转(单旋)

  • 拿到右子树的左子树,整体变右子树的左子树

LR - RR左旋转,LL右旋转(双旋)

  • 先对p进行左旋转,再对g进行右旋转

RL - LL右旋转,RR左旋转(双旋)

afterAdd

  • 添加元素之后,进行失衡调整
  • BST.java中

  • AVLTree.java中
    • 新增加的节点可能不导致失衡
    • 新增加节点导致失衡,向上找到第一个失衡的祖先

计算平衡因子

  • 在BinaryTree.java中,添加

  • BST.java中

  • 在AVLTree.java中

  • 计算平衡因子

更新高度

  • 新增的节点必然是叶子节点
  • 叶子节点创建出来高度就是1,向上看其父节点,祖先节点

  • 每一个节点更新自己的高度

  • 强转节点类型(封装一层)

  • 更新高度

恢复平衡

  • 在BinaryTree.java中,增加判断是否为左子树或者右子树

  • 在AVLTree.java中,求子树中较长的树

旋转方向的判断

 

 

左旋转的实现

右旋转的实现

代码整合

测试

  • AVLTree.java重写toString

示例

统一旋转操作

private void rebalance(Node<E> grand) {
		Node<E> parent = ((AVLNode<E>)grand).tallerChild();
		Node<E> node = ((AVLNode<E>)parent).tallerChild();
		if (parent.isLeftChild()) { // L
			if (node.isLeftChild()) { // LL
				rotate(grand, node, node.right, parent, parent.right, grand);
			} else { // LR
				rotate(grand, parent, node.left, node, node.right, grand);
			}
		} else { // R
			if (node.isLeftChild()) { // RL
				rotate(grand, grand, node.left, node, node.right, parent);
			} else { // RR
				rotate(grand, grand, parent.left, parent, node.left, node);
			}
		}
	}
	
	private void rotate(
			Node<E> r, // 子树的根节点
			Node<E> b, Node<E> c,
			Node<E> d,
			Node<E> e, Node<E> f) {
		// 让d成为这棵子树的根节点
		d.parent = r.parent;
		if (r.isLeftChild()) {
			r.parent.left = d;
		} else if (r.isRightChild()) {
			r.parent.right = d;
		} else {
			root = d;
		}
		
		//b-c
		b.right = c;
		if (c != null) {
			c.parent = b;
		}
		updateHeight(b);
		
		// e-f
		f.left = e;
		if (e != null) {
			e.parent = f;
		}
		updateHeight(f);
		
		// b-d-f
		d.left = b;
		d.right = f;
		b.parent = d;
		f.parent = d;
		updateHeight(d);
	}
  • 测试:

删除导致失衡

LL 右旋转(单旋)

RR 左旋转(单旋)

LR - RR左旋转,LL右旋转(双旋)

RL - LL右旋转,RR左旋转(双旋)

afterRemove代码实现

  • BST.java中

  • AVLTree.java

总结

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值