AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者G.M. Adelson-VelskyE.M. Landis,他们在1962年的论文《An algorithm for the organization of information》中发表了它。

节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子1、0或 -1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。

AVL树的基本操作一般涉及运作同在不平衡的二叉查找树所运作的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL旋转"。

以上内容转自维基百科AVL树

从图中可以比较形象的看出所谓左旋右旋的旋转支点是三个主节点中大小居中的那个节点,左旋就是左边的节点降下来,右旋就是右边的节点降下来,都成为中间节点的子树。

左右双旋分解就是先将左侧节点降为左子树,右边节点将为右子树。当然中间有合并子树的过程,这里没有细说。

高度为h的AVL树,节点数N最多; 最少 ( 其中 )N是h的斐波那契数列。

 
//定义节点
class AvlNode{
int val;
AvlNode left;
AvlNode right;
int height;
public AvlNode(int val,AvlNode left,AvlNode right){
this.val=val;
this.left=left;
this.right=right;
this.height=0;
}
public AvlNode(int val){
this(val,null,null);
}
}
public class AVLTree {
private static final int COUNT=1;
//判断高度
private static int height(AvlNode t) {
// TODO Auto-generated method stub
return t==null?-1:t.height;
}
//节点的插入
public static AvlNode insert(Integer val,AvlNode t){ if(t==null){
return new AvlNode(val);
}
int result=val.compareTo(t.val);
if(result<0){
t.left=insert(val, t.left);
}
else if(result>0){
t.right=insert(val, t.right);
}else{
;
}
//其余按照普通的二叉查找树来写,最后加一个平衡方法
return balance(t);
}
//删除方法,选择了一种比较简单的,在删除之后重新调整树
public static AvlNode remove(Integer x,AvlNode t){
if(t==null){
return null;
}
int result=x.compareTo(t.val);
if(result<0){
t.left=remove(x, t.left);
}else if(result>0){
t.right=remove(x,t.right);
}
else if(t.left!=null&&t.right!=null){
t.val=findMin(t.right).val;
t.right=remove(t.val,t.right);
}else{
t=(t.left!=null)?t.left:t.right;
}
return balance(t);
} private static AvlNode findMin(AvlNode t) {
if(t==null){
return null;
}else if(t.left==null){
return t;
}
return findMin(t.left);
}
//平衡方法
private static AvlNode balance(AvlNode t) {
// TODO Auto-generated method stub
//判断是哪种情况
//如果是左左情况或者是左右情况
if(height(t.left)-height(t.right)>COUNT){
if(height(t.left.left)-height(t.right.right)>COUNT){
//左左情况进行右旋
t=rightSpin(t);
}else{
//右左情况先左旋后右旋
t=leftrightSpin(t);
} }
//如果是右右情况或者是右左情况
else if(height(t.right)-height(t.left)>COUNT){
if(height(t.right.right)-height(t.right.left)>COUNT){
//右右情况进行左旋
t=leftSpin(t);
}else{
//右左情况先右旋再左旋
t=rightleftSpin(t);
}
}
return null;
}
private static AvlNode rightleftSpin(AvlNode t) {
t.right=rightSpin(t.right);
return leftSpin(t);
}
private static AvlNode leftrightSpin(AvlNode t) {
t.left=leftSpin(t.left);
return rightSpin(t);
}
private static AvlNode leftSpin(AvlNode t) {
AvlNode t1=t.right;
t.right=t1.left;
t1.left=t;
t1.height=Math.max(height(t1.left), height(t1.right))+1;
t.height=Math.max(height(t.left),height(t.right));
return t1;
}
private static AvlNode rightSpin(AvlNode t) {
AvlNode t1=t.left;
t.left=t1.right;
t1.right=t;
t1.height=Math.max(height(t1.left), height(t1.right))+1;
t.height=Math.max(height(t.left),height(t.right));
return t1;
} }

