先来了解一些基本概念:

1)什么是二叉平衡树?

之前我们了解过二叉查找树,我们说通常来讲, 对于一棵有n个节点的二叉查找树,查询一个节点的时间复杂度为log以2为底的N的对数。

通常来讲是这样的, 但是。。。有例外

比如,我们向一棵树中输入预先排好序的数据, 如1,2,3,4,5,。。。10000, 可以想象到,将形成一棵斜树那么查找10000就要经过9999次比较才能得到,这显然不是我们期望看到的

所以,我们希望引入一个约束条件----任何节点的深度不得过深。

这就是二叉平衡树

二叉平衡树是二叉查找树(排序树)的一种,其每一个节点的左子树和右子树的高度差最多为1

如上图, 左边两棵树并不是二叉平衡树, 因为节点58的左子树和右子树高度差>1。 (分别为2和3)

2)平衡因子?

二叉树上节点的左子树高度 减去 右子树高度, 得到的结果称为该节点的平衡因子

3)最小不平衡树?

当我们给一个二叉平衡树增加新的节点时,会产生最小不平衡树

以   距离插入节点最近的,平衡因子大于1的节点   为根的树, 我们称为最小不平衡树

了解了基本概念之后,我们来看看如何构建一棵二叉平衡树

来看一个例子,我们从初始的空AVL树开始插入3,2,1, 当插入1时, AVL的性质在根(3)处被破坏,此时,我们需要在根与其左儿子间实施单旋转以解决这个问题

我们继续插入节点4, 这没什么问题, 但当我们插入节点5时, AVL的性质在节点3处被破坏, 因此, 我们需要在节点3与其右儿子之间实施一次左旋来解决这个问题

现在我们再插入节点6,此时AVL的性质在根节点(2)处被破坏, 因此我们在根节点和其右节点4之间实施一次左旋

左旋的结果是 4成为根节点,2成为4的左儿子, 4 原本的左儿子3成为2的右儿子

现在再插入节点7, 此时AVL的性质在节点5处被破坏, 因此我们在5节点和其右节点6之间实施一次左旋

根据上面的操作,我们现总结处两条规律:(太绕口,不用记,看图能理解就可以)

假设当我们插入新节点时,导致了原AVL树在节点 p 处不平衡,那么

1)如果添加的新节点是p的左儿子的左儿子, 则在p和其左儿子之间实施一次右旋转, p变成其左儿子的右儿子(如果其左儿子原本已经有右儿子, 则原本的右儿子成为p的左儿子)

2)如果新加的节点是p的右儿子的右儿子, 则在p和其右儿子之间实施一次左旋转,p变成其右儿子的左儿子(如果其右儿子原本已经有左儿子, 则原本的左儿子成为p的右儿子)

感觉头都转晕了

but...真正复杂的还在后面。。。。。。。。

现在我们给上面的二叉树插入节点16,这没什么问题, 再插入15, 此时二叉树在节点7处不再平衡,这时我们发现单旋转已经不能解决问题了, 如果只是在7和16之间左旋的话,15将成为16的右节点,这显然不符合二叉排序树的性质。

因此这里我们需要两次旋转,先在15和16之间进行一次右旋,右旋之后就满足了上文规律2)的条件,此时再进行一次左旋

现在我们再插入14, 跟上面情况类似,插入之后需要执行先右旋再左旋的操作

现在让我们再做个小结,

当我们插入新节点时,导致了原AVL树在节点 p 处不平衡,那么

3)如果添加的新节点是p的右儿子的左儿子, 则先在其右儿子和右儿子的左儿子之间实施一次右旋转, 再在p和其右儿子之间实施一次左旋转

3)如果添加的新节点是p的左儿子的右儿子, 则先在其左儿子和左儿子的右儿子之间实施一次左旋转, 再在p和其左儿子之间实施一次右旋转

再高度总结下: 同向时单旋转,异向时双旋转

原理就到这里了, 代码实现比较复杂,这里就不再写了,个人觉得没有必要,因为AVL树是最古老的平衡树, 我们了解其原理是为了下一步----更好的理解红黑树。

