平衡树

平衡树有AVL树、红黑树、2-3树、2-3-4树

AVL树

AVL树是最早的一种平衡树,它以发明者的名字命名;AVL是一种特殊的二叉搜索树,平移保证二叉搜索树的正确。

特征

在AVL树中节点的左子树和右子树的高度差不会大于1

实现

在AVL树中每个节点都存储着一个额外的数据,它的左子树和右子树的高度差,这个差值不能大于1。
插入一个元素后,检查该元素所在的最低子树的根,如果它的子节点的高度相差大于1,执行一次或两次旋转使它们的高度相等;然后接着检查上面的节点,必要时均衡高度;这个检测一直向上,直到根为止。

旋转

右旋,顶端节点必须有一个左子节点,否则将没有节点代替原来的顶端节点;反之亦然。只要一个节点的左边有很多子孙节点而右边没有这么多节点,右旋;反之亦然。

1、单旋转——右旋1

a图是一个正确的AVL树,节点50的右子树高度为0,左子树的高度为1,差值不大于1
b图插入一个节点30后,整个树不平衡了。右旋,以节点50为顶端节点做右旋,节点50下降,节点40上升,节点30跟随着上升
c图是旋转后的样子

2、单旋转——右旋2

a图是一个正确的AVL树,节点50的右子树高度为1,左子树的高度为2,差值不大于1
b图插入一个节点5后,整个树不平衡了。右旋,以节点50为顶端节点做右旋,节点50下降,节点70跟随着下降;节点20上升,节点10、节点5跟随着上升;但节点30要平移
c图是旋转后的样子
注意:顶端节点的内侧子孙要做平移。如果顶端节点的内侧子孙是一颗树,旋转不会改变该子树中节点的关系,整体跟着平移就好了。

3、双旋转——左-右双旋转

a图是一个正确的AVL树,节点50的右子树高度为0,左子树的高度为1,差值不大于1
b图插入一个节点30后,整个树不平衡了。
c假如对b图做右旋,以节点50为顶端节点做右旋,节点50下降;节点20上升;但节点30要平移——这样就产生了c图,但c图还是不平衡,所以不能这么做
d正确的做法是,对b图以节点20做为顶端节点先做一次左旋,这次左旋后的样子如d图,还不平衡;
e再右旋,以节点50为顶端节点做右旋,结果如e图

a图是一个正确的AVL树,节点50的右子树高度为1,左子树的高度为2,差值不大于1
b图插入一个节点25后,整个树不平衡了。先左旋,以节点20为顶端节点做左旋,节点20下降,节点10跟随着下降;节点30上升;但节点25要平移
c图是第一次左旋后的样子,还不平衡;再右旋,以节点50为顶端节点做右旋
d图是旋转好的样子
注意:当新节点添加到内侧时,要做两次旋转;当新节点添加到了外侧时,只做一次旋转即可,如右旋1和右旋2

旋转总结

左-右双旋转举了两个例子。以上三种旋转包含了所有的旋转,只是对应的还有左旋、左旋2、右-左双旋转。

效率

AVL树的层数最多是Log2(N+1)+1,查找时间最差需要Log2(N+1)+1次比较,大约O(logN)。

插入或删除也大约需要O(logN)的时间。插入或删除一个节点时需要扫描两趟,一次向下查找插入点,一次向上平衡树,所以不如红黑树效率高。

