平衡二叉排序树

二叉树-详解平衡二叉排序树AVL 平衡二叉搜索树AVL也许因为输入值不够随机,也许因为输入顺序的原因,还或许一些插入、删除操作,会使得二叉搜索树失去平衡,造成搜索效率低落的情况。 比如上面两个树,在平衡树上寻找15就只要2次查找,在非平衡树上却要5次查找方能找到,效率明显下降。那么什么叫“平衡”,直观上的最佳平衡条件就是 每个节点的左右子树有着相同高度,但这确实太过苛刻。平衡二叉树AVL tree退而求其次,要求任何节 阅读详情

一.概念
在这里插入图片描述
最小不平衡子树:距离插入结点最近的,且平衡因子的绝对值大于1的结点为根的子树

二.实现原理
基本思想:在构建二叉排序树时,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。
1.BF为负时向左转,为正向右转
2.转向之前要确保最小不平衡子树的根结点与它的子结点符号是相同的 同正负再调向

举个例子
对于一个给定的数组 [3, 2, 1, 4, 5, 6, 7, 10, 9, 8]
在这里插入图片描述
在这棵树中可以看到只有根节点 2 是不平衡的,且 BF = -2 < 0,所以需要将根节点 2 向左旋转,得到如下的结果
在这里插入图片描述
由于 3 小于 4 ,所以将 3 连接在 4 的左子树的最右端,得到如下图所示的结果
在这里插入图片描述
添加9
在这里插入图片描述
但是这个结点不可以像之前一样通过旋转 7 10 9 这棵子树,因为这个时候, 10 结点的 BF 符号与之前的符号均不相同,所以要首先将 9 10 旋转,之后再将不平衡子树进行旋转,如下图所示
在这里插入图片描述
添加8
在这里插入图片描述
明显结点 4 的 BF 为正,结点 6 的 BF 为正,但是结点 9 的 BF 为负,这个时候应该先将 8 7 9 10 进行旋转,使得 BF 值相等,然后再调整二叉排序树,如下图所示

在这里插入图片描述
三.不平衡因子的四种情况
1.单向右旋平衡处理:若由于结点 a 的左子树为根结点的左子树上插入结点,导致结点 a 的平衡因子由 1 增至 2,致使以 a 为根结点的子树失去平衡,则只需进行一次向右的顺时针旋转,如下图这种情况
在这里插入图片描述
2.单向左旋平衡处理:如果由于结点 a 的右子树为根结点的右子树上插入结点,导致结点 a 的平衡因子由 -1变为 -2,则以 a 为根结点的子树需要进行一次向左的逆时针旋转,如下图这种情况:
在这里插入图片描述
3.双向旋转(先左后右)平衡处理:如果由于结点 a 的左子树为根结点的右子树上插入结点,导致结点 a 平衡因子由 1 增至 2,致使以 a 为根结点的子树失去平衡,则需要进行两次旋转操作,如下图这种情况:
在这里插入图片描述
4.双向旋转(先右后左)平衡处理:如果由于结点 a 的右子树为根结点的左子树上插入结点,导致结点 a 平衡因子由 -1 变为 -2,致使以 a 为根结点的子树失去平衡,则需要进行两次旋转(先右旋后左旋)操作,如下图这种情况:
在这里插入图片描述
四.构建平衡二叉树的代码实现
1.结点结构

