数据结构笔记_37 平衡二叉树(左、右旋转,双旋转)

本文介绍了平衡二叉树(AVL树)的概念,强调了其在二叉排序树基础上的优化作用。详细讲解了如何通过左旋转、右旋转以及双旋转来维护平衡二叉树的平衡性,并提供了相应的代码实现,包括求AVL树高度、左旋转、右旋转以及处理需要双旋转的情况。通过实例演示了这些操作如何确保树的平衡,使AVL树保持高效查找性能。
摘要由CSDN通过智能技术生成

一、简介:

需要注意的是,平衡二叉树是建立在二叉排序树的基础之上的。

是一种对二叉排序树的优化,以免出现下面类似的问题:
在这里插入图片描述
在这里插入图片描述
平衡二叉树(AVL),其中 AV和L是发明者的名字首字母。

在这里插入图片描述

二、分布代码:

很多代码可以复用前面的二叉排序树中的,下面列出新增的代码:

1、求AVL高度(Node类中)

在这里插入图片描述
测试一下:
在这里插入图片描述
输出:
在这里插入图片描述

可见,树的高度为4,而其右子树的高度为3,左子树的高度为1.

3 - 1 = 2 大于 1了,这就不是平衡二叉树了。

为了使其变成平衡二叉树,我们需要对其进行左旋转

左旋转的目的降低右子树的高度

左旋转图解:

在这里插入图片描述

👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

在这里插入图片描述

2、左旋转代码(Node类中):

在这里插入图片描述
在添加结点的方法中,增加一个判断语句:
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述

3、右旋转

与左旋转类似:
在这里插入图片描述
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
在这里插入图片描述
在这里插入图片描述
在Node类中,写一个右旋转方法:
在这里插入图片描述

在Node的add方法内,再加上这句:
在这里插入图片描述

测试一下:
在这里插入图片描述
可以发现根节点已经由10变成8了,右旋转成功。

4、双旋转★

前面两个数列,进行单旋转(一次旋转)就可以将非平衡二叉树转成平衡二叉树,但在某些情况下,单旋转不能完成平衡二叉树的转换。比如:

int [] arr = {
    10 , 11 , 7 , 6 , 8 , 9 };

运行之前代码,并没有转成 AVL 树:
在这里插入图片描述

原因图解:
在这里插入图片描述
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
先进行左旋转,再进行右旋转,成功转成 AVL 树。
在这里插入图片描述

在原先的add方法里面,增加一些代码即可:
在这里插入图片描述
测试:
在这里插入图片描述
输出:
在这里插入图片描述

三、完整代码

package com.huey.avl;

public class AVLTreeDemo {
   

	public static void main(String[] args) {
   
//		int[] arr = { 4, 3, 6, 5, 7, 8 };
//		int[] arr = { 10, 12, 8, 9, 7, 6 };
		int[] arr = {
    10, 11, 7, 6, 8, 9 };
		// 创建一个AVLTree对象
		AVLTree avlTree = new AVLTree();
		// 添加结点
		for (int i = 0; i < arr.length; i++) {
   
			avlTree.add(new Node(arr[i]));
		}

		// 遍历
		System.out.println("中序遍历~");
		avlTree.infixOrder();

//		System.out.println("在没有做平衡处理前~");
//		System.out.println("树的高度:" + avlTree.getRoot().height());// 4
//		System.out.println("树的左子树的高度:" + avlTree.getRoot().leftHeight());// 1
//		System.out.println("树的右子树的高度:" + avlTree.getRoot().rightHeight());// 3

		System.out.println("在做平衡处理后~");
		System.out.println("树的高度:" + avlTree.getRoot().height());// 3
		System.out.println("树的左子树的高度:" 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值