平衡二叉树AVL

平衡二叉树是一种特殊的二叉查找树,其中每个节点的左右子树的高度差不超过1。这种树的平衡性质使其在多种操作下保持较高的效率。
在这里插入图片描述

平衡二叉树的定义与性质
严格定义:在平衡二叉树中,任一节点的两个子树的高度最大差别为一,这使得树保持一定程度的平衡,进而保证操作的效率。
查找效率:平衡二叉树的查找、插入和删除操作的时间复杂度均为O(log n),其中n为树中节点的数量。这是因为树保持了相对平衡,避免了最坏情况下的链式存储结构。

代码实现

改造之前的二叉树代码,增加高度属性(二叉树的高度是根节点到叶子节点的最长简单路径边的条数),以便后面进行高度判断:
AVLNode类:

public class AVLNode {int value; // 节点的值int height; // 节点的高度AVLNode left; // 左子节点AVLNode right; // 右子节点public AVLNode(int value) {this.value = value;this.height = 1;}
}

AVL类:

public class AVL {private AVLNode root; // 根节点// 获取节点的高度public int getHeight(AVLNode node) {return node == null ? 0 : node.height;}public AVLNode insert(AVLNode node, int value) {if (node == null) {return new AVLNode(value);}if (value < node.value) {node.left = insert(node.left, value);} else if (value > node.value) {node.right = insert(node.right, value);} else {return node;}//增加当前节点高度node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));return node;}public void insert(int value) {root = insert(root, value);}}

平衡因子

AVL树中的平衡因子定义为某个节点的左子树高度与右子树高度之差的绝对值。具体来说:

如果一个节点的左子树高度大于右子树高度,那么该节点的平衡因子为左子树高度减去右子树高度,结果为正数。
如果一个节点的右子树高度大于左子树高度,那么该节点的平衡因子为右子树高度减去左子树高度,结果为负数。
如果左右子树高度相等,平衡因子为0。
在AVL树中,为了保持树的平衡性,任何节点的平衡因子只能是-1、0或1。这意味着AVL树是严格平衡的二叉搜索树,其中任意节点的两个子树的高度差最多为1。当通过插入或删除操作导致某个节点的平衡因子不满足这一条件时,AVL树会通过一系列的旋转操作来重新平衡树。这些旋转包括单旋(左旋或右旋)和双旋(先左后右或先右后左),以确保树的高度平衡特性得到恢复。

 public int getBalanceFactor(AVLNode node) {return node == null ? 0 : getHeight(node.left) - getHeight(node.right);}

avl的四种失衡

  1. LL型失衡
    定义:当在某个节点的左孩子的左子树上插入或删除一个节点后,如果这个左子树仍然有其他非空节点存在,导致该节点的左子树的高度比右子树高2,则发生LL型失衡。
    调整方法:通过一次右旋操作来修复这种失衡。 将当前节点的左孩子作为新的根节点,新的根节点的右孩子作为原根节点的左孩子,原根节点更新为新根节点的右孩子。
if (balance > 1 && value < node.left.value) {return rightRotate(node);
}
public AVLNode rightRotate(AVLNode y) {AVLNode x = y.left;AVLNode T2 = x.right;x.right = y;y.left = T2;y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;return x;
}
  1. RR型失衡
    定义:当在某个节点的右孩子的右子树上插入或删除一个节点后,如果这个右子树仍然有其他非空节点存在,导致该节点的右子树的高度比左子树高2,则发生RR型失衡。
    调整方法:通过一次左旋操作来修复这种失衡。 将当前节点的右孩子作为新的根节点,新的根节点的左孩子作为原根节点的右孩子,原根节点更新为新根节点的左孩子。
if (balance < -1 && value > node.right.value) {return leftRotate(node);
}
public AVLNode leftRotate(AVLNode x) {AVLNode y = x.right;AVLNode T2 = y.left;y.left = x;x.right = T2;x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;return y;
}

双旋

