平衡搜索二叉树—AVL树

一、定义:

        为了避免搜索二叉树的高度增长过快,降低二叉树的性能,规定在插入和删除二叉树的结点的时候,任何结点左右子树的高度差绝对值不超过1,这样的二叉树被称为平衡二叉树(balanced Binary Tree),简称平衡树。在搜索二叉树BST的基础上增加以上性质,就称为AVL树。

二、AVL树的构造

      1. AVL树的结点是一个三叉链结构:相比BST多了一个指向parent的结点。

template<class K,class V>
struct AVLTreeNode {pair<K,V> _kv;//结点值AVLTreeNode* _parent;//指针,三叉链AVLTreeNode* _left;AVLTreeNode* _right;int _bf;//平衡因子AVLTreeNode(const pair<K,V> kv):_kv(kv), _parent(nullptr), _left(nullptr), _right(nullptr), _bf(0){}
};

  2.AVL树的插入:

  1. 首先,从根结点开始,与待插入结点比较大小,直到直到插入位置——叶子结点的空孩子指针,然后建立新结点,并与父节点链接。
  2. 然后修改插入结点的父节点的平衡因子,左节点插入,平衡因子-1,反之,加1。
  3. 父节点平衡因子修改后,分三种情况处理:

①父节点平衡因子为0,不用处理return。

②父节点平衡因子为±1,向上传递,回到第二步,此时cur=parent,parent=grantparent,根据cur和parent的位置关系,修改平衡因子。

③父节点平衡因子为±2,根据插入结点cur、parent以及grandparent的位置,分4种情况,进行4种旋转结束。

 3.AVL树的四种旋转

右单旋:条件为
条件为:if (parent->_bf == 2 && cur->_bf == 1)

 所有情况下的结构图如下:h>=0

	void rotateR(Node* parent){Node* cur = parent->_left;Node* cur_right = cur->_right;parent->_left = cur_right;		//旋转第一步parent和cur_right的链接;if (cur->_right != nullptr)//Xcur_right->_parent = parent;cur->_right = parent;		//再处理cur和parent的链接Node* parent_parent = parent->_parent;//保存结点,用于处理,cur->parent;parent->_parent = cur;if (parent == _root)		//处理cur和parent_parent的链接{_root = cur;cur->_parent = nullptr;//X}else {cur->_parent = parent_parent;if (parent_parent->_left == parent){parent_parent->_left = cur;}else {parent_parent->_right = cur;}}parent->_bf = 0;//旋转后平衡因子为0cur->_bf = 0;}
左单旋:
条件为:if(parent->_bf==2&&cur->_bf==1)

  所有情况下的结构图如下:h>=0

void rotateL(Node* parent) {Node* cur = parent->_right;Node* cur_left = cur->_left;parent->_right = cur_left;if(cur_left!=nullptr)cur_left->_parent = parent;cur->_left = parent;Node* ppNode = parent->_parent;parent->_parent = cur;if (parent == _root){_root = cur;cur->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = cur;}else{ppNode->_right = cur;}cur->_parent = ppNode;}parent->_bf = 0;cur->_bf = 0;
}
先左后右双旋:
条件是 if(parent->_bf==-2&&cur->_bf==-1)

结构图如下: 注意H==0时,H-1=0

void rotateLR(Node* parent) {Node* cur = parent->_left;Node* cur_right = cur->_right;int bf = cur_right->_bf;//根据此节点的平衡因子决定,上层三个参加旋转的结点的平衡因子rotateL(parent->_left);//对平衡因子==±1的结点,即上层堆栈的cur,作为单左旋的parent,旋转后转为,单右旋的情况,再单右旋。rotateR(parent);if (bf == 1) {parent->_bf = 0;cur->_bf = -1;cur_right = 0;}else if (bf == -1) {parent->_bf = -1;cur->_bf =0;cur_right->_bf = 0;}else if (bf == 0) {parent->_bf = 0;cur->_bf = 0;cur_right->_bf = 0;}else {assert(false);}
}
先右后左双旋:
条件是:if(parent->_bf==2&&parent->_bf==-1)

