以下用大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. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  2. python爬虫学习(2) —— 爬一下ZOL壁纸

    我喜欢去ZOL找一些动漫壁纸当作桌面,而一张一张保存显然是太慢了. 那怎么办呢,我们尝试使用简单的爬虫来解决这个问题. 0. 本爬虫目标 抓取给定分类「或子分类」网址的内容 分析并得到每个分类下的所有 ...

  3. MIT研发的新型匿名网络Riffle,下一个Tor

    现在的隐私问题是一个网络热词,如果你担心你上网的隐私会泄露,最有效的解决办法就是使用Tor.这款免费的匿名通信软件,能够让人们在与其他人通信时隐藏自己真实的信息. 虽然Tor是一个很好的匿名网络系统, ...

  4. [Template]高精度模板

    重新写一下高精度模板(不要问我为什么) 自认为代码风格比较漂亮(雾 如果有更好的写法欢迎赐教 封装结构体big B是压位用的进制,W是每位长度 size表示长度,d[]就是保存的数字,倒着保存,从1开 ...

  5. Hibernate内测总结

    1.在Hibernate中,以下关于主键生成器说法错误的是( ). A.increment可以用于类型为long.short或byte的主键 B.identity用于如SQL Server.DB2.M ...

  6. 第3章 Linux常用命令(3)_文件搜索命令

    3. 文件搜索命令 3.1 文件搜索:find (1)find命令 命令名称 find 命令所在路径 /bin/find 执行权限 所有用户 语法 find [搜索范围] [-选项] [匹配条件] - ...

  7. GNU make使用变量⑤变量的引用、定义等

    在 Makefile 中,变量是一个名字(像是 C 语言中的宏),代表一个文本字符串(变量的值).在 Makefile 的目标.依赖.命令中引用变量的地方,变量会被它的值所取代(与 C 语言中宏引用的 ...

  8. [No000075]有没有安全的工作?

    如果你经常使用互联网,可能知道有一种东西叫做Flash. 它是一种软件,用来制作网页游戏.动画,以及视频播放器.只要观看网络视频,基本都会用到它. 七八年前,它是最热门的互联网技术之一.如果不安装Fl ...

  9. 2016-2017-2 《Java程序设计》预备作业1 总结

    2016-2017-2 <Java程序设计>预备作业1 总结 预备作业01:你期望的师生关系是什么见https://edu.cnblogs.com/campus/besti/2016-20 ...

  10. win7/8 访问 访问局域网 默认加载域 而无法成功访问的问题

    运行 gpedit.msc选择 本地计算机策略- 计算机配置-windows设置-安全设置-本地策略-安全选项 其中有个 网络安全:lan管理员身份验证级别 选择 发送LM和NTLM响应