版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

一、平衡二叉树的定义

对一棵查找树(search tree)进行查询/新增/删除 等动作, 所花的时间与树的高度h 成比例, 并不与树的容量 n 成比例。如果可以让树维持矮矮胖胖的好身材, 也就是让h维持在O(lg n)左右, 完成上述工作就很省时间。能够一直维持好身材, 不因新增删除而长歪的搜寻树, 叫做balanced search tree(平衡树)。

【百度百科】平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。

平衡二叉树一般是一个有序树,它具有二叉树的所有性质,其遍历操作和二叉树的遍历操作相同。但是由于其对二叉树施加了额外限制,因而其添加、删除操作都必须保证平衡二叉树的因子被保持。

二、树的左旋和右旋是怎么玩的?

动图体会一下:参考自最容易懂得红黑树

左旋代码:

右旋代码:

三、节点失衡后的调整

平衡二叉树中引入了一个概念:平衡二叉树节点的平衡因子,它指的是该节点的两个子树,即左子树和右子树的高度差,即用左子树的高度减去右子树的高度,如果该节点的某个子树不存在,则该子树的高度为0,如果高度差的绝对值超过1就要根据情况进行调整。

平衡的调整共有四种情况:分别为LL,LR,RR,RL。

下面我们通过不断插入数据来说明几种不同的旋转方式:

注意:橘黄色的结点为旋转中心,黑色结点的为离插入结点最近的失衡结点。

(1)LR型

简单说明:最开始插入数据16,3,7后的结构如上图所示,结点16失去了平衡,3为16的左孩子,7为失衡结点的左孩子的右孩子,所以为LR型,接下来通过两次旋转操作复衡,先通过以3为旋转中心,进行左旋转,结果如图所示,然后再以7为旋转中心进行右旋转,旋转后恢复平衡了。

(2)LL型

简单说明:在上面恢复平衡后我们再次插入数据11和9,发现又失去平衡了,这次失衡结点是16,11是其左孩子,9为其失衡结点的左孩子的左孩子,所以是LL型,以失衡结点的左孩子为旋转中心进行一次右旋转即可。

(3)RR型

简单说明:进一步插入数据26后又再次失衡了,失衡结点为7,很明显这是RR型,以失衡结点的右孩子为旋转中心左旋转一次即可。

(4)RL型

再插入18后又再次失衡了,失衡结点为16,26为其右孩子,18为其右孩子的左孩子,为RL型,以失衡结点的右孩子为旋转中心,进行一次右旋转,然后再次已失衡结点的右孩子为旋转中心进行一次左旋转变恢复了平衡。

小总结:

这就是4种失衡后调整的旋转方式,其实只有两种,RR和LL,RL和LR本质上是一样的。下面我们再次插入数据14,15,完成我们最后数据的插入操作:

又是一次LR型,按前面操作就可以了。

四、应用场景

这个数据结构类似于双向链表,任意插入元素时都会自动排序,红黑树和平衡二叉树都使二叉树尽量平衡,从而使查询时和二分法类似。它适合的场合主要是:

  1. 需要时刻保证列表元素的有序排列;
  2. 需要频繁的增删和查询操作;
  3. 属于双向迭代器,不能随机访问任意元素;

五、总结

个人觉得,这一章还是比较难于理解的,失衡后如何进行旋转还需要结合图片细细体会。

平衡二叉树主要优点集中在快速查找。


我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!

参考资料:

  1. https://www.cnblogs.com/shixiangwan/p/7530015.html
  2. https://blog.csdn.net/wannuoge4766/article/details/83998377
  3. https://blog.csdn.net/qq_25940921/article/details/82183093
  4. https://blog.csdn.net/u014634338/article/details/42465089
  5. https://blog.csdn.net/sun_tttt/article/details/65445754
  6. https://blog.csdn.net/lemon_tree12138/article/details/50393548
  7. https://www.jianshu.com/p/4f3c8f134833
  8. https://blog.csdn.net/zxzxzx0119/article/details/80012812
  9. https://blog.csdn.net/buffoon1900/article/details/51330990

