平衡树

平衡树有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. 线程中的定时器Timer类

    Timer 定时器 几分钟之后执行一个任务. 创建了一个定时器相当于开启了一条线程,TimerTask相当于一个线程的任务.内部使用wait/notify机制来实现的. 用法非常的简单  就足以里面的 ...

  2. Redis笔记(4)独立功能的实现

    1.前言 本节记录一下redis的一些功能上的实现,包括发布订阅.事务.Lua脚本.排序.二进制位数组.慢查询日志和监视器. 2.发布订阅 上一章介绍sentinel的时候说到了sentinel会订阅 ...

  3. Android之混淆心得与亲身体验

    project.properties 中设置 proguard.config=proguard-project.txt proguard-project.txt  中设置 -optimizationp ...

  4. 【JAVA】枚举

    枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示. 1.常量的使用 在JDK1.5之前,我们定义常量都是:public ...

  5. Python基础之好玩的字符串格式化之类C风格

    今天白月黑羽和大家说说字符串格式化,在python3中,字符串格式化主要有2种方法,今天先和大家介绍类C风格的printf. printf 风格 这种方式 和 传统的C语言printf函数使用一样的格 ...

  6. hadoop家族成员

    1.概述 使用hadoop已经有一段时间了,从最开始懵懂到迷茫,再到各种阅读与写作,再到如今各种组合应用,逐渐已经离不开hadoop了,hadoop在大数据行业的成功,加速了它本身的发展,各大社区都能 ...

  7. javascript实现代码高亮-wangHighLighter.js

    1. 引言 (先贴出wangHighLighter.js的github地址:https://github.com/wangfupeng1988/wangHighLighter注意,程序和使用说明的更新 ...

  8. 记一次解决CSS定位bug思路

    事因 网站中的遮罩层大都有一个问题,就是在这个遮罩层中滑动,里面的内容也会跟着滑动,我是这样想的,既然都有这个问题,干脆写一个通用的插件出来,省的每个还得单独处理.如果是单独处理这个问题是比较好解决的 ...

  9. 通过公钥远程登录sshd认证

    一.root账号使用ssh-keygen 生成密匙 [root@vmware ~]# ssh-keygen Generating public/private rsa key pair. Enter ...

  10. Python制作回合制手游外挂简单教程(上)

    引入: 每次玩回合制游戏的时候,反反复复的日常任务让人不胜其烦 玩问道的时候,我们希望能够自动刷道,玩梦幻希望能自动做师门.捉鬼等等 说明: 该外挂只能模拟鼠标键盘操作,并不能修改游戏数据 我这里使用 ...