平衡二叉查找树(AVL)的构建——左旋右旋

article/2025/9/29 15:26:55

原文链接:https://www.cnblogs.com/ZhaoxiCheung/p/6012783.html

平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树。这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N)。

一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树( 空树的高度定义为 -1 )。查找、插入和删除在平均和最坏情况下都是 O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

1、LL型(单次右旋转)

k2的左子树比右子树高2,所以不平衡,我们需要把k1提到k2的位置,然后k2下降到k1的右子树,最后还有把k1的右子树放到k2的左子树即可。
在这里插入图片描述

//LL型旋转(单次右旋)
static Position SingleRotateWithLeft( Position K2 )
{Position K1;K1 = K2->Left;          //找到 K2 左子树K2->Left = K1->Right;   //将 K1 右子树移到 K2 的左子树K1->Right = K2;         //建立 K1 和 K2 的关系K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;return K1;  /* New root */
}

2、RR型(单次右旋转)

与LL型对称,原理类似
在这里插入图片描述

static Position SingleRotateWithRight( Position K1 )
{Position K2;K2 = K1->Right;K1->Right = K2->Left;K2->Left = K1;K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;return K2;  /* New root */
}

3、LR型双旋转(单次左旋后右旋)

先以K3的左子树为根节点执行一次左左旋转,然后以k3的根节点,执行一次右右旋转即可。
在这里插入图片描述

static Position DoubleRotateWithLeft( Position K3 )
{/* Rotate between K1 and K2 */K3->Left = SingleRotateWithRight( K3->Left );/* Rotate between K3 and K2 */return SingleRotateWithLeft( K3 );
}

4、RL型双旋转(单次右旋后单次左旋)

与LR型双旋转对称,原理类似
在这里插入图片描述

static Position DoubleRotateWithRight( Position K1 )
{/* Rotate between K3 and K2 */K1->Right = SingleRotateWithLeft( K1->Right );/* Rotate between K1 and K2 */return SingleRotateWithRight( K1 );
}

5、结点插入

AVL树进行插入操作时,会破坏二叉树的平衡性,所以每当插入一个数据时,都要从插入点往上,一步一步检测出是否出现平衡因子大于1的,如果有,则要做相应的旋转。

AvlTree Insert( ElementType X, AvlTree T )
{if( T == NULL ){/* Create and return a one-node tree */T = malloc( sizeof( struct AvlNode ) );if( T == NULL )FatalError( "Out of space!!!" );else{T->Element = X;T->Height = 0;T->Left = T->Right = NULL;}}else if( X < T->Element )                              //插入值比当前结点值小,往左子树插入{T->Left = Insert( X, T->Left );                    //递归插入if( Height( T->Left ) - Height( T->Right ) == 2 )  //判断子树是否平衡if( X < T->Left->Element )                     //比当前结点左子树的值小,即为左左情形。T = SingleRotateWithLeft( T );             //LL旋转(右单旋转)else                                           //否则为左右情形T = DoubleRotateWithLeft( T );             //LR旋转}else if( X > T->Element )                              //插入值比当前结点值大,往右子树插入{T->Right = Insert( X, T->Right );                  //递归插入if( Height( T->Right ) - Height( T->Left ) == 2 )  //判断子树是否平衡if( X > T->Right->Element )                    //比当前结点右子树大,即为右右情形T = SingleRotateWithRight( T );            //RR旋转(左单旋转)else                                           //否则为右左情形T = DoubleRotateWithRight( T );            //RL旋转}/* Else X is in the tree already; we'll do nothing */T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;return T;
}

6、结点删除

结点删除包括四种情况:

  • 左右子树都非空
  • 左子树为空,右子树非空
  • 右子树为空,左子树非空
  • 左右子树都为空