结构图如下: 注意H==0时,H-1=0

	void rotateRL(Node* parent) {Node* cur = parent->_right;Node* cur_left = cur->_left;int bf = cur_left->_bf;rotateR(parent->_right);rotateL(parent);if (bf == -1) {parent->_bf = 0;cur->_bf = 1;cur_left->_bf = 0;}else if (bf == 1) {parent->_bf = -1;cur->_bf = 0;cur_left->_bf = 0;}else if (bf == 0) {//当cur_left的子节点为空时,bf=0,parent->_bf = 0;cur->_bf = 0;cur_left->_bf = 0;}else {assert(false);}}

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

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

相关文章

Unity2023.1.19_ECS_DOTS

Unity2023.1.19_ECS_DOTS 盲学-盲目的学习&#xff1a; 懒着自己整理就看看别人整理的吧&#xff0c;整合一下逻辑通了不少&#xff1a; DOTS/data oriented technology stack-面向数据的技术栈 ECS/Entities-Component-System Unity-Entities包 Entities提供ECS架构面向数…

2024年3月6日 十二生肖 今日运势

小运播报&#xff1a;2024年3月6日&#xff0c;星期三&#xff0c;农历正月廿六 &#xff08;甲辰年丁卯月己巳日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;牛、猴、鸡 需要注意&#xff1a;鼠、虎、猪 喜神方位&#xff1a;东北方 财神方位&#xff1a;正…

Hack The Box-Bizness

目录 信息收集 nmap dirsearch WEB Get shell 提权 get user flag get root flag 信息收集 nmap 端口扫描┌──(root㉿ru)-[~/kali/hackthebox] └─# nmap -p- 10.10.11.252 --min-rate 10000 -oA port Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-04 1…

It is also possible that a host key has just been changed

问题&#xff1a;ssh失败&#xff0c;提示如上图 分析: ssh的key存在上图里的路径里。 解决&#xff1a;win10删这个文件C:\Users\admin\.ssh\known_hosts , linux删这个文件.ssh\known_hosts ,或者删除这个文件里的制定ip的那一行&#xff0c;例如“106.1.1.22 ecdsa-sha2-…

【快速上手QT】07-对话框QDialog

QDialog 今天讲一个我们这个系列的第一篇就提到的东西&#xff1a;QDialog。 相信经过前几篇的学习&#xff0c;大家应该是能够通过QT助手来对QDialog有个初步的了解。 我们就直接来测试一下。 #include "Zhetu.h"#include <qdebug.h> #include <QPushBu…

IntelliJ IDEA插件php golang python shell docker ignore UML plantuml等插件安装

IntelliJ IDEA插件php golang python shell docker ignore UML plantuml等插件安装 有的插件,需要代理才能搜索和下载 设置代理 不然插件搜索不到&#xff0c;也可能下载不了 Preferences -->Plugins --> Browse repositorise… --〉HTTP Proxy Settings… 选择 Manual…

Linux笔记--静态库和动态库

库是指在我们的应用中&#xff0c;有一些公共代码是需要反复使用&#xff0c;就把这些代码编译为"库"文件;在链接步骤中&#xff0c;链接器将从库文件取得所需的代码&#xff0c;复制到生成的可执行文件中。 Linux中常见的库文件有两种&#xff0c;一种.a为后缀&…

这回就好好聊聊Kotlin的泛型

公众号「稀有猿诉」 原文链接 这回就好好聊聊Kotlin的泛型 泛型(Generics)是静态强类型编程语言中非常强大的特性&#xff0c;可以极大的加强代码的复用&#xff0c;并增强类型安全&#xff0c;减少运行时的类型转换错误。在这篇文章就来详细的学习一下Kotlin中对泛型的…

EasyX的学习2

消息处理——漂亮的按钮(鼠标) 用到的函数 1.消息结构体变量类型&#xff1a;使用ExMessage ExMessage msg{ 0 }; 定义一个变量名为msg的ExMessage结构体变量并初始化为0 2.获取消息函数&#xff1a;peekmessage函数 //获取消息 peekmessage(&msg, EX_MOUSE); 两个参…

Batch Normalization和Layer Normalization和Group normalization

文章目录 前言一、Group normalization二、批量规范化(Batch Normalization)三、层规范化&#xff08;Layer Normalization&#xff09; 前言 批量规范化和层规范化在神经网络中的每个批次或每个层上进行规范化&#xff0c;而GroupNorm将特征分成多个组&#xff0c;并在每个组内…

表格制作一对多,多对多

<!-- <tr><td>第1行第1列</td><td>第1行第2列</td></tr><tr><td rowspan"4">第2行第1列</td><td colspan"2">第2行第2列</td><td colspan"3">第2行第2列</td>…

STM32CubeMX学习笔记8 -ADC

1. ADC简介 ADC 是Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。简单地说就是将模拟电压值&#xff0c;转换成对应的肉眼…