程序员的进阶课-架构师之路(9)-平衡二叉树(AVL树)的更多相关文章

  1. 程序员的进阶课-架构师之路(14)-B+树、B*树

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  2. 程序员的进阶课-架构师之路(13)-B-树

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  3. (转)致Java程序员:你离架构师还差多远?

    转至:https://blog.csdn.net/ityouknow/article/details/82782965 几乎每个Java程序员心中,都有着成为架构师的技术追求.那么,成为Java架构师 ...

  4. 从程序员到asp.net架构师转变[转]

    微软的DotNet开发绝对是属于那种入门容易提高难的技术.而要能够成为DotNet架构师没有三年或更长时间的编码积累基本上是不可能的.特别是在大型软件项目中,架构师是项目核心成员,承上启下,因此 RU ...

  5. 【转】java架构师之路:JAVA程序员必看的15本书的电子版下载地址

    作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...

  6. Java架构师之路:JAVA程序员必看的15本书

    作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...

  7. 高焕堂《android从程序员到架构师之路》 YY讲坛直面大师学习架构设计

    <android从程序员到架构师之路>YY讲坛活动:  sundy携手高焕堂老师全程YY答疑 与大师一起,分享android技术 时间:7月21日下午2:00   报名联系QQ:22243 ...

  8. 2017PHP程序员的进阶之路

    2017PHP程序员的进阶之路 又是一年毕业季,可能会有好多毕业生即将进入开发这个圈子,踏上码农这个不归路.根据这些年在开发圈子总结的LNMP程序猿发展轨迹,结合个人经验体会,总结出很多程序员对未来的 ...

  9. 【转】2017PHP程序员的进阶之路

    2017PHP程序员的进阶之路 又是一年毕业季,可能会有好多毕业生即将进入开发这个圈子,踏上码农这个不归路.根据这些年在开发圈子总结的LNMP程序猿发展轨迹,结合个人经验体会,总结出很多程序员对未来的 ...

随机推荐

  1. NodeJs 实现 WebSocket 即时通讯(版本二)

    服务端代码 websocket.js 'use strict' const WebSocket = require('ws'); const connections = new Map(); cons ...

  2. 超融合与传统IT架构对比:成本价格优势有哪些

    之前文章中,我们已经介绍了超融合给用户 IT 基础架构带来的各个方面的价值,其中成本只是超融合架构的优势之一.但很多用户还是会非常关心这个话题,希望能有更具体的了解,所以本文整理超融合和传统 FC S ...

  3. [翻译]Jupyter notebook .NET Core 内核预览1

    当您想到Jupyter Notebooks时,您可能会考虑使用Python,R,Julia或Scala而不是.NET编写代码. 今天,我们很高兴宣布您可以在Jupyter Notebooks中编写.N ...

  4. 第二十九章 System V共享内存

    共享内存数据结构 共享内存函数 shmget int shmget(key_t key, size_t size, int shmflg); 功能: 用于创建共享内存 参数: key : 这个共享内存 ...

  5. [考试反思]1106csp-s模拟测试103: 渺茫

    7点之前上不了博客,用gedit写的.谅解一下. 看起来不是特别惨?但是被sdfz爆踩了...而且其实并不能说“不是特别惨”吧90分算个啥啊?还凑不出个T2的AC难易度评估错误,T2是最简单的没看出来 ...

  6. Kubernetes3-kubectl管理Kubernetes容器平台-1

    一.简介 1.什么是kubectl kubectl前面其实已经用到了一些,它其实就是用于操作kubernetes集群的命令行接口,通过kubectl的各种命令实现各种功能 2.环境还是用上一偏文章 K ...

  7. Linux Shell | 解析xml节点

    01 xml文件 # user.xml <user> <name>Toy</name> <sex>man</sex> <room/&g ...

  8. R画图——分屏

    最近项目需求,用R画了一个九宫格的图,第一次画,将简化后的脚本呈现一下,不是有人说,既然做了,那就摆出来吧. *中文行为说明: args <- commandArgs(T) 调用命令行读取 fi ...

  9. go中的数据结构通道-channel

    1. channel的使用 很多文章介绍channel的时候都和并发揉在一起,这里我想把它当做一种数据结构来单独介绍它的实现原理. channel,通道.golang中用于数据传递的一种数据结构.是g ...

  10. 理解Spark SQL(一)—— CLI和ThriftServer

    Spark SQL主要提供了两个工具来访问hive中的数据,即CLI和ThriftServer.前提是需要Spark支持Hive,即编译Spark时需要带上hive和hive-thriftserver ...