AvlTree Delete(ElementType X,AvlTree T)
{if (T == NULL)                        //空树直接返回return NULL;if (x < T->Element)                   //删除值小于当前节点,说明删除节点在当前节点左侧{T->Left = Delete(X,T->Left);if (Height(T->Right) - Height(T->Left) == 2){if (Height(T->Right->Left) > Height(T->Right->Right))T = DoubleRotateRL(T);elseT = SingleRotateRight(T);}}else if (X > T->Element)             //删除节点在当前节点右侧{T->Right = Delete(X,T->Right);if (Height(T->Left) - Height(T->Right) == 2){if (Height(T->Left->Right) > Height(T->Left->Left))T = DoubleRotateLR(T);elseT = SingleRotateLeft(T);}}else                                 //找到删除节点{if (T->Right)                    //右子树不为空的情况{AvlTree tmp = T->Right;while (tmp->Left != NULL) tmp = tmp->Left;  //找到要删除的结点的右子树的左子树最小值,以便替要删除的结点T->Element = tmp->Element;T->height = tmp->height;T->Right = Delete(tmp->Element,T->Right); //递归删除}else{//右子树为空的情况,free节点,返回被删除节点的左节点//这也是真正删除节点的地方AvlTree tmp=T;T = T->Left;free(emp);return T;}}//每次删除之后,都要更新节点的高度T->height = Max(Height(T->Left),Height(T->Right)) + 1;return T;
}

http://chatgpt.dhexx.cn/article/lOSbc9g4.shtml

相关文章

详解红黑树之左旋右旋

为什么要左旋右旋&#xff1f; 为了使得左右子树的高度差在一定范围内&#xff0c;需要通过旋转调整&#xff0c;这样就可以保持平稳的搜索效率 左旋&#xff1a; 步骤 1.设原来E的父节点是father&#xff0c;那么左旋之后需要改变的是&#xff1a; 2.S和father的关系&#…

avl树左旋右旋的理解

一直没搞懂非平衡二叉树变平衡二叉树时左旋右旋&#xff0c;今天下定决心搞懂&#xff0c;然后在众多博客中终于找到了这样一篇&#xff0c;非常形象&#xff0c;记录如下&#xff1a; AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一&…

搞懂平衡二叉树的左旋右旋双旋(Java实现)

刚看到韩顺平老师的数据结构与算法对于平衡二叉树的讲解&#xff08;最后会附上地址&#xff09;&#xff0c;有如下理解&#xff0c;希望能帮助大家&#xff01;哪里需要改正的欢迎指正&#xff01; 平衡二叉树&#xff1a;一种二叉排序树&#xff08;BST Binary Sort Tree&a…

图示讲解AVL平衡二叉树的左旋和右旋

AVLTree 高度平衡的搜索二叉树 一棵平衡树&#xff0c;或是空树&#xff0c;或是具有以下性质的二叉搜索树&#xff1a;左子树和右子树都是AVL树&#xff0c;且左右子树的高度之差的绝对值不超过1。 该二叉树&#xff0c;根结点的右子树高度为3&#xff0c;左子树高度为2。…

左右旋对比

目录 前言 一&#xff0c;逆置法 1.1逆置思路 1.2逆置实现 二&#xff0c;左旋和右旋对比 右旋代码分析 特点对比 前言 之前在up主的博客里面已经有过了对于左旋的三种实现方法。当然&#xff0c;如果我们考虑到时间复杂度的问题&#xff0c;那么我们只要一种方法&#xf…

平衡二叉树的左旋右旋详解 看不懂你打我

平衡二叉树的左旋右旋 看不懂你打我 左旋右旋的操作为什么要左旋右旋左旋右旋能保持排序二叉排序树的性质吗下次写平衡二叉树的LL、RR、LR、RL。 左旋右旋的操作 1.左旋&#xff1a;对X节点左旋&#xff0c;即以X的右孩子Y为轴&#xff0c;将X节点转下来&#xff0c;变为Y的左…

二叉树的旋转,左旋和右旋

在AVLTree中经常会有以某个节点为点对子树进行旋转的操作&#xff0c;今天就和大家分享一下什么是二叉树的旋转。 这是一棵二叉树&#xff0c;上图称为图一。 将图一中的树以1为旋转点进行左旋后得到图二&#xff1a; 将图一中的树以1为旋转点进行右旋旋后得到图三&#xff1…

