数据结构与算法——图解平衡二叉树及代码实现
平衡二叉树介绍
平衡二叉树,是一种二叉排序树,其中每一个节点的左子树和右子树的高度差最多等于1。由3位科学家共同发明,用他们首字母命名 又被称为AVL树。从平衡二叉树的名称,你也可以体会到它是一种高度平衡的二叉排序树。我们将二叉树上结点的左子树深度减去右子树的深度的值称为平衡因子BF,那么平衡二叉树上的所有结点的平衡因子只能是-1,0,1。
平衡二叉树的实现原理
平衡二叉树构建的基本思想就在在构建二叉排序树的过程中,每当插入一个结点时,先检查否是因为插入而破坏了树的平衡性,若是,这找出最小不平衡树,在满足二叉排序树的特点,将其调整成新的平衡二叉树。
旋转图解
在理解平衡二叉树代码之前,我们得理解树的旋转,在下面的一系列图中,字母并无实际意义不代表其数据域,就是一个标识,但是要想着他们都是满足二叉排序的特性,在这个特性之上进行旋转。
对树节点进行左右旋转
下面2图是最基本的左右旋转,理解后,对应的旋转代码就好理解了。
双旋转的情况
让其左平衡,进行右旋转,让其右平衡进行左旋转。T代表要旋转的树节点,L = T->lchild,Lr = L-rchild;R = T->rchild,Rl = R->lchild;
但是要注意下面情况:
某个树节点T插入结点后,如果其左不平衡bf > 0,我们通过旋转让其左平衡。此时,其 L 左孩子的 bf 会影响如何旋转,如果L->bf = 1 同 T 方向一致,这是最简单的情况,只需将T进行右旋转。右平衡也是一样的道理。如果L->bf 和 T的方向不一致,那么就要先通过左旋转 让T->lchild和 T的方向一致,T在进行右旋转。
结合代码很好看明白。
左平衡情况
右平衡情况
实现代码
下面主要是平衡二叉树的插入算法,平衡二叉树的主要算法也就是插入算法。它的删除和查找同二叉排序树是一样的这里就多写了,有兴趣可以看数据结构与算法——二叉排序树详解以及代码实现。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{int data;int bf;struct BiTNode* lchild, *rchild;
}BiTNode, *BiTree;
typedef enum{false,true}bool;
//左旋转
void L_Rotate(BiTree *T)
{BiTree R = (*T)->rchild;(*T)->rchild = R->lchild;R->lchild = *T;*T = R;return;
}
//右旋转
void R_Rotate(BiTree *T)
{BiTree L = (*T)->lchild;(*T)->lchild = L->rchild;L->rchild = *T;*T = L;return;
}
#define LH +1
#define EH 0
#define RH -1
//T 的左边高,不平衡,使其平衡,右旋转,右旋转前先检查L->bf,
//如果为RH,L要先进行左旋转,使T->lchild->bf和T->bf一致
void LeftBalance(BiTree* T)
{BiTree L,Lr;L = (*T)->lchild;Lr = L->rchild;switch (L->bf){case LH:L->bf = (*T)->bf = EH;R_Rotate(T);break;case RH:switch (Lr->bf){case LH:L->bf = EH;(*T)->bf = RH;break;case EH:L->bf = (*T)->bf = EH;break;case RH:L->bf = LH;(*T)->bf = EH;break;}Lr->bf = EH;L_Rotate(&L);R_Rotate(T);break;}
}
//T 的右边高,不平衡,使其平衡,左旋转,左旋转前先检查R->bf,
//如果为LH,R要先进行右旋转,使T->rchild->bf和T->bf一致
void RightBalance(BiTree* T)
{BiTree R,Rl;R = (*T)->rchild;Rl = R->lchild;switch(R->bf){case RH:R->bf = (*T)->bf = EH;L_Rotate(T);break;case LH:switch(R->bf){case LH:R->bf = RH;(*T)->bf = EH;break;case EH:R->bf = (*T)->bf = EH;break;case RH:R->bf = EH;(*T)->bf = LH;break;}Rl->bf = EH;R_Rotate(&R);L_Rotate(T);break;}
}
//往平衡二叉树上插入结点
bool InsertAVL(BiTree* T,int data,bool *taller)
{if(*T == NULL) //找到插入位置{*T = (BiTree)malloc(sizeof(BiTNode)); (*T)->bf = EH;(*T)->rchild = (*T)->lchild = NULL;(*T)->data = data; *taller = true;}else{if(data == (*T)->data) //树中有相同的结点数据直接返回{*taller = false;return false;}if(data < (*T)->data) //往左子树搜索进行插入{if(!InsertAVL(&(*T)->lchild,data,taller)) //树中有相同的结点{*taller = false;return false;} if (*taller){switch ((*T)->bf) //T插入结点后,检测平衡因子,根据情况,做相应的修改和旋转{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(!Insert(&(*T)->rchild),data,taller) //树中有相同的结点{*taller = false;return false;}if (*taller) //插入到右子树中且长高了{switch ((*T)->bf) //T插入结点后,检测平衡因子,根据情况,做相应的修改和旋转{case LH:(*T)->bf = EH;*taller = false;break;case EH:(*T)->bf = RH;*taller = true;break;case RH:R_Balance(T); //插入后右边不平衡了,让其右平衡*taller = false;break;}}}}return true;
}
数据结构与算法——图解平衡二叉树及代码实现相关推荐
- 算法为何重要(《数据结构与算法图解》by 杰伊•温格罗)
本文内容借鉴一本我非常喜欢的书--<数据结构与算法图解>.学习之余,我决定把这本书精彩的部分摘录出来与大家分享. 写在前面 算法这个词听起来很深奥,其实不然.它只是解决某个问题的一套流程. ...
- 【数据结构与算法】平衡二叉树、红黑树
1.树.二叉树 2.二叉查找树 3.平衡二叉树.红黑树 4.递归树 一,什么是"平衡二叉查找树" 1,定义:二叉树中任意一个节点的左右子树的高度相差不能大于1. 所以:完全二叉树, ...
- 数据结构与算法 pdf_整理一个月完成的数据结构与算法PDF和测试代码免费拿
点击上方「10分钟编程」关注我呦 让我们每天「博学」一点点 数据结构与算法 作为一名2021届的学生,今年7月份就要面临秋招了,那么对于应届生来说,要想脱颖而出,笔试就显得太重要了,算法题是笔试环节的 ...
- 数据结构与算法之-----图(代码实现)
[ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己构建的,未使用 ...
- 数据结构与算法(一) 链表(代码示例)
数据结构与算法 1. 什么是单链表 2. 实现单链表的增删操作 1. 插入单链表第i个结点,即插入到ai-1与ai之间的具体步骤: 2. 删除第i个结点 3. 删除链表的重复数据 4. 找出单链表中的 ...
- python数据结构与算法知识点_数据结构和算法基础知识点(示例代码)
数据结构和算法基础知识点 链表 1.链表是一种由节点组成的线性数据集合,每个节点通过指针指向下一个节点.它是 一种由节点组成,并能用于表示序列的数据结构. 2.单链表:每个节点仅指向下一个节点,最后一 ...
- java数据结构与算法之平衡二叉树(AVL树)的设计与实现中的事实代码
普通二叉查找树的问题 在开篇,我们提到过,普通二叉树(二叉查找树)在操作的时间复杂度上不一定遵循O(㏒n),也有可能是O(n),这是为什么呢?在上一篇中,我们明明插入都按照一定规则比较的呀,其实那 ...
- 《算法笔记》中文版 - 包括数组,链表,树,图,递归,DP,有序表等相关数据结构与算法的讲解及代码实现...
来源:专知本文为资源,建议阅读5分钟本文为你分享<算法笔记>中文版. https://github.com/Dairongpeng/algorithm-note 目录概览 第一节 复杂度. ...
- 数据结构与算法图解——树
文章目录 7. 树 7.1 树的逻辑结构 7.1.1 例题 7.2 树的基本术语 7.2.1 例题 7.3 二叉树的性质 7.3.1 性质1 7.3.2 性质2 7.3.3 性质3 7.3.4 性质4 ...
最新文章
- 360首席安全官谭晓生宣布离职
- oracle加并行变慢,并行设置不当导致数据处理速度变慢
- FastRCNN 训练自己数据集 (1编译配置)
- ASCII表完整版(包含16进制对应表)
- graph-easy 纯文本图绘制工具(表格或流程图)
- [运维]---linux机器一般监控用到的概念记录
- Oracle 11g安装(window)的7个服务
- Idea导出可运行Jar包
- qlv格式转Mp4格式
- ES已经安装了ik分词器,仍然报错analyzer [ik_max_word] not found for field
- c语言字符码,C语言字符转ASII码
- 【技巧】如何修改PDF文件?
- 剑灵在该服务器上未获取到角色信息,白青FAQ!常见问题一网打尽
- 计算机运行加减乘除哪个最慢,计算机算加减乘除的时间对比
- 电机编码器的使用方法
- 第十六章 综合实例——《跟我学Shiro》
- linux远程 p2p下载,在linux as3中利用iptables+ipp2p限制bt、eMule等下载
- 【云原生布道系列】第三篇:“软”饭“硬”吃的计算
- 豆腐西施新传:大学毕业生也去磨豆腐
- 铁路订票网站,网友设计整理
热门文章
- 什么样的研究有价值?
- 小学奥数 7828 最大公约数与最小公倍数 python
- linux安装常用命令工具包wget,cmake等
- avg最多用多少列 mysql_MySQL之聚合数据(AVG,COUNT,MAX,MIN,SUM)
- flash源文件_Animate/FLASH如何将多个源文件合并
- statement执行insert into语句_【图文并茂】源码解析MyBatis ShardingJdbc SQL语句执行流程详解...
- Java笔记-获取自己资源文件中的配置文件(打包成jar包为其他包所引用也能获取)
- Linux学习笔记-生成动态库(补充说明)
- webso员ket php,客戶端和PHP後端通信:Sokets,Stream,TCP/UDP?
- 计算机大致可以分为大型计算机嵌入式系统,计算机类型大致可以分为:大型计算机、、嵌入式系统三类...