以下用大O表示节点,ABC表示三个集合。

  仅分析左子树的情况,因为对称,右子树的情况一样。

  插入节点前

      O

     /     \

    O        A

     /    \

B       C

  插入节点后:

      O

     /     \

    O        A

     /    \

B       C

/

O

此时造成了最高节点的不平衡,说明了B+2 - A = 2;另外可以知道B = C,考虑B<C,那么在插入节点前最高点就已经不平衡了,考虑B > C,那么最高的左子树就已经不平衡了,而不应该考虑最高点。所以此时可以知道A = B = C。

  左子树单旋转之后:

      O

     /     \

    B        O

     /          /    \

O         C       A

  对于最高点来说,左子树深度为B+1,右子树深度为A+1,即B + 1。

  对比插入后的树,可以知道只有原最高节点的深度发生变化,所以只需更新该节点的深度。

另外一种情况:

插入后:

 

      O

     /     \

    O        A

     /    \

B       C

/

O

此时如果单旋转,结果为:

      O

     /     \

    B        O

                 /    \

C       A

/

O

明显这个情况并没有得到解决。

所以首先要单右旋转最高节点的左子树,结果为:

      O

     /     \

    C        A

     /    \

O       O

/

B

此时可以知道C集合的深度发生了变化,需要更新C的深度,而之前更新的是最高点的深度,所以在旋转时需要更新原最高点和现最高点的深度。

第二次左旋转原最高点,结果为

      C

     /     \

    O        O

     /         /    \

B        O       A

这里面的正确有一些缺陷,应该把ABC集合多展开几层,否则在双旋转时的证明有些怪异,反正就是这个思路,因为画图实在是太麻烦了。

最后是代码:

  

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct _node
{
int element;
int high;
struct _node *lefttree;
struct _node *righttree;
}node; int gethigh(node *t)
{
if(t == )
return -;
return t->high;
} node *singlerotatewithleft(node *t)
{
node *tmp = t->lefttree;
t->lefttree = tmp->righttree;
tmp->righttree = t; tmp->high = ((gethigh(tmp->lefttree) > gethigh(tmp->righttree))?gethigh(tmp->lefttree):gethigh(tmp->righttree)) + ;
t->high = ((gethigh(t->lefttree) > gethigh(t->righttree))?gethigh(t->lefttree):gethigh(t->righttree)) + ;
return tmp;
} node *singlerotatewithright(node *t)
{
node *tmp = t->righttree;
t->righttree = tmp->lefttree;
tmp->lefttree = t; tmp->high = ((gethigh(tmp->lefttree) > gethigh(tmp->righttree))?gethigh(tmp->lefttree):gethigh(tmp->righttree)) + ;
t->high = ((gethigh(t->lefttree) > gethigh(t->righttree))?gethigh(t->lefttree):gethigh(t->righttree)) + ;
return tmp;
} node *doubleroratewithleft(node *t)
{
t->lefttree = singlerotatewithright(t->lefttree);
return singlerotatewithleft(t);
} node *doubleroratewithright(node *t)
{
t->righttree = singlerotatewithleft(t->righttree);
return singlerotatewithright(t);
} node *insert(node *t,int element)
{
if (t == )
{
t = (node *)malloc(sizeof(node));
t->element = element;
t->lefttree = t->righttree = ;
}
else if(t->element > element){
t->lefttree = insert(t->lefttree,element);
if(gethigh(t->lefttree) - gethigh(t->righttree) == )
if(element < t->lefttree->element)
t= singlerotatewithleft(t);
else
t= doubleroratewithleft(t);
}
else if(t->element < element){
t->righttree = insert(t->righttree,element);
if(gethigh(t->righttree) - gethigh(t->lefttree) == )
if(element > t->righttree->element)
t= singlerotatewithright(t);
else
t= doubleroratewithright(t); }
t->high = ((gethigh(t->lefttree) > gethigh(t->righttree))?gethigh(t->lefttree):gethigh(t->righttree)) + ;
return t;
} node *find(node *t,int element)
{
if(t == )
return ;
else if(t->element > element)
return find(t->lefttree,element);
else if(t->element < element)
return find(t->righttree,element);
else
return t;
} node* findmin(node *t)
{
if(t == )
return ;
if(t->lefttree == )
return t;
else
return findmin(t->lefttree);
} node *delele(node *t,int element)
{
if(t == )
return ;
else if(t->element > element)
t->lefttree = delele(t->lefttree,element);
else if(t->element < element)
t->righttree = delele(t->righttree,element);
else
{
if(t->lefttree && t->righttree)
{
node *tmp;
tmp = findmin(t->righttree);
t->element = tmp->element;
t->righttree = delele(t->righttree,tmp->element);
}
else
{
node *tmp;
tmp = t->lefttree?t->lefttree:t->righttree;
free(t);
t = tmp;
}
}
return t;
} void printtree(node *t)
{
if(t == )
return;
printtree(t->lefttree);
printf("%d\t",t->element);
printf("high = %d\n",t->high);
printtree(t->righttree);
} int main()
{
int a[] = {,,,,,,,,};
node *t;
int i = ;
t = insert(,);
for(;i<;i++){
t = insert(t,a[i]);
//printtree(t);
//sleep(1);
}
//t = delele(t,6);
printtree(t);
printf("\n");
//while(1);
return ;
}

 

 

 

