平衡二叉树之AVL树
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树的更多相关文章
- 【Java】 大话数据结构(12) 查找算法(3) (平衡二叉树(AVL树))
本文根据<大话数据结构>一书及网络资料,实现了Java版的平衡二叉树(AVL树). 平衡二叉树介绍 在上篇博客中所实现的二叉排序树(二叉搜索树),其查找性能取决于二叉排序树的形状,当二叉排 ...
- Java数据结构(十四)—— 平衡二叉树(AVL树)
平衡二叉树(AVL树) 二叉排序树问题分析 左子树全部为空,从形式上看更像一个单链表 插入速度没有影响 查询速度明显降低 解决方案:平衡二叉树 基本介绍 平衡二叉树也叫二叉搜索树,保证查询效率较高 它 ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- 数据结构之平衡二叉树(AVL树)
平衡二叉树(AVL树)定义如下:平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树: (1)它的左子树和右子树的高度之差绝对值不超过1: (2)它的左子树和右子树都是平衡二叉树. AVL树避免了 ...
- 二叉树学习笔记之经典平衡二叉树(AVL树)
二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...
- 一步一步写平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...
- 平衡二叉树(AVL树)
参考资料 http://www.cnblogs.com/Cmpl/archive/2011/06/05/2073217.html http://www.cnblogs.com/yc_sunniwell ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)(Swift版)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- 经典平衡二叉树(AVL树)
二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...
随机推荐
- linux通过wget直接下载jdk,避免用户验证
下载地址 :http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 下载语句: wget ...
- nginx虚拟机的配置
user nginx nginx;worker_processes 1;pid /data/var/run/nginx/nginx.pid;worker_rlimit_nofile 51200; ev ...
- WPF ComboBox下拉绑定Treeview 功能的实现
因为项目需要,接触到这个功能点,借助网络还有自己的一点摸索,实现了这个功能.相关代码如下: XAML部分的代码: <ComboBox Grid.Row=" RenderTransfor ...
- VS2003在vista/win7下搜索会出现僵死
1. VS2003在vista下搜索关键词的时候会出现僵死的问题的解决方案: VS2003快捷方式右击选中属性->兼容性页签 : 选中用兼容模式运行这个程序,下拉框中用windows xp2 ...
- ubuntu 进入单用户模式
进入单用户模式: 按shift进入 1.开机到grub时,用上下键移到第二行的恢复模式,按e(注意不是回车) 即Ubuntu,With Linux 3.2.0-23-generic(recovery ...
- (转)Inno Setup入门(十一)——完成安装后执行某些程序
本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17250901 有些时候我们的程序虽然能够很好的完成安装,但是程序的配 ...
- app的apk 安装的方法--adb--命令安装 (含把apk放某个文件夹,每次启动自己安装)
adb安装 1.在app自动化之前,首先手机上有要被测试的app,如何把电脑本地上的app安装到手机上呢?可以在运行自动化代码前,在cmd输入adb指令,把电脑app安装到手机上 adb instal ...
- java代码---------陈勇老师的
总结:看看写的多漂亮啊 package com.test4; import java.awt.*; import java.awt.event.*; import javax.swing.*; pub ...
- kotlin学习一:kotlin简介
kotlin是JetBrains公司出品的基于JVM的语言,和其他JVM语言一样,目的在于提供比JAVA更加简介的语法, 同时提供函数式编程,不需要再像JAVA一样所有的一切都要依托于类. kotli ...
- Hadoop Map/Reduce的工作流
问题描述 我们的数据分析平台是单一的Map/Reduce过程,由于半年来不断地增加需求,导致了问题已经不是那么地简单,特别是在Reduce阶段,一些大对象会常驻内存.因此越来越顶不住压力了,当前内存问 ...