day062:平衡二叉树——左旋、右旋

二叉树、平衡二叉树的介绍&#xff1a;day061&#xff1a;二叉树、二叉查找树、平衡二叉树_ZQyyds&#xff1a;&#xff09;的博客-CSDN博客 目录 一、平衡二叉树的左旋 1.为什么要左旋、右旋&#xff1f; 2.什么是左旋&#xff1f; 3.图解 二、平衡二叉树的右旋 1.什么是…

大型json文件格式化【超简单】

问题 遇到了一个很大的JSON文件&#xff08;约4M&#xff09;&#xff0c;想格式化查看&#xff0c;在线json工具会直接崩溃&#xff0c;网上其他同学说的python方法之类的我也都实验失败&#xff0c;但是发现了vs code中一个超强的代码格式化 解决1&#xff08;2019.2.10更…

Unity存档系统——Json格式的文件

实例场景 点击Save按钮后&#xff0c;查看保存的文件 点击Load按钮后加载文档数据 Json介绍https://www.json.org/json-zh.htmlUnity中自带的JsonUtility可以将可序列化对象与Json格式相互转换。 将对象转为可序列化对象需要添加[SerializeField]&#xff0c;且为public&#…

将json文件格式转化成Excel表格形式

在程序员的工作中&#xff0c;经常有产品或者运营部门的小姐姐需要数据&#xff0c;由于不懂技术&#xff0c;就需要我们将Json格式的数据转换成Excel文档提供给她们进行数据分析。 本文就介绍一个非常简单方便的方法 1.运用的是Excel表格自带的功能 首先打开Excel文件 点击插…

js导出JSON格式文件

在src目录下新建tools文件价&#xff0c;在tools文件中新建index.js(文件内名字随意) 在index.js文件中 const Tools {// 导出文件exportJson(name, data) {let blob new Blob([data]); // 创建 blob 对象let link document.createElement("a");link.href URL.…

json文件

认识一下 json文件 直接使用记事本打开&#xff1a;例如猫狗二分类 一般都使用类似字典的方式存储&#xff0c;但和字典不同&#xff0c;无论是键还是值&#xff0c;都要加上双引号。 json文件的读取与写入 import jsondata {"a":"1","b":&q…

JSON格式校验工具

经常用ApiPost 和 Postman 测试自己写的接口的话&#xff0c;有时会不小心写错传进去的json对象&#xff0c;我们可以用json格式检验工具去检查一下自己json格式。 在线工具&#xff1a;在线 JSON 工具&#xff0c;JSON 校验/格式化/压缩/工具 - 在线工具-wetools.com微工具

python文件处理——JSON格式文件

python文件处理——JSON格式文件 hello&#xff01;我是wakeyo_J&#xff0c;每天一个konwledge point&#xff0c;一起学python&#xff0c;让技术无限发散。 JSON格式文件 python文件处理——JSON格式文件1. JSON格式1.1 JSON常用的两种结构数据类型1.2 JSON数据与python数据…

json文件格式详解

json文件格式详解 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式&a…

json文件格式转换为png文件格式

话不多少&#xff0c;直接上代码&#xff0c;更换源目录和目标目录即可 1、导入库 import cv2 import numpy as np import os import shutil import matplotlib.pyplot as plt 2、设置源目录/输出目录 json_dir G:/json_filedir/ #json文件所在文件夹(注&#xff1a;文…

Notepad++工具 格式化Json文件格式

简介&#xff1a; Notepad是常用的文件查看工具&#xff0c;在查看json的文件时&#xff0c;如果json文件的格式不符合正常的可视格式&#xff0c;那就需要格式化json文件&#xff0c;使之符合我们的可视化需求。 流程&#xff1a; 首先打开Notepad 打开Plugins 在搜索框中填入…

JSON 文件存储

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是W_chuanqi&#xff0c;一个编程爱好者 &#x1f4d9; 个人主页&#xff1a;W_chaunqi &#x1f600; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4ac; 愿你我共…