平衡二叉树(Balancedbinary tree)是由阿德尔森-维尔斯和兰迪斯(Adelson-Velskiiand Landis)于1962年首先提出的,所以又称为AVL树。

定义:平衡二叉树或为空树,或为如下性质的二叉排序树:

(1)左右子树深度之差的绝对值不超过1;

(2)左右子树仍然为平衡二叉树.

平衡二叉树可以避免排序二叉树深度上的极度恶化,使树的高度维持在O(logn)来提高检索效率。

因为插入节点导致整个二叉树失去平衡分成如下的四种情况:

假设由于在二叉排序树上插入节点而失去平衡的最小子数根节点的指针为a(即a是离插入节点最近,且平衡因子绝对值超过1的祖先节点),则失去平衡后进行调整的规律如下:

1.如上图LL单向右旋处理:由于在*a的左子树根节点的左子树上插入节点,*a的平衡因子由1增至2,致使以*a为根节点的子树失去平衡,则需要进行一次向右的顺时针旋转操作。

2.如上图RR单向左旋处理:由于在*a的右子树根节点的右子树上插入节点, *a的平衡因子有-1变为-2,致使以*a为根节点的子树失去平衡,则学要进行一次向左的逆时针旋转操作。

3.如上图LR双向旋转(先左后右)处理:由于在*a的左子树根节点的右子树插入节点,*a的平衡因子有1增至2,致使以*a为根节点的子树失去平衡,则需要进行两次旋转(先左旋后右旋)操作。

4.如上图RL双向旋转(先右后左)处理:由于在*a的右子树根节点的左子树上插入节点,*a的平衡因子由-1变为-2,致使以*a为根节点的子树失去平衡,则需要进行两次旋转(先左旋后右旋)操作。

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdio>
#define LH 1 //左高
#define EH 0 //等高
#define RH -1 //右高
using namespace std; template <typename ElemType>
class BSTNode{
public:
ElemType data;//节点的数据
int bf;//节点的平衡因子
BSTNode *child[];
BSTNode(){
child[] = NULL;
child[] = NULL;
}
}; typedef BSTNode<string> BSTnode, *BSTree; template <typename ElemType>
class AVL{
public:
BSTNode<ElemType> *T;
void buildT();
void outT(BSTNode<ElemType> *T);
private:
bool insertAVL(BSTNode<ElemType>* &T, ElemType key, bool &taller);
void rotateT(BSTNode<ElemType>* &o, int x);//子树的左旋或者右旋
void leftBalance(BSTNode<ElemType>* &o);
void rightBalance(BSTNode<ElemType>* &o);
}; template <typename ElemType>
void AVL<ElemType>::rotateT(BSTNode<ElemType>* &o, int x){
BSTNode<ElemType>* k = o->child[x^];
o->child[x^] = k->child[x];
k->child[x] = o;
o = k;
} template <typename ElemType>
void AVL<ElemType>::outT(BSTNode<ElemType> *T){
if(!T) return;
cout<<T->data<<" ";
outT(T->child[]);
outT(T->child[]);
} template <typename ElemType>
void AVL<ElemType>::buildT(){
T = NULL;
ElemType key;
while(cin>>key){
if(key==) break;
bool taller = false;
insertAVL(T, key, taller);
outT(T);
cout<<endl;
}
} template <typename ElemType>
bool AVL<ElemType>::insertAVL(BSTNode<ElemType>* &T, ElemType key, bool &taller){
if(!T){//插入新的节点,taller=true 那么树的高度增加
T = new BSTNode<ElemType>();
T->data = key;
T->bf = EH;
taller = true;
} else {
if(T->data == key){
taller = false;
return false;
}
if(T->data > key){//向T的左子树进行搜索并插入
if(!insertAVL(T->child[], key, taller)) return false;
if(taller){//
switch(T->bf){
case LH://此时左子树的高度高,左子树上又插入了一个节点,失衡,需要进行调整
leftBalance(T);
taller = false;//调整之后高度平衡
break;
case EH:
T->bf = LH;
taller = true;
break;
case RH:
T->bf = EH;
taller = false;
break;
}
}
}
if(T->data < key) {//向T的右子树进行搜索并插入
if(!insertAVL(T->child[], key, taller)) return false;
switch(T->bf){
case LH:
T->bf = EH;
taller = false;
break;
case EH:
T->bf = RH;
taller = true;
break;
case RH:
rightBalance(T);
taller = false;
break;
}
}
}
return true;
} template <typename ElemType>
void AVL<ElemType>::leftBalance(BSTNode<ElemType>* &T){
BSTNode<ElemType>* lchild = T->child[];
switch(lchild->bf){//检查T的左子树的平衡度,并作相应的平衡处理
case LH://新节点 插入到 T的左孩子的左子树上,需要对T节点做单旋(右旋)处理
T->bf = lchild->bf = EH;
rotateT(T, );
break;
case RH://新节点 插入到 T的左孩子的右子树上,需要做双旋处理 1.对lchild节点进行左旋,2.对T节点进行右旋
BSTNode<ElemType>* rdchild = lchild->child[];
switch(rdchild->bf){//修改 T 及其左孩子的平衡因子
case LH: T->bf = RH; lchild->bf = EH; break;
case EH: T->bf = lchild->bf = EH; break;//发生这种情况只能是 rdchild无孩子节点
case RH: T->bf = EH; lchild->bf = LH; break;
}
rdchild->bf = EH;
rotateT(T->child[], );//不要写成 rotateT(lc, 0);//这样的话T->lchild不会改变
rotateT(T, );
break;
}
} template <typename ElemType>
void AVL<ElemType>::rightBalance(BSTNode<ElemType>* &T){
BSTNode<ElemType>* rchild = T->child[];
switch(rchild->bf){//检查T的左子树的平衡度,并作相应的平衡处理
case RH://新节点 插入到 T的右孩子的右子树上,需要对T节点做单旋(左旋)处理
T->bf = rchild->bf = EH;
rotateT(T, );
break;
case LH://新节点 插入到 T的右孩子的左子树上,需要做双旋处理 1.对rchild节点进行右旋,2.对T节点进行左旋
BSTNode<ElemType>* ldchild = rchild->child[];
switch(ldchild->bf){//修改 T 及其右孩子的平衡因子
case LH: T->bf = EH; rchild->bf = RH; break;
case EH: T->bf = rchild->bf = EH; break;//发生这种情况只能是 ldchild无孩子节点
case RH: T->bf = LH; rchild->bf = EH; break;
}
ldchild->bf = EH;
rotateT(T->child[], );
rotateT(T, );
break;
}
} int main(){
AVL<int> avl;
avl.buildT();
avl.outT(avl.T);
return ;
} /*
13 24 37 90 53 0
*/

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

  1. 平衡二叉树AVL - 插入节点后旋转方法分析

    平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1. 首先我们知道,当插入一个节点,从此插入点到树根 ...

  2. 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)

    二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...

  3. 平衡二叉树AVL删除

    平衡二叉树的插入过程:http://www.cnblogs.com/hujunzheng/p/4665451.html 对于二叉平衡树的删除采用的是二叉排序树删除的思路: 假设被删结点是*p,其双亲是 ...

  4. 平衡二叉树,AVL树之图解篇

    学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建 ...

  5. 数据结构与算法--从平衡二叉树(AVL)到红黑树

    数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...

  6. K:平衡二叉树(AVL)

    相关介绍:  二叉查找树的查找效率与二叉树的形状有关,对于按给定序列建立的二叉排序树,若其左.右子树均匀分布,则查找过程类似于有序表的二分查找,时间复杂度变为O(log2n).当若给定序列原来有序,则 ...

  7. 平衡二叉树(AVL)的理解和实现(Java)

    AVL的定义 平衡二叉树:是一种特殊的二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1.从平衡二叉树的名字中可以看出来,它是一种高度平衡的二叉排序树.那么什么叫做高度平衡呢?意思就是要么它 ...

  8. 平衡二叉树,AVL树之代码篇

    看完了第一篇博客,相信大家对于平衡二叉树的插入调整以及删除调整已经有了一定的了解,下面,我们开始介绍代码部分. 首先,再次提一下使用的结构定义 typedef char KeyType; //关键字 ...

  9. 二叉查找树、平衡二叉树(AVL)、B+树、联合索引

    1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...

