AVL树(命名来源于作者姓名,Adelson-Velskii和Landis),即平衡二叉树,满足以下的条件:

1)它的左子树和右子树都是AVL树

2)左子树和右子树的高度差不能超过1

从条件1可能看出是个递归定义。

AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。

AVL树插入节点的步骤,分为2类:

第1类:外侧插入,单旋转

第2类:内侧插入,双旋转(先旋转成外侧插入的情况,再单旋转)

由于调整以后,树高与插入前是相同的,所以无需再向上查看balance情况

代码实现:http://blog.chinaunix.net/uid-20662820-id-142440.html

struct node
{
node* parent;
node* left;
node* right;
int balance; //左右子树高度之差
int key;
}; int searchNode(int key, node* root, node** parent) //如果没找到,parent也是指向要插入位置的父位置
{
node* temp;
assert(root != NULL);
temp = root;
*parent = root->parent;
while (temp !=NULL)
{
if (temp->key == key)
return ;
else
{
*parent = temp;
if (temp->key > key)
temp = temp->left;
else
temp = temp->right;
}
}
return ;
} node* adjustAVL(node* root, node* parent, node* child)
{
node *cur;
assert((parent != NULL)&&(child != NULL));
switch (parent->balance)
{
case :
if (child->balance == -)//LR型(内侧插入):插入的节点的父节点直接升级做parent
{
cur = child->right;
cur->parent = parent->parent;
child->right = cur->left;
if (cur->left != NULL)
cur->left->parent = child;
parent->left = cur->right;
if (cur->right != NULL)
cur->right->parent = parent;
cur->left = child;
child->parent = cur;
cur->right = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = cur;
else parent->parent->right = cur;
else
root = cur;
parent->parent = cur;
if (cur->balance == )
{
parent->balance = ;
child->balance = ;
}
else if (cur->balance == -)
{
parent->balance = ;
child->balance = ;
}
else
{
parent->balance = -;
child->balance = ;
}
cur->balance = ;
}
else //LL型(外侧插入):插入的节点的父节点升级做child,child升级做parent
child->parent = parent->parent;
parent->left = child->right;
if (child->right != NULL)
child->right->parent = parent;
child->right = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = child;
else parent->parent->right = child;
else
root = child;
parent->parent = child;
if (child->balance == ) //插入时
{
child->balance = ;
parent->balance = ;
}
else //删除时
{
child->balance = -;
parent->balance = ;
}
}
break; case -:
if (child->balance == ) //RL型
{
cur = child->left;
cur->parent = parent->parent;
child->left = cur->right;
if (cur->right != NULL)
cur->right->parent = child;
parent->right = cur->left;
if (cur->left != NULL)
cur->left->parent = parent;
cur->left = parent;
cur->right = child;
child->parent = cur;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = cur;
else parent->parent->right = cur;
else
root = cur;
parent->parent = cur;
if (cur->balance == )
{
parent->balance = ;
child->balance = ;
}
else if (cur->balance == )
{
parent->balance = ;
child->balance = -;
}
else
{
parent->balance = ;
child->balance = ;
}
cur->balance = ;
}
else //RR型
{
child->parent = parent->parent;
parent->right = child->left;
if (child->left != NULL)
child->left->parent = parent;
child->left = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = child;
else parent->parent->right = child;
else
root = child;
parent->parent = child;
if (child->balance == -) //插入时
{
child->balance = ;
parent->balance = ;
}
else //删除时
{
child->balance = ;
parent->balance = -;
}
}
break;
}
return root;
} node* insertNode(int key, node* root)
{
node *parent, *cur, *child;
assert (root != NULL);
if (searchNode(key, root, &parent)) //结点已存在
return root;
else
{
cur = (node*)malloc(sizeof(node));
cur->parent = parent;
cur->key = key;
cur->left = NULL;
cur->right = NULL;
cur->balance = ;
if (keykey)
{
parent->left = cur;
child = parent->left;
}
else
{
parent->right = cur;
child = parent->right;
} while ((parent != NULL)) //查找需要调整的最小子树
{
if (child == parent->left)
if (parent->balance == -)
{
parent->balance = ;
return root;
}
else if (parent->balance == )
{
parent->balance = ;
break;
}
else
{
parent->balance = ;
child = parent;
parent = parent->parent;
}
else if (parent->balance == ) //是右孩子,不会引起不平衡
{
parent->balance = ;
return root;
}
else if (parent->balance == -) //是右孩子,并且引起parent的不平衡
{
parent->balance = -;
break;
}
else //是右孩子,并且可能引起parent的parent的不平衡
{
parent->balance = -;
child = parent;
parent = parent->parent;
}
} if (parent == NULL)
return root;
return adjustAVL(root, parent, child);
}
}

