AVL 平衡树
AVL是一种平衡二叉树,它通过对二叉搜索树中的节点进行旋转使得二叉搜索树达到平衡。AVL在所有的平衡二叉搜索树中具有最高的平衡性。
定义
平衡二叉树或者为空树或者为满足如下性质的二叉搜索树:
- 左右子树的高度之差绝对值不超过1
- 左右子树仍然为平衡二叉树
定义平衡因子 BF(x) = x的左子树高度 - x的右子树的高度。平衡二叉树的每个节点的平衡因子只能为-1, 0, 1.
维持平衡思想
若二叉树当前为平衡状态,此时插入/删除一个新的节点,此时有可能造成二叉树不满足平衡条件,此时需要通过对节点进行旋转来使得二叉树达到平衡状态。从被插入/删除的节点开始向上查找,找到第一个不满足 |BF| <= 1的祖先节点P,此时对P和P的子节点(或P的子节点的子节点)进行旋转(可能分为下面的四种情况)。
旋转
(1)LL型平衡旋转法
由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行一次顺时针旋转操作。 即将A的左孩子B向右上旋转代替A作为根结点,A向右下旋转成为B的右子树的根结点。而原来B的右子树则变成A的左子树。 
(2)RR型平衡旋转法
由于在A的右孩子C 的右子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行一次逆时针旋转操作。即将A的右孩子C向左上旋转代替A作为根结点,A向左下旋转成为C的左子树的根结点。而原来C的左子树则变成A的右子树。 
(3)LR型平衡旋转法
由于在A的左孩子B的右子数上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行两次旋转操作(先逆时针,后顺时针)。即先将A结点的左孩子B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。即先使之成为LL型,再按LL型处理。
如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为LL型,再按LL型处理成平衡型。
(4)RL型平衡旋转法
由于在A的右孩子C的左子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行两次旋转操作(先顺时针,后逆时针),即先将A结点的右孩子C的左子树的根结点D向右上旋转提升到C结点的位置,然后再把该D结点向左上旋转提升到A结点的位置。即先使之成为RR型,再按RR型处理。
如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为RR型,再按RR型处理成平衡型。
实现(c++)
#include<iostream>
using namespace std;
#define MAX(a, b) a > b? a:b
struct TreeNode{
int data;
TreeNode* child[2];
int size;
int height;
int count;
TreeNode(int val){
data = val;
size = count = height = 1;
child[0] = child[1] = NULL;
}
void Update(){
size = count;
height = 1;
if (child[0]){
size += child[0]->size;
height = MAX(height, 1 + child[0]->height);
}
if (child[1]){
size += child[1]->size;
height = MAX(height, 1 + child[1]->height);
}
}
}; struct AVL{
TreeNode* root;
AVL() :root(NULL){}; int GetHeight(TreeNode* node){
if (!node)
return 0;
return node->height;
}
int GetSize(TreeNode* node){
if (!node)
return 0;
return node->size;
} //注意这里使用指针的引用
void Rotate(TreeNode*& node, int dir){
TreeNode* ch = node->child[dir];
node->child[dir] = ch->child[!dir];
ch->child[!dir] = node;
node->Update();
node = ch;
}
void Maintain(TreeNode*& node){
if (!node){
return;
}
int bf = GetHeight(node->child[0]) - GetHeight(node->child[1]);
if (bf >= -1 && bf <= 1){
return;
}
if (bf == 2){
int bf2 = GetHeight(node->child[0]->child[0]) - GetHeight(node->child[0]->child[1]);
if (bf2 == 1){ //左左旋转
Rotate(node, 0);
}
else if (bf2 == -1){ //左右旋转
Rotate(node->child[0], 1);
Rotate(node, 0);
}
}
else if (bf == -2){
int bf2 = GetHeight(node->child[1]->child[0]) - GetHeight(node->child[1]->child[1]);
if (bf2 == 1){ //右左旋转
Rotate(node, 1);
}
else if (bf2 == -1){ //右右旋转
Rotate(node->child[1], 0);
Rotate(node, 1);
}
} }
void Insert(TreeNode*& node, int val){
if (!node){
node = new TreeNode(val);
}
else if (node->data == val){
node->count++;
}
else{
int dir = node->data < val;
Insert(node->child[dir], val);
}
//维持树的平衡
Maintain(node);
//更新节点
node->Update();
} //注意参数为指针的引用
void Delete(TreeNode*& node, int val){
if (!node){
return;
}else if (node->data == val){
if (node->child[0] && node->child[1]){
int dir = GetHeight(node->child[0]) < GetHeight(node->child[1]);
//将子树中较高的那棵,旋转
Rotate(node, dir);
//递归调用delete,直到叶子节点才进行真正的删除
Delete(node->child[! dir], val);
}
else{
TreeNode* tmp_node = NULL;
if (node->child[0]){
tmp_node = node->child[0];
}
else if (node->child[1]){
tmp_node = node->child[1];
}
delete node;
node = tmp_node; //使用引用
}
}
else{
int dir = node->data < val;
Delete(node->child[dir], val);
}
Maintain(node); //维持平衡
node->Update(); //更新节点
}
int GetKth(TreeNode* node, int k){
while (node){
if (! node->child[0]){
if (k <= node->count){
return node->data;
}
else{
k -= node->count;
node = node->child[1];
}
}
else{
if (node->child[0]->size < k && node->child[0]->size + node->count >= k){
return node->data;
}
else if (node->child[0]->size > k){
node = node->child[0];
}
else{
k -= (node->child[0]->size + node->count);
node = node->child[1];
}
}
}
return -1;
}
};
参考:
平衡树 balanced binary tree (AVL tree)
AVL树 模板
AVL 平衡树的更多相关文章
- 实现Avl平衡树
实现Avl平衡树 一.介绍 AVL树是一种自平衡的二叉搜索树,它由Adelson-Velskii和 Landis于1962年发表在论文<An algorithm for the organi ...
- Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现
AVL 平衡树和树旋转 目录 AVL平衡二叉树 树旋转 代码实现 1 AVL平衡二叉树 AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实 ...
- 数据结构学习-AVL平衡树
环境:C++ 11 + win10 IDE:Clion 2018.3 AVL平衡树是在BST二叉查找树的基础上添加了平衡机制. 我们把平衡的BST认为是任一节点的左子树和右子树的高度差为-1,0,1中 ...
- AVL平衡树的插入例程
/* **AVL平衡树插入例程 **2014-5-30 11:44:50 */ avlTree insert(elementType X, avlTree T){ if(T == NULL){ T = ...
- AVL平衡树(非指针实现)
看了网上三四篇博客,学习了AVL树维护平衡的方式.但感觉他们给出的代码都有一点瑕疵或者遗漏,懂得了思想之后,花了一些时间把他们几篇的长处结合起来,没有使用指针,实现了一下.每个小逻辑功能都抽象成了函数 ...
- 数据结构——AVL平衡树
1.是二叉搜索树(Binary Search Tree) 2.树和所有左右子树高度之差为-1,0,1 平衡因子(balance factor) =右子树高度-左子树高度 平衡化旋转: 1.从插入位置向 ...
- My implementation of AVL tree
C++实现的avl平衡树 #include <stdlib.h> #include <time.h> #include <string.h> #include &l ...
- [SinGuLaRiTy] 平衡树
[SinGuLaRiTy-1009] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 二叉查找树 二叉查找树是指具有下列性质的非空二叉树: ⑴ ...
- 数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作
AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上 ...
随机推荐
- 【转】【C#】实现依赖注入
1. 问题的提出 开发中,尤其是大型项目的开发中,为了降低模块间.类间的耦合关系,比较提倡基于接口开发,但在实现中也必须面临最终是“谁”提供实体类的问题.Martin Fowler在<Inver ...
- JAVA String.format 方法使用介绍<转>
在JDK1.5中,String类增加了一个非常有用的静态函数format(String format, Objece... argues),可以将各类数据格式化为字符串并输出.其中format参数 ...
- Android——TextView属性XML详解
Android_TextView属性XML详解 博客分类: android 属性名称 描述 android:autoLink 设置是否当文本为URL链接/email/电话号码/map时 ...
- Node.js连接postgres
一.下载Node.js postgres驱动 Node.js里面没有postgres模块的,我们需要安装node-postgres模块. node-postgres模块的下载地址为:https://g ...
- ionic2 生命周期
在 Ionic 2 的版本中生命周期命名的改变,以及各个事件的解释. 官方文档地址在 这里 . 事件名称 事件说明 ionViewLoaded 页面加载完毕触发.该事件发生在页面被创建成 DOM 的时 ...
- R语言--saprkR基本使用
1.在sparkR的shell中交互式使用 sparkR --masterspark://10.130.2.20:7077 sparkR --masterlocal[6] #sparkR --mast ...
- ES学习2
1:es中的分页 一般搜索引擎中的分页都不会提供很大的页面查询,因为查询的页码越大,查询效率越低. 例子: 我们就先预想一下我们在搜索一个拥有5个主分片的索引.当我们请求第一页搜索的时 候,每个分片产 ...
- (转)x264 编码流程
转自:http://alphamailpost.blog.163.com/blog/static/20111808120128111160728/ http://www.usr.cc/thread-5 ...
- ASP.NET WebApi 路由配置【转】
一.路由介绍 ASP.NET Web API路由是整个API的入口.我们访问某个资源就是通过路由映射找到对应资源的URL.通过URL来获取资源的. 对于ASP.NET Web API内部实现来讲,我们 ...
- UGUI之Canvas Group
可以通过Canvas Group影响该组UI元素的部分性质,而不需要费力的对该组UI下的每个元素逐个调整.Canvas Group是同时作用于该组UI下的全部元素. 参数:Alpha:该组UI元素的透 ...