随机推荐

  1. Python列表和元组

    Python是没有数组的概念,但是和数组比较相近的概念是列表和元素. 下面两个例子展示列表和元组. # coding=utf-8 # 元组 students = ('小明', '小黄', '小李', ...

  2. POJ 1160 题解

    Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18835   Accepted: 10158 Des ...

  3. 怎么取得dropdownlist选中的ID值

    把数据库绑定在dropdownlist中,然后把选中的dropdownlist的项的ID值保存在另外的一个数据库中.怎么取得dropdownlist选中的ID值呢?? this.DropDownLis ...

  4. WCF服务编程

    WCF服务编程, 我是WCF的初学者,在这想分享学习WCF服务编程的过程,欢迎大家多多指教!

  5. 腾讯网2016回响中国:华清远见荣获2016年度知名IT培训品牌

    12月1日,由腾讯网主办的“2016回响中国·腾讯网教育年度盛典”上,揭晓了“2016腾讯网教育年度总评榜”榜单.高端IT就业培训专家——华清远见教育集团凭借自身优质的高薪IT就业服务优势成功入围,荣 ...

  6. JS 将数字转化成为货币格式

    最近由于项目的需要需要将数字format成货币格式,自己搞了半天效果不是很好,博客园有篇问题很好,再次转载记录一下 http://www.cnblogs.com/mingmingruyuedlut/a ...

  7. h5 audio标签在手机上不能自动播放????

    最近在做一个微信端的项目,快到接近尾声的时候,发现还没放入音频,于是乎,放入音频,在电脑端测试一切正常,无阻碍. 后来在手机上测试,发现背景音乐不能播放,于是开始找错,刚开始以为是IIS服务器出错,结 ...

  8. linux shell中不显示路径了,显示为-bash-4.1#的两种解决办法

    出现这个问题的原因是因为没有配置.bash_profile的问题,或者是我们不小心清空或删除了.bash_profile文件. 办法一:修改 ~/.bash_profile文件 步骤如下: vim ~ ...

  9. HTML元素基础学习

    HTML元素 HTML文档是由HTML元素定义的.HTML元素是指从start tag(opening tag)到end tag(closing tag)的所有代码,即start tag + cont ...

  10. 【Beta】Daily Scrum Meeting总结

    团队博客目录:FTD团队博客目录 一.项目预期计划和现实进展 更换网络请求框架为okHttp 完成 补充和完善服务器的API 完成(可与web端互连) 补充和完善app与服务器交互的类和方法 完成 完 ...