平衡二叉树之AVL树的更多相关文章

  1. 【Java】 大话数据结构(12) 查找算法(3) (平衡二叉树(AVL树))

    本文根据<大话数据结构>一书及网络资料,实现了Java版的平衡二叉树(AVL树). 平衡二叉树介绍 在上篇博客中所实现的二叉排序树(二叉搜索树),其查找性能取决于二叉排序树的形状,当二叉排 ...

  2. Java数据结构(十四)—— 平衡二叉树(AVL树)

    平衡二叉树(AVL树) 二叉排序树问题分析 左子树全部为空,从形式上看更像一个单链表 插入速度没有影响 查询速度明显降低 解决方案:平衡二叉树 基本介绍 平衡二叉树也叫二叉搜索树,保证查询效率较高 它 ...

  3. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  4. 数据结构之平衡二叉树(AVL树)

    平衡二叉树(AVL树)定义如下:平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树: (1)它的左子树和右子树的高度之差绝对值不超过1: (2)它的左子树和右子树都是平衡二叉树. AVL树避免了 ...

  5. 二叉树学习笔记之经典平衡二叉树(AVL树)

    二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...

  6. 一步一步写平衡二叉树(AVL树)

    平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...

  7. 平衡二叉树(AVL树)

    参考资料 http://www.cnblogs.com/Cmpl/archive/2011/06/05/2073217.html http://www.cnblogs.com/yc_sunniwell ...

  8. 算法与数据结构(十一) 平衡二叉树(AVL树)(Swift版)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  9. 经典平衡二叉树(AVL树)

    二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...

随机推荐

  1. Portainer docker 可视化管理工具

    1. 快速使用 docker run -d -p 9000:9000 portainer/portainer 2. docker  swarm  模式 docker service create \ ...

  2. Spring boot admin 使用

    1. maven依赖 <dependencies> <dependency> <groupId>org.springframework.boot</group ...

  3. 使用Apache Archiva管理Maven仓库

    1 . 私服简介 私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件.有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库:否则,私服请求外部 ...

  4. wordpress域名解析到了网站,但是点击其他页面会出现ip而不是域名

         1.前提域名可以访问你的网站证明解析没问题 2.那就是wp后台的设置问题,将url和站点url改为你的域名http://www.eovision.cc清理缓存即可 亲测可用,如果改了出现页面 ...

  5. bzoj 1043 [HAOI2008]下落的圆盘——圆的周长

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1043 算每个圆被它后面的圆盖住了多少圆弧即可.注意判断这个圆完全被后面盖住的情况. #inc ...

  6. bzoj5248(洛谷4363)(2018九省联考)一双木棋

    题目:https://www.luogu.org/problemnew/show/P4363 一种考虑状态数的方法:有几个用了k个格子的列,就在第k个0的左边插入几个1: 这也是求不降序列的个数的方法 ...

  7. linux通过wget直接下载jdk,避免用户验证

    下载地址 :http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 下载语句: wget ...

  8. C++关于变量初始化的琐记

    #include <iostream> using namespace std; class Base{ virtual void func1() { cout<<" ...

  9. Web项目中定时任务无法绑定SessionFactory的问题解决

    正常我们在web开发中,由于需要在页面上或者脱离事务时使用到懒加载对应的对象,一般都采用Open Session In View模式.   Open Session In View   OpenSes ...

  10. Java类的初始化与实例对象的初始化

    Java对象初始化详解 2013/04/10 · 开发 · 1 评论· java 分享到:43 与<YII框架>不得不说的故事—扩展篇 sass进阶篇 Spring事务管理 Android ...