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 点 链 重点! 树 树 简单, 线 ...
随机推荐
- Java+selenium之WebDriver的cookie,等待等高级操作(五)
1. 操作cookie // 增加一个 name = "name",value="value" 的 cookie Cookie cookie = new Coo ...
- 华硕X75VB安装ubuntu12.10网卡不可用等相关问题总结
笔记本相关信息: 电脑型号:华硕X75VB 笔记本电脑 处理器:i5-3230M 2.60GHz 双核 主板:华硕X75VB (英特尔 Ivy Bridge - HM76 Express芯片组) 内存 ...
- JAVA二分搜索树
二叉树: 和链表一样,动态数据结构. 二叉树具有唯一根节点 二叉树具有天然的递归结构 二分搜索树是二叉树 二分搜索树的每个节点的值: 1.大于其左子树的所有节点的值 2.小于其右子树的所有节点的值 每 ...
- 一脸懵逼学习Storm的搭建--(一个开源的分布式实时计算系统)
Storm的官方网址:http://storm.apache.org/index.html :集群部署的基本流程(基本套路): 集群部署的流程:下载安装包.解压安装包.修改配置文件.分发安装包.启动集 ...
- jquery.pjax 单页面, 无刷新打开页面.
介绍: pushState+ajax=pjax 工作原理: 什么是pjax? 现在很多网站(facebook, twitter)都支持这样的一种浏览方式, 当你点击一个站内的链接的时候, 不是做页面跳 ...
- table无法控制宽度
table-layout:fixed
- Centos6.5系统压力测试过程大量TIME_WAIT
统计tcp状态的命令: netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' netstat -n | awk '/ ...
- Codeforces 594D REQ 线段树
REQ 把询问离线, 我们从n 到 1遍历过去的时候, 把(1 - 1 / p)乘在最靠近当前位置的地方, 然后区间求乘积就好啦. #include<bits/stdc++.h> #def ...
- BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...
- L3-007 天梯地图 (30 分) dijkstra
本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至少存在一条可达路线. 输 ...