typedef struct BiTNode{
	int data;
	int BF;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

2.左右旋操作

void L_Rotate(BiTree *p)
{
	BiTree L;
	L = (*p) -> rchild;
	(*p) -> rchild = L -> lchild;
	L -> lchild = (*p);
	*p = L;
}

void R_Rotate(BiTree *p)
{
	BiTree L;
	L = (*p) -> lchild;
	(*p) -> lchild = L -> rchild;
	L -> rchild = (*p);
	*p = L;
}

3.左右平衡旋转处理

void LeftBalance(BiTree *T)
{
	BiTree L, Lr;
	L = (*T) -> lchild;
	switch(L -> BF)
	{
		case LH:
			{
				(*T) -> BF = L -> BF = EH;
				R_Rotate(T);
				break;
			}
		case RH:
			{
				Lr = L -> rchild;
				switch(Lr -> BF)
				{
					case LH:
						{
							(*T) -> BF = RH;
							L -> BF = EH;
							break;
						}
					case EH:
						{
							(*T) -> BF = L -> BF = EH;
							break;
						}
					case RH:
						{
							(*T) -> BF = EH;
							L -> BF = LH;
							break;
						}
				}
				Lr -> BF = EH;
				L_Rotate(&(*T) -> lchild);
				R_Rotate(T);
			}
	}
}

void RightBalance(BiTree *T)
{
	BiTree L, Lr;
	L = (*T) -> rchild;
	switch(L -> BF)
	{
		case RH:
			{
				(*T) -> BF = L -> BF = EH;
				L_Rotate(T);
				break;
			}
		case LH:
			{
				Lr = L -> lchild;
				switch(Lr -> BF)
				{
					case LH:
						{
							(*T) -> BF = EH;
							L -> BF = RH;
							break;
						}
					case EH:
						{
							(*T) -> BF = L -> BF = EH;
							break;
						}
					case RH:
						{
							(*T) -> BF = EH;
							L -> BF = LH;
							break;
						}
				}
				Lr -> BF = EH;
				R_Rotate(&(*T) -> rchild);
				L_Rotate(T);
			}
	}
}

4.二叉树的主函数

int InsertAVL(BiTree *T, int e, int *taller)
{
	if(!*T)
	{
		*T = (BiTree)malloc(sizeof(BiTNode));
		(*T) -> data = e;
		(*T) -> lchild = (*T) -> rchild = NULL;
		(*T) -> BF = EH;
		*taller = TRUE;
	}
	else 
	{
		if(e == (*T) -> data)
		{
			*taller = FALSE;
			return FALSE;
		}
		if(e < (*T) -> data) //应继续在T的左子树中进行搜索 
		{
			if(! InsertAVL(&(*T) -> lchild, e, taller))
			{
				return FALSE;
			}
			if(*taller) //已经插入到T的左子树里且左子树"长高"
			{
				switch((*T) -> BF)
				{
					case LH:
						{
							LeftBalance(T);
							*taller = FALSE;
							break;
						}
					case EH: //原本左右子树等高,现在左子树增高而树增高 
						{
							(*T) -> BF = LH; 
							*taller = TRUE;
							break;
						}
					case RH:  
						{
							(*T) -> BF = EH;
							*taller = FALSE;
							break;
						}
				}
			}
		}
		else
		{
			if(! InsertAVL(&(*T) -> rchild, e, taller))
			{
				return FALSE;
			}
			if(*taller)
			{
				switch((*T) -> BF)
				{
					case LH:
						{
							(*T) -> BF = EH;
							*taller = FALSE;
							break;
						}
					case EH:
						{
							(*T) -> BF = RH; 
							*taller = TRUE;
							break;
						}
					case RH:
						{
							RightBalance(T);
							*taller = FALSE;
							break;
						}
				}
			}
		}
	}
	return TRUE;
} 
数据结构.平衡二叉树.从二叉排序树到平衡二叉树 数据结构的平衡二叉树,自己的思路整理,有图示和部分的代码 阅读详情

相关推荐

平衡二叉排序树(完整案例详解及完整C代码实现)

写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站。博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事,做自己以后不会留有遗憾的事,做自己觉得有意义的事,不浪费这大好的青春年华。博主写博客目的是记录所学到的知识并方便自己复习,在记录知识的同时获得部分浏览量,得到更多人的认可,满足小小的成就感,同时在写博客的途中结交更多志同道合的朋友,让自己在技术的路上并不孤单。 目录: 1.平衡二叉树简介 2.二叉排序.

记录博主学到的点滴 6257

查找知识盘点(树形结构)

我们实现LL变换,就把平衡因子为1的这个B节点拎起来,想象一下把图(b)的B节点提起来,然后因为重力,BL成了它的左节点,A掉下来成了它的右节点,也就是以A为起点遍历两次Lchild,即为LL,遍历了A B BL,再以B为中心,BL和A分别成了B的左右孩子。那么我们这次以C为中心,把C提起来,从AB中间穿过,并将B作为左孩子,A作为右孩子,那么CL挂到了B的右孩子上,CR挂到了A的左孩子上,就得到了(c)同理,我们观察RR旋转,A为-2,B为-1,AB同号且都为负,那么要抓住其最小不平衡子树中的这个形状。

milu_ELK的博客 911

依次把 11 个关键字插入到初始化为空的平衡二叉排序树中,在插入过程中平衡树条件如被破坏,得到的平衡二叉排序树的深度为()

依次把结点的关键字的值为50,30,20,150,130,40,80,70,85,15的记录插入到初始化为空的平衡二叉排序树中,在插入过程中平衡树条件如被破坏,则进行必要的调整,得到的平衡二叉排序树的深度为() 正确答案: C   你的答案: D (错误) 6 5 4 3 添加笔记 求解答(3) 收藏 纠错

chengonghao的博客 4752

平衡二叉树详解 通俗易懂

平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点的时候,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡树。在保持二叉排序树特性的前提下,调整最小不平衡树中各结点之间的连接关系,进行相应的旋转,使之称为新的平衡子树。 为了我们以后的讲解看起来更加轻松一点,我们先讲述一个平衡二叉树构建过程的例子。假设我们现在有一个数组a【10】={ 3,2,1,4,5,6,7,10,9,8}需要构建二叉排序树。在没有学习平衡二叉树之前,根据二叉排序树的特性,我们通常会将它构建称为图5的样子。.

m0_61886762的博客 1万+

查找 —— 平衡二叉排序树

一、定义 二叉排序树的时间复杂度为 O(n),平衡二叉排序树的时间复杂度为 O(logn) 平衡二叉树又称 AVL 树,是一种特殊的二叉排序树,拥有更高的查询效率。平衡二叉树或是一棵空树,或满足下列性质的一棵非空的二叉树T: T的左子树和右子树的深度之差的绝对值不超过1; T的左子树和右子树均为平衡二叉树。 二叉树T的结点平衡因子BF(Balance Factor)为左子树的深度减去右子树的深...

starter_____的博客 1104

【swjtu】数据结构实验8_平衡二叉排序树

实验内容及要求: 从键盘输入若干两两互不相同的非0整数,直到输入0时停止。将输入的所有非0整数按输入次序插入二叉排序树来构造平衡的二叉排序树。输出平衡的二叉排序树的先序和中序递归遍历次序;按中序递归遍历次序输出平衡的二叉排序树各结点的平衡因子。注意:二叉树结点存储结构中应增加平衡因子域。 实验目的: 掌握平衡二叉排序的建立方法(学会LL,LR,RR,RL四种旋转类型);掌握二叉排序树的特性。 数据结构设计简要描述: 平衡二叉排序树的数据结构设计以树的结点结构为基础,在每个结点..

qq_52046937的博客 805

看图说话之平衡二叉排序树(AVL树)

介绍了平衡二叉排序树的基本原理,重点介绍了AVL树的基本实现方法,并且给出了完整java代码实现

涂印的博客 7780

数据结构07:查找[C++][平衡二叉排序树AVL]

考研笔记整理1w+字,小白友好、代码可跑,请小伙伴放心食用~~🥝🥝

weixin_42789937的博客 1226

【数据结构】基于树的查找法——平衡二叉排序树(C语言)

平衡二叉排序树又称AVL树。一棵平衡二叉排序树或者是空树,或者是具有下列性质的二叉排序树:① 左子树与右子树的高度之差的绝对值小于等于1;② 左子树和右子树也是平衡二叉排序树。

weixin_51450101的博客 3469

Tribon Vitesse开发教程(一)

Tribon Vitesse简介 Tribon Vitesse是Tribon提供给Python编程语言的编程接口,它是一系列的API。使用Python的语法调用这些API,结合Python语言自身的语法生成的程序叫做Vitesse程序。Vitesse是法语“速度”的意思,读作“为戴斯”。使用Tribon Vitesse可以直接访问Tribon产品信息模型和使用Tribon应用程序的功能,以控制设计

forevermemory的专栏 2593

电力系统设计实战:如何用ETAP绘制一次接线图并优化供电方案

本文详细介绍了如何使用ETAP软件进行电力系统一次接线图的绘制与供电方案优化。从基础环境配置到主接线拓扑构建,再到典型接线方式的对比分析与智能优化,为工业与民用电力系统设计提供实用指南。通过ETAP的可靠性分析和动态仿真功能,帮助工程师选择最优供电方案,提升系统可靠性和运维效率。

weixin_29250573的博客 206

Java实现平衡二叉排序树

目录: 平衡二叉排序树的概念 平衡二叉排序树四种不平衡的类型及解决方法 算法 插入 删除 查找 一.平衡二叉排序树的概念 如果树T既是平衡二叉树(树中每个结点的左右子树的高度差不超过1),又是二叉排序树,那么它就是平衡二叉排序树。 二.平衡二叉排序树四种不平衡的类型及解决方法 在此文已经分析过:开头:数据结构和算法的平衡二叉排序树部分 三.算法 1....

yiguang_820的博客 295

XY2-100协议解析

1.XY2-100包括四路信号 : SENDCK(时钟信号)、SYNC(同步信号)、CHANNELX(X通道)、CHANNELY(Y通道)

qq_38360574的博客 9534

平衡二叉排序树(AVL)构造过程及Java代码实现

1、定义 平衡二叉排序树要求任何节点的左右子树高度差绝对值不超过1(左右子树高度可相同)。 2、普通二叉排序树不足 以依次插入1,2,3,4,5,6数为例,结果如下图所示: 当查找元素6时,时间复杂度为O(n),并且这样构造相当于有一边的孩子节点失去了意义,这样就违背了二叉树的初衷。 3、平衡二叉排序树构造 为了在不断向二叉排序树插入或者删除元素的过程中保持平衡性(即...

henry的博客 7410

基于 openEuler 24.03 LTS 源码编译安装 Zabbix 7.4

Zabbix是一款开源的企业级分布式监控系统,支持网络、服务器、应用等多种IT资源的监控。核心功能包括数据采集、告警通知、可视化展示等,采用Server/Agent架构,支持多种操作系统。本文详细介绍了在openEuler 24.03系统上部署Zabbix 7.4.2的完整流程,包括环境准备、MySQL配置、PHP/Apache安装、Zabbix编译安装等步骤,为构建企业级监控系统提供了实践指导。

广然笔记 1193

【Claude Code】Claude Code 使用指南

本文介绍了AI编码助手Claude的基础和进阶操作指南。基础部分涵盖启动命令、模式切换(自动编辑/Plan/Yolo模式)、资源监控等核心功能,重点讲解了斜杠命令的使用方法。进阶操作详细说明了CLAUDE.md文件的创建与管理,包括项目规范、代码风格等内容的配置,以及如何通过该文件建立持久上下文。同时提醒了使用过程中的安全风险,建议通过配置文件限制AI对关键代码的访问权限。全文提供了完整的操作指引和安全建议,帮助开发者高效安全地使用Claude进行编码辅助。

大家好,我是敖云岚,一个沉迷代码的 “技术玩家”。擅长 Java、C++ 开发,对 MySQL、Redis、RabbitMQ 等技术也颇有研究。博客里既有硬核技术干货,也有诙谐幽默的编程日常分享。愿和你一起,笑着学技术,快乐敲代码! 1万+

[数据结构与算法] 二叉排序树之平衡二叉排序树

文章目录二叉排序树1. 二叉排序树2. 平衡二叉排序树 二叉排序树 1. 二叉排序树 二叉排序树的检索 def bt_search(btree, key): bt = btree: while bt: if key < bt.val: bt = bt.left elif key > bt.val: ...

阿辉的博客 1688

ubuntu20.04升级OpenSSH

业务需求,需要将服务器的OpenSSH版本从8.2升级到最新版本(9.9),由于apt能提供的最新版本就是8.2,所以需要采用源码安装的方式。

xiamu66的博客 1527

平衡二叉排序树插入结点的学习总结

最近写了平衡二叉排序树代码,在这里对自己的理解做一下总结。 下面的文字,更多的是把我自己的遇到的理解上的问题和思路讲清楚,可能不能让你一下就看明白,这是我的问题。网上其实有很多写的很好的文章,我也是学他们的,然后通过写文章来考研自己是不是真的理解平衡二叉树,如果你在看完文章有任何疑惑,请留言。 下面几张图片是从这里拿过来的:http://blog.sina.com.cn/s/blog_

wangxiaolongbob的专栏 2806

OneOS远程升级能力实操演示 | OTA升级

OneOS远程升级能力实操演示,差分算法提升效率,OTA升级,OTA差分算法,全量升级、压缩升级、差分升级,有线网络连接,bootloader,升级平台,在线差分包制作,触摸屏以及GUI图形操作

OneOS是中国移动针对物联网领域推出的轻量级操作系统 2011

YOLOv8 | 代码逐行解析(一) | 项目目录构造分析

Hello,大家好这次给大家带来的不是改进,是整个YOLOv8项目的分析,整个系列大概会更新7-10篇左右的文章,从项目的目录到每一个功能代码的都会进行详细的讲解,同时YOLOv8改进系列也突破了三十篇文章,最后预计本专栏持续更新会在年底更新上百篇的改进教程, 所以大家如果没有订阅专栏可以提前订阅以下。下面开始进行YOLOv8逐行解析的一篇——项目目录构造分析在这里给大家推荐我的YOLOv8改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,。

Snu77的博客 4万+

构建平衡二叉排序树

对于输入数据,编写程序构建平衡二叉排序树,即实现不断插入数据以及调节树高度保持平衡的过程。

weixin_67324437的博客 548

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

26. 平衡二叉排序树

平衡二叉排序树的生成,查找和删除

dugudaibo的博客 2万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

数据结构 平衡二叉排序树有话说

平衡二叉排序树又称AVL树。 平衡二叉排序树性质: ① 左右子树的高度之差的绝对值小于等于1。 ② 左右子树也是平衡二叉排序树。 平衡二叉排序树比普通的二叉排序树查询效率要高。 平衡因子:结点的左子树深度与右子树深度之差。对于一棵平衡二叉排序树,其所有结点的平衡因子只能是-1、0或1。 求平衡二叉排序树各结点因子: 每个结点旁边的数字就是每个结点的平衡因子。 计算过程: 如A结点,它的左右子树是根节点为B和C的子树 对于根节点为B的子树,树的深度是1,对于C,深度是2,则可以得到A..

qq_44647223的博客 395

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: 二叉排序树
下一篇: 多路查找树
ZoeLandia
博客等级 码龄6年 734粉丝 183原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值