平衡二叉树

AVL简称平衡二叉树,缩写为BBST,由苏联数学家 Adelse-Velskil 和 Landis 在 1962 年提出。

二叉树是动态查找的典范,但在极限情况下,二叉树的查找效果等同于链表,而平衡二叉树可以完美的达到 log ⁡ 2 n \log_2 n log2n

一直想深入的研究一下,并手写平衡二叉树的插入、删除代码。

可惜的是,国内数据结构的神级教材:阎蔚敏老师主编《数据结构》一书中并未看到关于AVL树的代码。

例子:

将17,9,2,12,14,26,33,15,40,23,25一次插入到一棵初始化为空的AVL树中,画出该二叉平衡树。

解:过程和结果如下图所示。

在这里插入图片描述

所谓平衡二叉树,就是指二叉树的左、右子树的深度差不超过2。每当插入一个新的元素,导致左右子树的深度超过2层时,需要对二叉树的失衡节点进行平衡,保持左右子树高度差在-1到1之间。

可以使用两个整数来表示左右子树的深度,前面一个表示左子树的层数,右边一个代表右子树的层数。

调整时,首先需要找到要平衡的节点。找到调整节点后,处理的方法有4种:

上图中圆标号1的是左-左结构,标号2的是左-右结构,标号3的是右-右,标号4的是右-左结构,这4种结构的处理方式各有不同。

  1. 左-左结构,即(2,1)结构

中间节点当作父节点,最上面的节点当作右节点,最下边节点当作左节点

  1. 左-右结构,即(2,-1)结构

最下面节点当作父节点,父节点当作右节点,中间节点当作左节点

  1. 右-右结构,即(-2,-1)结构

中间节点当作父节点,最上面的节点当作左节点,最下边节点当作右节点

  1. 右-左结构,即(-2,1)结构

最下面节点当作父节点,最上面节点当作左节点,中间节点当作右节点

编程中,计算左、右子树深度的代码如下:


int deep(BBST* b) {if (b == 0){return 0;}int ld =  deep(b->lchild);int rd = deep(b->rchild) ;return ld > rd ? ld + 1 : rd + 1;
}

有了上面的理论和编程基础,我们可以慢慢的调试并手动写出平衡二叉树的插入代码:

int BBSTree::insert(ELEMENT* e) {if (mTree == 0){mTree = newnode(e);mSize = 1;return 1;}BBST* t = mTree;BBST* tc = 0;Stack s;ELEMENT elem;while (1) {if (e->e == t->data.e) {return 0;}else if (e->e > t->data.e){if (t->rchild == 0){tc = newnode(e);tc->parent = t;t->rchild = tc;mSize++;break;}else {			elem.e = (unsigned long long)t;s.push((ELEMENT*)&elem);t = t->rchild;				}}else {if (t->lchild == 0){tc = newnode(e);tc->parent = t;t->lchild = tc;mSize++;break;}else {elem.e = (unsigned long long)t;s.push((ELEMENT*)&elem);t = t->lchild;		}}}while (s.isEmpty() == 0) {s.pop(&elem);BBST* b = (BBST*)elem.e;b->ld = deep(b->lchild);b->rd = deep(b->rchild);t->ld = deep(t->lchild);t->rd = deep(t->rchild);int high_diff = b->ld - b->rd;int low_diff = t->ld - t->rd;if(high_diff == 2 && low_diff == 1){BBST* f = (BBST*)b->parent;if (f&&f->lchild == b){f->lchild = t;}else if (f&&f->rchild == b){f->rchild = t;}t->parent = f;BBST* tr = t->rchild;t->rchild = b;b->parent = t;b->lchild = tr;if (tr){tr->parent = b;}if (b == mTree){mTree = t;}}else if (high_diff == 2 && low_diff == -1){BBST* f = (BBST*)b->parent;if (f->lchild == b){f->lchild = tc;}else if (f->rchild == b){f->rchild = tc;}tc->parent = f;t->parent = tc;if (tc->lchild){tc->lchild->parent = t;}t->rchild = tc->lchild;b->parent = tc;if (tc->rchild){tc->rchild->parent = b;}b->lchild = tc->rchild;tc->rchild = b;tc->lchild = t;		if (b == mTree){mTree = tc;}}else if (high_diff == -2 && low_diff == 1){BBST* f = (BBST*)b->parent;if (f&&f->lchild == b){f->lchild = tc;}else if (f&&f->rchild == b){f->rchild = tc;}tc->parent = f;b->parent = tc;b->rchild = tc->lchild;if (tc->lchild){tc->lchild->parent = b;}t->parent = tc;t->lchild = tc->rchild;if (tc->rchild){tc->rchild->parent = t;}tc->rchild = t;tc->lchild = b;if (b == mTree){mTree = tc;}}else if (high_diff == -2 && low_diff == -1){BBST* f = (BBST*)b->parent;if (f && f->lchild == b){f->lchild = t;}else if (f && f->rchild == b){f->rchild = t;}t->parent = f;BBST* tl = t->lchild;t->lchild = b;b->parent = t;b->rchild = tl;if (tl){tl->parent = b;}if (b == mTree){mTree = t;}}tc = t;t = b;}return 0;
}