平衡树、AVL树的更多相关文章

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

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

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

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

  3. 二叉查找树,AVL树,伸展树【CH4601普通平衡树】

    最近数据结构刚好看到了伸展树,在想这个东西有什么应用,于是顺便学习一下. 二叉查找树(BST),对于树上的任意一个节点,节点的左子树上的关键字都小于这个节点的关键字,节点的右子树上的关键字都大于这个节 ...

  4. 平衡树以及AVL树

    平衡树是计算机科学中的一类数据结构. 平衡树是计算机科学中的一类改进的二叉查找树.一般的二叉查找树的查询复杂度是跟目标结点到树根的距离(即深度)有关,因此当结点的深度普遍较大时,查询的均摊复杂度会上升 ...

  5. Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现

    AVL 平衡树和树旋转 目录 AVL平衡二叉树 树旋转 代码实现 1 AVL平衡二叉树 AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实 ...

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

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

  7. 从零开始学算法---二叉平衡树(AVL树)

    先来了解一些基本概念: 1)什么是二叉平衡树? 之前我们了解过二叉查找树,我们说通常来讲, 对于一棵有n个节点的二叉查找树,查询一个节点的时间复杂度为log以2为底的N的对数. 通常来讲是这样的, 但 ...

  8. 树-二叉平衡树AVL

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

  9. 【数据结构06】二叉平衡树(AVL树)

    目录 一.平衡二叉树定义 二.这货还是不是平衡二叉树? 三.平衡因子 四.如何保持平衡二叉树平衡? 五.平衡二叉树插入节点的四种情况 六.平衡二叉树操作的代码实现 七.AVL树总结 @ 一.平衡二叉树 ...

随机推荐

  1. StringBuffer、StringBuilder、冒泡与选择排序、二分查找、基本数据类型包装类_DAY13

    1:数组的高级操作(预习) (1)数组:存储同一种数据类型的多个元素的容器. (2)特点:每个元素都有从0开始的编号,方便我们获取.专业名称:索引. (3)数组操作: A:遍历 public stat ...

  2. C++:运算符重载

    运算符重载是一种形式的C++多态.运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义.实际上,很多C++运算符已经被重载.eg:将*运算符用于地址,将得到存储在这个地址中的值,将他用于 ...

  3. 五、CLR加载程序集代码时,JIT编译器对性能的产生的影响

    1.CLR首次加载代码造成的性能损失 四.CLR执行程序集中代码介绍了CLR在首次执行一个类的时,会初始化一个内部结构,然后当目标方法被首次调用时,JITComplier函数(JIT编译器)会验证IL ...

  4. StreamSets学习系列之StreamSets支持多种安装方式【Core Tarball、Cloudera Parcel 、Full Tarball 、Full RPM 、Docker Image和Source Code 】(图文详解)

    不多说,直接上干货! Streamsets的官网 https://streamsets.com/ 得到 https://streamsets.com/opensource/ StreamSets支持多 ...

  5. mysql5.7主从复制配置——读写分离实现

    为什么使用主从架构?1.实现服务器负载均衡:2.通过复制实现数据的异地备份:3.提高数据库系统的可用性:4.可以分库[垂直拆分],分表[水平拆分]: 主从配置的前提条件1.MySQL版本一致:2.My ...

  6. 和我一起打造个简单搜索之ElasticSearch入门

    本文简单介绍了使用 Rest 接口,对 es 进行操作,更深入的学习,可以参考文末部分. 环境 本文以及后续 es 系列文章都基于 5.5.3 这个版本的 elasticsearch ,这个版本比较稳 ...

  7. Mysql字符串转换为整型

    使用Convert(字段名, 类型)方法 SELECT CONVERT(filedName, UNSIGNED INTEGER) ;

  8. [Python学习笔记-003] 使用PyOTP获取基于OTOP算法的动态口令

    建立安全的VPN连接,不仅需要输入用户名和密码,还需要输入动态口令(token).作为一个懒人,我更喜欢什么手工输入都不需要,既不需要输入password,也不需要输入token.也就是说,只需一个命 ...

  9. IDEA SQL dialect detection和Duplicated Code检测关闭

    IDEA似乎做的太多,对于Mybatis文件中的SQL语法检查可能就没有太大的必要性,Duplicated Code检测其实非常好,但是我测试使用JDBC代码的时候一堆波浪线让我很不舒服 因此将这两个 ...

  10. Solidity数组

    一.固定长度的数组(Arrays) 1.固定长度类型数组的声明 pragma solidity ^0.4.4; contract C { // 数组的长度为5,数组里面的存储的值的类型为uint类型 ...