  1. LR型失衡
    定义:当在某个节点的左孩子的右子树上插入或删除一个节点后,如果这个右子树仍然有其他非空节点存在,导致该节点的左子树的高度比右子树高2,则发生LR型失衡。
    调整方法:需要先进行RR旋转(围绕左孩子的右孩子),然后再进行LL旋转(围绕原节点)。这两次旋转使树重新获得平衡。
 if (balance < -1 && value < node.right.value) {node.right = rightRotate(node.right);return leftRotate(node);}
  1. RL型失衡
    定义:当在某个节点的右孩子的左子树上插入或删除一个节点后,如果这个左子树仍然有其他非空节点存在,导致该节点的右子树的高度比左子树高2,则发生RL型失衡。
    调整方法:**需要先进行LL旋转(围绕右孩子的左孩子),然后再进行RR旋转(围绕原节点)。**这两次旋转使树重新获得平衡。
 if (balance > 1 && value > node.left.value) {node.left = leftRotate(node.left);return rightRotate(node);}

avl 的遍历

AVL树的遍历方式主要有以下几种:

  • 中序遍历(Inorder Traversal):左子树 -> 根节点 -> 右子树。这种遍历方式可以得到排序后的序列。
void inOrder(Node node) {if (node != null) {inOrder(node.left);System.out.print(node.key + " ");inOrder(node.right);}}
  • 前序遍历(Preorder Traversal):根节点 -> 左子树 -> 右子树。这种遍历方式可以用于复制一棵树。
void preOrder(Node node) {if (node != null) {System.out.print(node.key + " ");preOrder(node.left);preOrder(node.right);}}
  • 后序遍历(Postorder Traversal):左子树 -> 右子树 -> 根节点。这种遍历方式可以用于删除一棵树。
void postOrder(Node node) {if (node != null) {postOrder(node.left);postOrder(node.right);System.out.print(node.key + " ");}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/24662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node学习之常用内置模块

这里只列举一些常用的&#xff0c;具体使用方法请查看官网 一、os模块 const os require("node:os"); // 获取计算机cup信息 // console.log(os.cpus());// 获取当前操作系统的换行符 // console.log(os.EOL);// 获取系统架构 // console.log(os.arch());// 以整数…

Linux卸载RocketMQ教程【带图文命令巨详细】

巨详细Linux卸载RocketMQ教程 #查询rocketmq进程 ps -ef | grep rocketmq #杀掉相关进程 kill -9 进程id #查找安装目录 find / -name runbroker.sh #删除rocketMQ目录 rm -rf 安装目录框起来的就是进程id&#xff0c;全部杀掉 这里就是我的安装目录&#xff0c;我的删除命令…

SwiftUI五视图动画和转场

代码下载 使用SwiftUI可以把视图状态的改变转成动画过程&#xff0c;SwiftUI会处理所有复杂的动画细节。在这篇中&#xff0c;会给跟踪用户徒步的图表视图添加动画&#xff0c;使用animation(_:)修改器给一个视图添加动画效果非常容易。 下载起步项目并跟着本篇教程一步步实践…

Linux下tcpwrappers防火墙介绍

tcpwrappers&#xff08;防火墙&#xff09; &#xff0d;&#xff0d;过滤TCP包头(/usr/sbin/tcpd) /etc/hosts.allow 允许 /etc/hosts.deny 拒绝 匹配顺序 tcp包头----<wrappers.so> ------- /etc/hosts.allow ------- /etc/hosts.deny 匹配规则< 规则马上写&…

AI 写高考作文丨10 款大模型 “交卷”,实力水平如何?

前言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遥不可及的未来科技&#xff0c;而是逐渐融入我们日常生活的实用工具。从智能语音助手到自动驾驶汽车&#xff0c;从智能家居系统到精准医疗诊断&#xff0c;AI技术正以其强大的计算能力和数…

算法之链表知识

一、链表的概念 链表是一种常见的数据结构&#xff0c;用于存储数据元素的集合。它由一系列节点组成&#xff0c;每个节点包含数据和指向下一个节点的指针。这种数据结构在动态内存分配中非常有用&#xff0c;因为它不需要连续的内存空间。 二、单向链表和双向链表 单向链表&a…

Rust基础学习-Rust宏

Rust中的宏是生成另一段代码的一段代码。可以根据输入生成代码&#xff0c;简化重复模式&#xff0c;使得代码更加简洁。比如我们一直在用的println!,vec!,panic!都是宏。 创建宏 可以使用macro_rules!创建一个宏&#xff1a; macro_rules! macro_name {(...) > {...} }这…

Java中类初始化的奥秘

一、概述 在 Java 语言中&#xff0c;类的加载、链接&#xff08;验证、准备、解析&#xff09;和初始化过程都是在程序运行期间完成的。 其中加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的。解析阶段可以在初始化之前也可以在初始化之后再开始(又叫作运行时绑定、动…

c#与汇川plc通信 使用官网API库

前言 上位机开发中有时会要求与PLC进行通信&#xff0c;汇川官网也有好用的API库方便大家使用。记录一下开发过程。 1.下载资料 汇川官网地址&#xff1a;汇川技术 - 推进工业文明 共创美好生活 打开后选择&#xff1a;服务与支持-》资料下载-》 资料下载 这里可以直接搜索&am…

六级作文---3.图画类

六级作文—3.图画类 范文 As is illustrated in the graph, the share of urban population increased from 19.39% to 60.6% between 1980 and 2019. From my perspective, the above figures reveal a currently prevailing tendency and represent China’s achievements i…

C++学习插曲:“name“的初始化操作由“case“标签跳过

问题 "name"的初始化操作由"case"标签跳过 问题代码 case 3: // 3、删除联系人string name;cout << "请输入删除联系人姓名&#xff1a;" << endl;cin >> name;if (isExistPerson(&abs, name) -1){cout << "…

【刷题篇】分治-归并排序

文章目录 1、排序数组2、交易逆序对的总数3、计算右侧小于当前元素的个数4、翻转对 1、排序数组 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 class Solution { public:vector<int> tmp;void mergeSort(vector<int>& nums,int left,int right){…

cocos creator3.7版本拖拽事件处理

前言&#xff1a;网上能找到的资料都太落后了&#xff0c;导致哥们用AI去写&#xff0c;全是瞎B写&#xff0c;版本都不对。贴点实际有用的。别老捣鼓你那破convertToNodeSpaceAR或者convertToNodeSpace了。 核心代码 touch.getDeltaX() touch.getDeltaY() 在cocoscreator3…

python-自幂数判断

[题目描述]&#xff1a; 自幂数是指&#xff0c;一个N 位数&#xff0c;满足各位数字N 次方之和是本身。例如&#xff0c;153153 是 33 位数&#xff0c;其每位数的 33 次方之和&#xff0c;135333153135333153&#xff0c;因此 153153 是自幂数&#xff1b;16341634 是 44 位数…

简单快速设置Windows和Ubuntu双系统双引导

一、参考资料 Windows和Ubuntu双系统安装教程 二、设置引导 1. 安装EasyBCD 下载并安装 EasyBCD 2. 设置Windows引导 3. 设置Ubuntu引导 4. 启动系统 遇到这种情况&#xff0c;直接Enter回车。 三、修复引导 如果引导区损坏&#xff0c;导致无法进入系统&#xff0c;可以…

FuTalk设计周刊-Vol.041

&#x1f525;AI漫谈 热点捕手 1、国产GPTs来了&#xff0c;基于智谱第4代大模型 全自研第四代基座大模型GLM-4&#xff0c;且所有更新迭代的能力全量上线。GLM-4性能相比GLM-3提升60%&#xff0c;逼近GPT-4&#xff08;11月6日最新版本效果&#xff09;。而同时推出的GLM-4-…

【漏洞复现】多客圈子论坛系统 httpGet 任意文件读取漏洞

0x01 产品简介 多客圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…

生活中的人工智能

生活中的人工智能应用广泛&#xff0c;涵盖了多个领域&#xff0c;以下是一些主要的应用场景和详细介绍&#xff1a; 智能家居&#xff1a; 智能家居控制&#xff1a;利用AI技术&#xff0c;实现对智能家居设备的智能化控制&#xff0c;如智能灯光、智能窗帘、智能音响、智能门…

六级作文---2.选择与平衡类

六级作文—2.选择与平衡类 范文一&#xff08;选择理科还是文科专业&#xff1f;&#xff09; It is universally acknowledged that, all other factors being equal, a proper choice on major could be the difference between one’s success of failure. But when it com…

算法分析与设计期末考试复习(更新ing)

重点内容&#xff1a; 绪论&#xff1a; 简单的递推方程求解 1.19(1)(2) 、 教材例题 多个函数按照阶的大小排序 1.18 分治法&#xff1a; 分治法解决芯片测试问题 计算a^n的复杂度为logn的算法&#xff08;快速幂&#xff09; 分治法解决平面最近点对问…