平衡二叉树(AVL)

目录

一、平衡二叉树

1.1  平衡二叉树简介

1.2  平衡二叉树示例

二、二叉排序树的左旋转

2.1  什么时候需要左旋转

2.2  左旋转思路

2.3  左旋转图解

2.4  左旋转代码实现

三、二叉排序树的右旋转

3.1  什么时候需要右旋转

3.2  右旋转思路

3.3  右旋转图解

3.4  右旋转代码

四、二叉排序树的双旋转

4.1  双旋转条件及图解

4.2  双旋转代码 


一、平衡二叉树

1.1  平衡二叉树简介

  • 空树它的左右两棵子树的高度差的绝对值不超过1,并且左右两棵子树都是平衡二叉树。
  • 查询效率较高。

1.2  平衡二叉树示例

二、二叉排序树的左旋转

2.1  什么时候需要左旋转

  • 当二叉排序树的右子树的高度(Rh)比左子树的高度(Lh)多1时,即Rh-Lh > 1。  

2.2  左旋转思路

  • 创建新的结点,赋值为当前结点(当前结点是指待处理子树的根结点)
  • 将新结点的左子树设置为当前结点的左子树 
  • 将新的结点的右子树设置为当前结点的右子树的左子树
  • 把当前结点的值替换为右子结点的值
  • 把当前结点的右子树设置为右子树的右子树
  • 把当前结点的左子树设置成刚刚创建的新结点

2.3  左旋转图解

2.4  左旋转代码实现

/**
	 * 该方法实现左旋转
	 */
	public void leftRotate() {
		//创建新的结点,赋值为当前结点
		Node newNode = new Node(value);
		//将新结点的左子树设置成当前结点的左子树
		newNode.left = left;
		//将新的结点的右子树设置成当前结点的右子树的左子树
		newNode.right = right.left;
		//把当前结点的值替换为右子结点的值
		value = right.value;
		//把当前结点的右子树设置成右子树的右子树
		right = right.right;
		//把当前结点的左子树设置成新结点
		left = newNode;
	}

三、二叉排序树的右旋转

3.1  什么时候需要右旋转

  • 当二叉排序树的左子树的高度(Lh)比右子树的高度(Rh)多1时,即Lh-Rh > 1。

3.2  右旋转思路

  • 创建新的结点,赋值为当前结点(当前结点是指待处理子树的根结点)
  • 将新结点的左子树设置为当前结点的左子树的右子树
  • 将新的结点的右子树设置为当前结点的右子树
  • 把当前结点的值替换为左子结点的值
  • 把当前结点的左子树设置为左子树的左子树
  • 把当前结点的右子树设置成刚刚创建的新结点

3.3  右旋转图解

3.4  右旋转代码

/**
	 * 该方法实现右旋转
	 */
	public void rightRotate() {
		Node newNode = new Node(value);
		newNode.right = right;
		newNode.left = left.right;
		value = left.value;
		left = left.left;
		right = newNode;
	}

四、二叉排序树的双旋转

4.1  双旋转条件及图解

  • 当符合右旋转条件时,若当前结点的左子树的右子树高度大于当前结点的左子树的左子树高度时,先对当前结点的左结点进行左旋转,再对当前结点右旋转。

 

  • 当符合左旋转条件时,若当前结点的右子树的左子树高度大于当前结点的右子树的右子树高度时,先对当前结点的右结点进行右旋转,再对当前结点左旋转。这种情况下的图解与上面的类似,不再给出。

4.2  双旋转代码 

// 每添加一次结点,判断左子树和右子树的高度
		if (rightHeight() - leftHeight() > 1) {
			// 若当前结点的右子树的左子树的高度大于当前结点的右子树的右子树的高度
			if (right != null && right.leftHeight() > right.rightHeight()) {
				// 对右子树右旋转
				right.rightRotate();
			}
			leftRotate();
			return;// 这句很重要
		}
		if (leftHeight() - rightHeight() > 1) {
			// 若当前结点左子树的右子树的高度大于当前结点左子树的左子树高度
			if (left != null && left.rightHeight() > left.leftHeight()) {
				// 将当前结点的左结点左旋转
				left.leftRotate();
			}
			// 再对当前结点进行右旋转
			rightRotate();
		}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值