avl树的操作证明的更多相关文章

  1. AVL树插入操作实现

    为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...

  2. AVL树相关操作

    #include <iostream> using namespace std; //AVL树的节点 template<typename T> class TreeNode { ...

  3. 纸上谈兵:AVL树

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 二叉搜索树的深度与搜索效率 我们在树, 二叉树, 二叉搜索树中提到,一个有n个节点 ...

  4. 纸上谈兵: AVL树[转]

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 二叉搜索树的深度与搜索效率 我们在树, 二叉树, 二叉搜索树中提到,一个有n个节点 ...

  5. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  6. 图解数据结构树之AVL树

    AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...

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

    一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...

  8. AVL树Python实现

    # coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...

  9. AVL树(平衡二叉树)

    定义及性质 AVL树:AVL树是一颗自平衡的二叉搜索树. AVL树具有以下性质: 根的左右子树的高度只差的绝对值不能超过1 根的左右子树都是 平衡二叉树(AVL树) 百度百科: 平衡二叉搜索树(Sel ...

随机推荐

  1. gdb进程调试,多进程调试

    1.单进程的调试 常规的通过gdb cmd这种方式开启调试,特别说明的是通过attach的方法附加到一个指定的进程上去进行调试,这种方法适合于调试一个已经运行的进程,具体用法:  gdb -p [pi ...

  2. 帆软报表FineReport数据库连接编码转换

    1. 问题描述 数据库会以某种编码方式保存与读取数据,FineReport解析时默认使用GBK字符集,若数据库端编码与设计器端编码不一致时,就会导致中文及特殊字符的乱码. FineReport在定义数 ...

  3. java报表工具FineReport常用函数的用法总结(文本和日期函数)

    文本函数 CHAR CHAR(number):根据指定数字返回对应的字符.CHAR函数可将计算机其他类型的数字代码转换为字符. Number:用于指定字符的数字,介于1Number:用于指定字符的数字 ...

  4. [COPY] How to become a hacker

    Engish version copied from here Why This Document? As editor of the Jargon File and author of a few ...

  5. 在github上建立自己的网站

    学了前端小半年,如今写了个自己的网页想要去应聘,却发现部署很麻烦,部署到阿里云之类,买域名啊啥的还要收费,说贵也不贵,但我就是傲娇~ google一下了解到Github有一个Github pages的 ...

  6. SpringMVC 返回json

    1.导入jackson的jar包 2.在方法体上加上@ResponseBody /** * 得到ProType的typeId,typeName列表 * 返回json * */ @RequestMapp ...

  7. hadoop 8088无法访问

    http://bbs.csdn.net/topics/390891983 yarn-site.xml <property> <name>yarn.resourcemanager ...

  8. BZOJ2595[WC2008]游览计划

    Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数 ...

  9. google-analytics的使用: 解析页面引入代码

    代码整理和注释 // 创建ga()方法, 加载analytics.js文件 // a, m 作为形参,确保下面的执行不会修改外部的同名变量 (function(win, doc, o, g, ga, ...

  10. jQuery动画效果animate和scrollTop结合使用实例

    CSS属性值是逐渐改变的,这样就可以创建动画效果.只有数字值可创建动画(比如 "margin:30px").字符串值无法创建动画(比如 "background-color ...