本文将介绍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. 从被插入节点的父节点开始,按照查找路径原路返回直到根节点,返回过程中更新当前节点的平衡因子,如果发现当前节点更新后的平衡因子绝对值大于1,则使用旋转操作进行重新平衡;
  2. 达到以下任一条件则完成所有操作。

    a. 节点高度保持不变;

    b. 旋转操作(该节点必然恢复原高度);

    c. 到达根节点。

AVL树的删除操作

与插入操作类似,删除操作可能会导致查找路径上节点的高度减小,所以需要更新查找路径上节点的平衡因子,如果更新平衡因子后节点违背了平衡因子属性,则需要通过旋转进行重新平衡。过程如下:

  1. 从被删除节点的父节点开始,按照查找路径原路返回,返回过程中更新当前节点的平衡因子,如果发现当前节点更新后的平衡因子绝对值大于1,则使用旋转操作进行重新平衡;
  2. 达到以下任一条件则完成更新和修复操作。

    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树的更多相关文章

  1. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  2. AVL树原理及实现(C语言实现以及Java语言实现)

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好 ...

  3. AVL树

    AVL树 在二叉查找树(BST)中,频繁的插入操作可能会让树的性能发生退化,因此,需要加入一些平衡操作,使树的高度达到理想的O(logn),这就是AVL树出现的背景.注意,AVL树的起名来源于两个发明 ...

  4. AVL树的平衡算法(JAVA实现)

      1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...

  5. 【数据结构】平衡二叉树—AVL树

    (百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...

  6. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. 数据结构之平衡二叉树(AVL树)

    平衡二叉树(AVL树)定义如下:平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树: (1)它的左子树和右子树的高度之差绝对值不超过1: (2)它的左子树和右子树都是平衡二叉树. AVL树避免了 ...

  8. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

  9. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

随机推荐

  1. MySQL 索引的增删查

    查看索引: > SHOW INDEX FROM table_name; > SHOW KEYS FROM table_name;   删除索引: > DROP INDEX index ...

  2. Office365维护命令

    # 会议室日历相关# 日语:予定表# 汉语:日历Set-MailboxFolderPermission -Identity "XXXXX@qq.com:\Calendar" -ac ...

  3. C#中基于GDI+(Graphics)图像处理系列

    https://blog.csdn.net/lhtzbj12/article/details/54024821

  4. 前端-JavaScript练习2

    用户输入一个年份,判断这个年是否是闰年. 判断闰年条件: ① 非整百年数除以4,无余为闰,有余不闰: ② 整百年数除以400,无余为闰,有余不闰. 比如: 2000年,整百数年,就要用②公式,除以40 ...

  5. ROS多根adsl叠加负载均衡PCC的做法

    命令行: / ip firewall mangle1.保证访问局域网IP的时候不被PCC了.add chain=prerouting dst-address=10.1.1.0/24 action=ac ...

  6. Python【每日一问】11

    问: 请简单说明一下以下代码的执行过程以及最终的输出结果 def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + ...

  7. Kafka安装及开启SASL_PLAINTEXT认证(用户名和密码认证)

    前些日子要封装一个kafka的客户端驱动,配置了下kafka环境,发现配置复杂度完爆rabbitmq很多倍啊,而且发布订阅模式使用起来也很麻烦,可能就胜在分布式了吧. kafka需要java环境,自行 ...

  8. 设计模式<2>------工厂模式和抽象工厂模式------创建型

    简单工厂: 拿我们的简单三层举例子 先定义dal层 class Dal { public void Delete() { } } 工厂类 class Factory { //这样掉的好处是 当dal层 ...

  9. 羊车门问题(Python)

    羊车门问题(结对作业) 在完成本题之前,请仔细阅读下面内容: 题目描述:有3扇关闭的门,一扇门后面停着汽车,其余门后是山羊,只有主持人知道每扇门后面是什么.参赛者可以选择一扇门,在开启它之前,主持人会 ...

  10. N个工作日后的日期

    这里对特殊日期采用了模拟的方式,在实际开发中当然这些数据是从数据库中读取,调用方法时 只需传入开始时间(一般当前) 和N(代表N个工作日) /// <summary> /// 获取时间 / ...