AVL树的理解及自写AVL树
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者G.M. Adelson-Velsky和E.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树的更多相关文章
- 手写AVL 树(下)
上一篇 手写AVL树上实现了AVL树的插入和查询 上代码: 头文件:AVL.h #include <iostream> template<typename T1,typename T ...
- 数据结构图解(递归,二分,AVL,红黑树,伸展树,哈希表,字典树,B树,B+树)
递归反转 二分查找 AVL树 AVL简单的理解,如图所示,底部节点为1,不断往上到根节点,数字不断累加. 观察每个节点数字,随意选个节点A,会发现A节点的左子树节点或右子树节点末尾,数到A节点距离之差 ...
- 常见基本数据结构——树,二叉树,二叉查找树,AVL树
常见数据结构——树 处理大量的数据时,链表的线性时间太慢了,不宜使用.在树的数据结构中,其大部分的运行时间平均为O(logN).并且通过对树结构的修改,我们能够保证它的最坏情形下上述的时间界. 树的定 ...
- 手写AVL平衡二叉搜索树
手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...
- 平衡二叉查找树(AVL)的理解与实现
AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...
- [BinaryTree] AVL树、红黑树、B/B+树和Trie树的比较
转自:AVL树.红黑树.B/B+树和Trie树的比较 AVL树 最早的平衡二叉树之一.AVL是一种高度平衡的二叉树,所以通常的结果是,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应 ...
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- 【面试普通人VS高手系列】b树和b+树的理解
数据结构与算法问题,困扰了无数的小伙伴. 很多小伙伴对数据结构与算法的认知有一个误区,认为工作中没有用到,为什么面试要问,问了能解决实际问题? 图灵奖获得者: Niklaus Wirth 说过: 程序 ...
- 瞎写的树dfs序
这里枚举了树的DFS序来解决树上问题的多个板子,自己最好多看看. ↓改↓ ↓求↓ 点 点 ————————>>>这个就算了 点 树 简单, BIT 点 链 重点! 树 树 简单, 线 ...
随机推荐
- js两种写法执行速度比较
记录 function test1(){ this.say = function(){} } function test2(){ this.say = function(){} return this ...
- 根据ip地址获得国家和城市(C#)
/// <summary> /// get country and city /// </summary> /// <param name="ip"& ...
- Idea和PyCharm激活破解
1. 先去百度去官网下载专业版IDE, Idea 和PyCharm激活方法一样 2. 下载破解包, 点击下载 3. 将下载的jar包放到这个安装目录的bin目录下面 4. 在bin目录下面的文件pyc ...
- github.com加速节点
github.com加速节点 192.30.253.118 github.com192.30.253.119 github.com93.46.8.89 github.com
- js中匿名函数和回调函数
匿名函数: 通过这种方式定义的函数:(没有名字的函数) 作用:当它不被赋值给变量单独使用的时候 1.将匿名函数作为参数传递给其他函数 2.定义某个匿名函数来执行某些一次性任务 var f = func ...
- 一脸懵逼加从入门到绝望学习hadoop之Caused by: java.net.UnknownHostException: master报错
windows下开发hadoop应用程序,hadoop部署在linux环境中, 在运行调试时可能会出现无法找到主机,类似异常信息如下: java.net.UnknownHostException: u ...
- 封装curl的get和post请求
/** * GET 请求 * @param string $url */ function http_get($url){ $oCurl = curl_init(); if(stripos($url, ...
- Python初次安装使用教程
Python官网: https://www.python.org/downloads/ 当前版本为3.7.0 下载(64位系统)exe文件进行安装. 双击安装运行 选择自定义安装路径 ...
- skyline添加wfs服务时,弹出错误“no layers were found”!
1.问题描述: 使用TerraExplorer Pro添加ArcGIS Server 10.2发布的WFS服务图层时,弹出如下错误: 2.错误原因: 发布wfs服务前,图层数据源的空间参考未设置,不能 ...
- 今天开始学习php,粘一些重点放这以便查看记忆。
1.PHP的变量用$定义. PHP 将所有全局变量存储在一个名为 $GLOBALS[index] 的数组中. index 保存变量的名称.这个数组可以在函数内部访问,也可以直接用来更新全局变量. 2. ...