完整代码地址:
https://github.com/satadriver/dataStruct

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

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

相关文章

ElementPlus table 中嵌套 input 输入框

文章目录 需求分析 需求 vue3 项目中 使用UI组件库 ElementPlus 时&#xff0c;table 中嵌入 input输入框 分析 <template><div class"p-10"><el-table :data"tableData" border><el-table-column prop"date" label&qu…

课堂练习4.1:段式内存管理

4-1 课堂练习4.1&#xff1a;段式内存管理 段式内存管理以段为单位分配内存空间&#xff0c;段内连续&#xff0c;段间可以不连续。段可以很大&#xff0c;比如数据段、代码段、栈段等。本实训分析 Linux 0.11 的段式内存管理技术。 第1关1 号进程 mynext 变量的逻辑地址与线性…

cache教程 3.HTTP服务器

上一节我们实现了单机版的缓存服务&#xff0c;但是我们的目标是分布式缓存。那么&#xff0c;我们就需要把缓存服务部署到多态机器节点上&#xff0c;对外提供访问接口。客户端就可以通过这些接口去实现缓存的增删改查。 分布式缓存需要实现节点间通信&#xff0c;而通信方法…

【面试经典150 | 二叉树】翻转二叉树

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;递归方法二&#xff1a;迭代 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题…

4-SpringMVC

文章目录 项目源码地址回顾-MVC什么是MVC&#xff1f;MVC各部分组成 回顾-ServletMaven创建Web项目1、创建Maven父工程pom&#xff0c;并导入依赖2、用Maven新建一个Web Module3、代码&#xff1a;HelloServlet.java3、代码-hello.jsp3、代码-web.xml4、配置Tomcat5、浏览器测试…

github使用方法【附安装包】

如果你是一枚Coder&#xff0c;但是你不知道Github&#xff0c;那么我觉的你就不是一个菜鸟级别的Coder&#xff0c;因为你压根不是真正Coder&#xff0c;你只是一个Code搬运工。说明你根本不善于突破自己&#xff01;为什么这么说原因很简单&#xff0c;很多优秀的代码以及各种…

高级系统架构设计师之路

前言&#xff1a;系 统 架 构 设 计 师 (System Architecture Designer)是项目开发活动中的众多角色之 一 &#xff0c;它可 以是 一个人或 一个小组&#xff0c;也可以是一个团队。架构师 (Architect) 包含建筑师、设计师、创造 者、缔造者等含义&#xff0c;可以说&#xff0…

边缘计算系统设计与实践:引领科技创新的新浪潮

文章目录 一、边缘计算的概念二、边缘计算的设计原则三、边缘计算的关键技术四、边缘计算的实践应用《边缘计算系统设计与实践》特色内容简介作者简介目录前言/序言本书读者对象获取方式 随着物联网、大数据和人工智能等技术的快速发展&#xff0c;传统的中心化计算模式已经无法…

基于ssm人力资源管理系统论文

摘 要 随着企业员工人数的不断增多&#xff0c;企业在人力资源管理方面负担越来越重&#xff0c;因此&#xff0c;为提高企业人力资源管理效率&#xff0c;特开发了本人力资源管理系统。 本文重点阐述了人力资源管理系统的开发过程&#xff0c;以实际运用为开发背景&#xff0…

【大数据】Hudi 核心知识点详解(一)