AVL树的理解及自写AVL树的更多相关文章

  1. 手写AVL 树(下)

    上一篇 手写AVL树上实现了AVL树的插入和查询 上代码: 头文件:AVL.h #include <iostream> template<typename T1,typename T ...

  2. 数据结构图解(递归,二分,AVL,红黑树,伸展树,哈希表,字典树,B树,B+树)

    递归反转 二分查找 AVL树 AVL简单的理解,如图所示,底部节点为1,不断往上到根节点,数字不断累加. 观察每个节点数字,随意选个节点A,会发现A节点的左子树节点或右子树节点末尾,数到A节点距离之差 ...

  3. 常见基本数据结构——树,二叉树,二叉查找树,AVL树

    常见数据结构——树 处理大量的数据时,链表的线性时间太慢了,不宜使用.在树的数据结构中,其大部分的运行时间平均为O(logN).并且通过对树结构的修改,我们能够保证它的最坏情形下上述的时间界. 树的定 ...

  4. 手写AVL平衡二叉搜索树

    手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...

  5. 平衡二叉查找树(AVL)的理解与实现

    AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...

  6. [BinaryTree] AVL树、红黑树、B/B+树和Trie树的比较

    转自:AVL树.红黑树.B/B+树和Trie树的比较 AVL树 最早的平衡二叉树之一.AVL是一种高度平衡的二叉树,所以通常的结果是,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应 ...

  7. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  8. 【面试普通人VS高手系列】b树和b+树的理解

    数据结构与算法问题,困扰了无数的小伙伴. 很多小伙伴对数据结构与算法的认知有一个误区,认为工作中没有用到,为什么面试要问,问了能解决实际问题? 图灵奖获得者: Niklaus Wirth 说过: 程序 ...

  9. 瞎写的树dfs序

    这里枚举了树的DFS序来解决树上问题的多个板子,自己最好多看看. ↓改↓ ↓求↓ 点 点 ————————>>>这个就算了 点 树 简单, BIT 点 链 重点! 树 树 简单, 线 ...

随机推荐

  1. 步步為營-96-MyMVC2

    說明:地址欄中的URL還存在一些不足之處 地址欄中最好能是http"www.sss.com/asdf/aaa 1.1 模擬路由的原理:創建Routing文件夾,并添加URLRoutingMo ...

  2. bootstrap的模拟单选按钮

    <div class="btn-group" data-toggle="buttons" id="radio"> <lab ...

  3. K3 WISE 开发插件《SQL语句WHERE查询-范围查询/模糊查询》

    0.存储过程开头变量定义 @FBeginDate varchar(10), --单据起始日期 @FEndDate varchar(10), --单据截止日期. @FItemID varchar(50) ...

  4. SQLServer锁的基础问题探究

    SqlServer需要在执行操作前对目标资源获取所有权,那么久发生锁定,是一个逻辑概念.为了保证事务的ACID特性设计的一种机制. 在多用户并发操作数据时,为了出现不一致的数据,锁定是必须的机制.使用 ...

  5. 升级到 Android Studio 3.0 + Gradle 4.1 遇到的一些坑及解决方案

    问题一: Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkD ...

  6. Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、

    1:Scala之函数式编程学习笔记: :Scala函数式编程学习: 1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法: class User { private ...

  7. Redis监控和告警

    https://blog.csdn.net/isoleo/article/details/52981140

  8. Pytorch LSTM 词性判断

    首先,我们定义好一个LSTM网络,然后给出一个句子,每个句子都有很多个词构成,每个词可以用一个词向量表示,这样一句话就可以形成一个序列,我们将这个序列依次传入LSTM,然后就可以得到与序列等长的输出, ...

  9. console输出彩色字体

    console.log("%c%s","color: red; background: yellow; font-size: 24px;","警告!& ...

  10. Spring Security 架构与源码分析

    Spring Security 主要实现了Authentication(认证,解决who are you? ) 和 Access Control(访问控制,也就是what are you allowe ...