从零开始学算法---二叉平衡树(AVL树)的更多相关文章

  1. (4) 二叉平衡树, AVL树

    1.为什么要有平衡二叉树? 上一节我们讲了一般的二叉查找树, 其期望深度为O(log2n), 其各操作的时间复杂度O(log2n)同时也是由此决定的.但是在某些情况下(如在插入的序列是有序的时候), ...

  2. Algorithms: 二叉平衡树(AVL)

    二叉平衡树(AVL):   这个数据结构我在三月份学数据结构结构的时候遇到过.但当时没调通.也就没写下来.前几天要用的时候给调好了!详细AVL是什么,我就不介绍了,维基百科都有.  后面两月又要忙了. ...

  3. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  4. 二叉平衡树AVL的插入与删除(java实现)

    二叉平衡树 全图基础解释参考链接:http://btechsmartclass.com/data_structures/avl-trees.html 二叉平衡树:https://www.cnblogs ...

  5. 树-二叉平衡树AVL

    基本概念 AVL树:树中任何节点的两个子树的高度最大差别为1. AVL树的查找.插入和删除在平均和最坏情况下都是O(logn). AVL实现 AVL树的节点包括的几个组成对象: (01) key -- ...

  6. 高度平衡的二叉搜索树(AVL树)

    AVL树的基本概念 AVL树是一种高度平衡的(height balanced)二叉搜索树:对每一个结点x,x的左子树与右子树的高度差(平衡因子)至多为1. 有人也许要问:为什么要有AVL树呢?它有什么 ...

  7. 各种查找算法的选用分析(顺序查找、二分查找、二叉平衡树、B树、红黑树、B+树)

    目录 顺序查找 二分查找 二叉平衡树 B树 红黑树 B+树 参考文档 顺序查找 给你一组数,最自然的效率最低的查找算法是顺序查找--从头到尾挨个挨个遍历查找,它的时间复杂度为O(n). 二分查找 而另 ...

  8. AVL树(二叉平衡树)详解与实现

    AVL树概念 前面学习二叉查找树和二叉树的各种遍历,但是其查找效率不稳定(斜树),而二叉平衡树的用途更多.查找相比稳定很多.(欢迎关注数据结构专栏) AVL树是带有平衡条件的二叉查找树.这个平衡条件必 ...

  9. java项目---用java实现二叉平衡树(AVL树)并打印结果(详)(3星)

    package Demo; public class AVLtree { private Node root; //首先定义根节点 private static class Node{ //定义Nod ...

随机推荐

  1. Js/jquery常用

    id属性不能有空格 1. js判断checkebox是否被选中 var ischecked = document.getElementById("xxx").checked  // ...

  2. ProjectEuler 009题

    题目: A Pythagorean triplet is a set of three natural numbers, a b c, for which, a2 + b2 = c2 For exam ...

  3. rabbitMQ重复消费(结合死循环重发那一篇看)

    /** * 重复消费逻辑判断与处理 */ @Component public class RepeatMqConsumer { /** * 服务对象 */ private int count=1; @ ...

  4. 高德地图——骑行路线&骑行指定

    &plugin=AMap.Riding 也是[]中放json, 包含keyword和city,不能有途经1.骑行路线(关键字) <!DOCTYPE html> <html&g ...

  5. ffplay 播放网络摄像头视频

    shell脚本如下,无须加port ffplay rtsp://cameral_ip

  6. Learning ROS: rqt_console和rqt_logger_level使用

    rqt_console:操作.查看log信息 rqt_logger_level:设置log等级 打开node: rosrun rqt_console rqt_console rosrun rqt_lo ...

  7. AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)

    AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法) 我的依赖包的主要版本以及Redis依赖如下 1:添加依赖 <PackageReferen ...

  8. 【良心保姆级教程】java手把手教你用swing写一个学生的增删改查模块

    很多刚入门的同学,不清楚如何用java.swing去开发出一个系统? 不清楚如何使用java代码去操作数据库进行增删改查一些列操作,不清楚java代码和数据库(mysql.sqlserver)之间怎么 ...

  9. Python - 头部解析

    背景 写 python 的时候,基本都要加两个头部注释,这到底有啥用呢? #!usr/bin/env python # -*- coding:utf-8 _*- print("hello-w ...

  10. TypeScript 中命名空间与模块的理解?区别?

    一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...