使用C编程语言实现AVL树
本文将介绍AVL树及其插入、删除操作,最后使用C编程语言实现基于平衡因子(balance factor)的AVL树。
什么是AVL树?
AVL树(AVL tree)是前苏联计算机科学家Adelson-Velsky和Landis发明的一种自平衡二叉查找树(self-balancing binary search tree)。它有两大属性,一个是继承自二叉查找树的查找属性(binary search property),另一个是AVL树特有的平衡因子属性(balance factor property)。
节点的平衡因子是节点两个子树的高度差
BalanceFactor(N) = Height(RightSubtree(N)) – Height(LeftSubtree(N))
AVL树限定任意节点两个子树的高度差最大为1
BalanceFactor(N) ∈ {–1,0,+1}
由于AVL树是一种二叉查找树,所以它只能维持大体平衡,无法达到完全平衡。AVL树通过限定任意节点两个子树的高度差最大为1来保证二叉查找树的大体平衡,如果高度差大于1,则需要重新平衡。
AVL树只能大体平衡,2-3-4树通过可变的元素数量可完全平衡。
1
/ \ (1)
5 9 / \
/ (5) (6 9)
6
AVL树 2-3-4树
插入、删除操作
插入、删除操作后需要更新所有被影响的节点的平衡因子,稍作观察就能发现这些节点一定在从根节点到被插入、删除节点的路径上,这些节点都是被插入、删除节点的祖先节点(ancestors)。如何更新这些节点的平衡因子?如果更新后的平衡因子为+2或-2,如何重新平衡(rebalance)?
为了更好的描述,我们把根节点到被插入、删除节点的路径称作查找路径(search path),这条路径贯穿被插入、删除节点的所有祖先节点。
插入6的查找路径为1,9
1
/ \
5 9
删除6的查找路径为1,9
1
/ \
5 9
/
6
所以插入、删除操作只会影响查找路径上节点的平衡因子,而不会影响别的节点的平衡因子。
AVL树的插入操作
插入操作可能会导致查找路径上节点的高度增大,所以需要更新查找路径上节点的平衡因子,如果更新平衡因子后节点违背了平衡因子属性,则需要通过旋转进行重新平衡。过程如下:
- 从被插入节点的父节点开始,按照查找路径原路返回直到根节点,返回过程中更新当前节点的平衡因子,如果发现当前节点更新后的平衡因子绝对值大于1,则使用旋转操作进行重新平衡;
- 达到以下任一条件则完成所有操作。
a. 节点高度保持不变;
b. 旋转操作(该节点必然恢复原高度);
c. 到达根节点。
AVL树的删除操作
与插入操作类似,删除操作可能会导致查找路径上节点的高度减小,所以需要更新查找路径上节点的平衡因子,如果更新平衡因子后节点违背了平衡因子属性,则需要通过旋转进行重新平衡。过程如下:
- 从被删除节点的父节点开始,按照查找路径原路返回,返回过程中更新当前节点的平衡因子,如果发现当前节点更新后的平衡因子绝对值大于1,则使用旋转操作进行重新平衡;
- 达到以下任一条件则完成更新和修复操作。
a. 节点高度保持不变;
b. 旋转操作且旋转后节点恢复原高度;
c. 到达根节点。
综上,AVL树的插入操作最多只需要一次旋转操作就能重新平衡,而删除操作则可能需要多次旋转操作才能重新平衡。
AVL树的实现
经过较长时间的学习和分析,使用C编程语言实现了一个完整的基于平衡因子的AVL树,源码链接为https://github.com/xieqing/avl-tree,该实现通过了较完整的测试用例的验证,README.md对AVL树的实现做了详尽的分析,另外,通过一个简单的使用示例avl_example.c,您可以快速了解它的使用方法。
欢迎大家指正。
/*
* Copyright (c) 2019 xieqing. https://github.com/xieqing
* May be freely redistributed, but copyright notice must be retained.
*/
使用C编程语言实现AVL树的更多相关文章
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- AVL树原理及实现(C语言实现以及Java语言实现)
欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好 ...
- AVL树
AVL树 在二叉查找树(BST)中,频繁的插入操作可能会让树的性能发生退化,因此,需要加入一些平衡操作,使树的高度达到理想的O(logn),这就是AVL树出现的背景.注意,AVL树的起名来源于两个发明 ...
- AVL树的平衡算法(JAVA实现)
1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...
- 【数据结构】平衡二叉树—AVL树
(百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 数据结构图文解析之:AVL树详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- 数据结构之平衡二叉树(AVL树)
平衡二叉树(AVL树)定义如下:平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树: (1)它的左子树和右子树的高度之差绝对值不超过1: (2)它的左子树和右子树都是平衡二叉树. AVL树避免了 ...
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...
- 论AVL树与红黑树
首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...
随机推荐
- RN 获取组件的宽度和高度
https://www.cnblogs.com/zhiyingzhou/p/7471212.html https://blog.csdn.net/calvin_zhou/article/details ...
- 发布一个PHP包到Packagist, 然后使用Composer安装
Composer 能够方便的进行项目的依赖管理, 当我们发布一个包并且希望别人通过Composer安装的时候, 就需要将包发布到Composer的包仓库Packagist上面. 下面进行详细的说明一 ...
- 51nod1986 Jason曾不想做的数论题
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1986 方便起见,公式中的区间内只考虑整数,X的gcd,lcm定义为每个元 ...
- activity--常见属性总结
15.Activit的几个重要属性总结? 12.onNewIntent()使用Tips?11.launchMode的属性介绍?及其常用的Intent Flag? ==== 15.Activit的几个重 ...
- Livepeer中文白皮书(翻译)
Livepeer Whitepaper 分布式视频流媒体传输协议及经济激励 Doug Petkanics doug@livepeer.org Eric Tang eric@livepeer.org 翻 ...
- centos 7刚安装后无法联网解决
从6版本到7版本后, 7版本默认会关闭网卡 ,并且ifconfig 命令也换了 ip 命令来代替, 在这记录一下 ,希望 新人发现. 不是源的问题, 是压根没开网卡... 下面是写给萌新的: 先看一下 ...
- c#单例设计模式
class Person { private static Person persons; public static Person Persons { get{ if (persons==null) ...
- 如何通过dba_hist_active_sess_history分析数据库历史性能问题
背景在很多情况下,当数据库发生性能问题的时候,我们并没有机会来收集足够的诊断信息,比如system state dump或者hang analyze,甚至问题发生的时候DBA根本不在场.这给我们诊断问 ...
- mvcmovie sample 在window10 下的部署问题(HTTP Error 500.19 - Internal Server Error)
mvcmovie sample 在window10 下的部署问题 使用VS2018配置好了mvcmovie sample,发布到IIS后,打开报错: HTTP Error 500.19 - Inter ...
- 2018-2019-2 20175328 《Java程序设计》第八周学习总结
2018-2019-2 20175328 <Java程序设计>第八周学习总结 主要内容 泛型 泛型推出的主要目的是可以建立具有类型安全的集合框架,如链表.散列映射等数据结构. 1.泛型类声 ...