平衡二叉树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,一经查实,立即删除!

相关文章

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(_:)修改器给一个视图添加动画效果非常容易。 下载起步项目并跟着本篇教程一步步实践…

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

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

Rust基础学习-Rust宏

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

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

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

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;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…

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

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

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

文章部分素材来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 前言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遥不可及的未来科技&#xff0c;而是逐渐融入我们日常生活的实用工具。从智能语音助手到自动驾驶汽车&#xff0c…

炫技来了!使用SDR设备成功抓到蓝牙air packet, 并且wireshark实时解析, 没错就是蓝牙空口抓包器

本文章主要介绍是用ZYNQ7020AD9361Gnu radio是搭建一个蓝牙抓包器的文章。 由于之前一直做蓝牙Host&#xff0c;对controller觉得是一个比较虚无缥缈的东西&#xff0c;得不到的总是在骚动&#xff0c;所以最近用我用吃灰了2年的SDR(Software Defined Radio&#xff09;设备研…

C语言scanf( ) 函数、fprintf( ) 函数与 scanf( ) 函数和printf( ) 函数有什么不同?

一、问题 fscanf( ) 函数、fprintf( ) 函数与 printf( ) 函数、scanf( ) 函数的作⽤相似&#xff0c;都是格式化读写函 数&#xff0c;那么这两个读写函数有什么不同呢&#xff1f; 二、解答 两者的区别就在于前⾯的字符“f”&#xff0c;即 fscanfQ函数和 fprintfD函数的读写…

【Java基础】OkHttp 超时设置详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

AddressSanitizer理论及实践:heap-use-after-free、free on not malloc()-ed address

AddressSanity&#xff1a;A Fast Address Sanity Checker 摘要 对于C和C 等编程语言&#xff0c;包括缓冲区溢出和堆内存的释放后重用等内存访问错误仍然是一个严重的问题。存在许多内存错误检测器&#xff0c;但大多数检测器要么运行缓慢&#xff0c;要么检测到的错误类型有…

Java基础——数组Array

系列文章目录 文章目录 系列文章目录前言一、数组基本概念二、一维数组三、数组的模型四、数组对象的创建五、元素为引用数据类型的数组 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网…

leetcode 所有可能的路径(图的遍历)

leetcode 链接&#xff1a; 所有可能的路径 1 图的基本概念 1.1 有向图和无向图 左边是有向图&#xff0c;右边是无向图。对于无向图来说&#xff0c;图中的边没有方向&#xff0c;两个节点之间只可能存在一条边&#xff0c;比如 0 和 1 之间的边&#xff0c;因为是无向图&am…