Hudi 核心知识点详解&#xff08;一&#xff09; 1.数据湖与数据仓库的区别 &#xff1f;1.1 数据仓库1.2 数据湖1.3 两者的区别 2.Hudi 基础功能2.1 Hudi 简介2.2 Hudi 功能2.3 Hudi 的特性2.4 Hudi 的架构2.5 湖仓一体架构 3.Hudi 数据管理3.1 Hudi 表数据结构3.1.1 .hoodie …

【C语言】位运算实现二进制数据处理及BCD码转换

文章目录 1&#xff0e;编程实验&#xff1a;按short和unsigned short类型分别对-12345进行左移2位和右移2位操作&#xff0c;并输出结果。2&#xff0e;编程实验&#xff1a;利用位运算实现BCD码与十进制数之间的转换&#xff0c;假设数据类型为unsigned char。3&#xff0e;编…

多线程(进阶二:CAS)

目录 一、CAS的简单介绍 CAS逻辑&#xff08;用伪代码来描述&#xff09; 二、CAS在多线程中简单的使用 三、原子类自增的代码分析 都看到这了&#xff0c;点个赞再走吧&#xff0c;谢谢谢谢谢 一、CAS的简单介绍 CAS的全称&#xff1a;“Compare And Swap”&#xff0c;字…

C语言——字符函数和字符串函数(一)

&#x1f4dd;前言&#xff1a; 这篇文章对我最近学习的有关字符串的函数做一个总结和整理&#xff0c;主要讲解字符函数和字符串函数&#xff08;strlen&#xff0c;strcpy和strncpy&#xff0c;strcat和strncat&#xff09;的使用方法&#xff0c;使用场景和一些注意事项&…

Java入门项目--蚂蚁爱购

简介 这是一个靠谱的Java入门项目实战&#xff0c;名字叫蚂蚁爱购。 从零开发项目&#xff0c;视频加文档&#xff0c;十天就能学会开发JavaWeb项目&#xff0c;教程路线是&#xff1a;搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Ja…

解锁MySQL的威力:针对常见问题的快速解决指南

数据库和表的创建 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS MyDatabase; USE MyDatabase;案例&#xff1a; 想象您要开始一个博客项目。首先&#xff0c;您需要一个地方来存储所有的文章和用户信息。上述命令帮助您创建了这样一个存储空间&#xff0c;名为MyDa…

RocketMQ-源码架构二

梳理一些比较完整&#xff0c;比较复杂的业务线 消息持久化设计 RocketMQ的持久化文件结构 消息持久化也就是将内存中的消息写入到本地磁盘的过程。而磁盘IO操作通常是一个很耗性能&#xff0c;很慢的操作&#xff0c;所以&#xff0c;对消息持久化机制的设计&#xff0c;是…

蒙特霍尔问题(选择三扇门后的车与羊)及其贝叶斯定理数学解释

1. 蒙特霍尔问题 有一个美国电视游戏节目叫做“Let’s Make a Deal”&#xff0c;游戏中参赛者将面对3扇关闭的门&#xff0c;其中一扇门背后有一辆汽车&#xff0c;另外两扇门后是山羊&#xff0c;参赛者如果能猜中哪一扇门后是汽车&#xff0c;就可以得到它。 通常&#xf…

javaee实验:文件上传及拦截器的使用

目录 文件上传ModelAttribute注解实验目的实验内容实验过程项目结构编写代码结果展示 文件上传 Spring MVC 提供 MultipartFile 接口作为参数来处理文件上传。 MultipartFile 提供以下方法来获取上传的文件信息&#xff1a;  getOriginalFilename 获取上传的文件名字&#x…

飞天使-linux操作的一些技巧与知识点2

TCP 的三次握手 第一次&#xff0c;客户端与服务端建立链接&#xff0c;需要发送请求连接的消息 第二次&#xff0c;服务端接口到数据后&#xff0c;返回一个确认的操作*&#xff08;至此客户端和服务端链路建立成功&#xff09; 第三次&#xff0c;服务端还需要发送要与客户端…

【Linux】探索Linux进程状态 | 僵尸进程 | 孤儿进程

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 目录 一、进程状态1.1运行状态1.2阻塞状态1.3挂起状态 二、具体L…