[数据结构与算法] : AVL树
头文件
typedef int ElementType; #ifndef _AVLTREE_H_
#define _AVLTREE_H_ struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree; AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X, AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X, AvlTree T);
AvlTree Delete(ElementType X, AvlTree T);
ElementType Retrieve(Position P);
void PrintTree(AvlTree T); #endif
源文件
#include "fatal.h"
#include "avltree.h"
#include <malloc.h> struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
}; AvlTree MakeEmpty(AvlTree T) // 同二叉查找树
{
if(T != NULL) // 递归终止
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return T;
} Position Find(ElementType X, AvlTree T) // 同二叉查找树
{
if(T == NULL)
return NULL;
else if(X < T->Element)
{
return Find(X, T->Left);
}
else if(X > T->Element)
{
return Find(X, T->Right);
}
else
return T;
} Position FindMin(AvlTree T) // 递归实现
{
if(T == NULL)
return NULL;
else if(T->Left == NULL)
return T;
else
return FindMin(T->Left);
} Position FindMax(AvlTree T) // 非递归实现
{
if(T != NULL)
while(T->Right != NULL)
T = T->Right; return T;
} static int Height(Position P)
{
if(P == NULL)
return -; // 空树高度为-1
else
return P->Height;
} static int Max(int Left, int Right)
{
return Left > Right ? Left : Right;
} /* This function can be called only if K2 has a left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */
static Position SingleRotateWithLeft(Position K2)
{
Position K1; K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2; K2->Height = Max(Height(K2->Left), Height(K2->Right)) + ;
K1->Height = Max(Height(K1->Left), Height(K1->Right)) + ; return K1; /* New root */
} /* This function can be called only if K1 has a right child */
/* Perform a rotate between a node (K1) and its right child */
/* Update heights, then return new root */
static Position SingleRotateWithRight(Position K1)
{
Position K2; K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1; K1->Height = Max(Height(K1->Left), Height(K1->Right)) + ;
K2->Height = Max(Height(K2->Left), Height(K2->Right)) + ; return K2; /* New root */
} /* This function can be called only if K3 has a left */
/* child and K3's left child has a right child */
/* Do the left-right double rotation */
/* Update heights, then return new root */
static Position DoubleRotateWithLeft(Position K3)
{
/* Rotate between K1 and K2 */
K3->Left = SingleRotateWithRight(K3->Left);
/* Rotate between K3 and K2 */
return SingleRotateWithLeft(K3);
} /* This function can be called only if K1 has a right */
/* child and K1's right child has a left child */
/* Do the right-left double rotation */
/* Update heights, then return new root */
static Position DoubleRotateWithRight(Position K1)
{
/* Rotate between K3 and K2 */
K1->Right = SingleRotateWithLeft(K1->Right);
/* Rotate between K1 and K2 */
return SingleRotateWithRight(K1);
} // 1. 找位置; 2. 插入; 3. 平衡性; 4. 旋转
AvlTree Insert(ElementType X, AvlTree T)
{
if(T == NULL)
{
/* Create and return a one-node tree */
T = (AvlTree)malloc(sizeof(struct AvlNode));
if(T == NULL)
FatalError("Out of space!");
else
{
T->Left = T->Right = NULL;
T->Height = ;
T->Element = X;
}
}
else if(X < T->Element)
{
T->Left = Insert(X, T->Left);
// 因为插到左边了, 所以肯定是左边比较高
if(Height(T->Left) - Height(T->Right) == )
{
if(X < T->Left->Element)
T = SingleRotateWithLeft(T);
else
T = DoubleRotateWithLeft(T);
}
}
else if(X > T->Element)
{
T->Right = Insert(X, T->Right);
// 插到右边了, 右边比较高
if(Height(T->Right) - Height(T->Left) == )
{
if(X > T->Right->Element)
T = SingleRotateWithRight(T);
else
T = DoubleRotateWithRight(T);
}
}
/* Else X is in the tree already; we'll do nothing */
T->Height = Max(Height(T->Left), Height(T->Right)) + ; return T;
} AvlTree Delete(ElementType X, AvlTree T)
{
printf( "Sorry; Delete is unimplemented; %d remains\n", X );
return T;
} ElementType Retrieve(Position P)
{
return P->Element;
} void PrintTree(AvlTree T)
{
if( T != NULL)
{
PrintTree(T->Left);
printf("%d ", T->Element);
PrintTree(T->Right);
}
}
测试文件
#include "avltree.h"
#include <stdio.h> main( )
{
AvlTree T;
Position P;
int i;
int j = ; T = MakeEmpty( NULL );
for( i = ; i < ; i++, j = ( j + ) % )
T = Insert( j, T );
for( i = ; i < ; i++ )
if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
printf( "Error at %d\n", i ); /* for( i = 0; i < 50; i += 2 )
T = Delete( i, T ); for( i = 1; i < 50; i += 2 )
if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
printf( "Error at %d\n", i );
for( i = 0; i < 50; i += 2 )
if( ( P = Find( i, T ) ) != NULL )
printf( "Error at %d\n", i );
*/
printf( "Min is %d, Max is %d\n", Retrieve( FindMin( T ) ),
Retrieve( FindMax( T ) ) );
PrintTree(T);
return ;
}
[数据结构与算法] : AVL树的更多相关文章
- 数据结构与算法——AVL树类的C++实现
关于AVL树的简单介绍能够參考:数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额外 ...
- 数据结构和算法(Golang实现)(28)查找算法-AVL树
AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和La ...
- 【数据结构】平衡二叉树—AVL树
(百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 数据结构(三)实现AVL树
AVL树的定义 一种自平衡二叉查找树,中面向内存的数据结构. 二叉搜索树T为AVL树的满足条件为: T是空树 T若不是空树,则TL.TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高 ...
- 数据结构与算法分析-AVL树
1.AVL树是带有平衡条件的二叉查找树. 2.AVL树的每个节点高度最多相差1. 3.AVL树实现的难点在于插入或删除操作.由于插入和删除都有可能破坏AVL树高度最多相差1的特性,所以当特性被破坏时需 ...
- 数据结构——二叉查找树、AVL树
二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...
- [算法] avl树实现
大二的时候数据结构课死活没看懂的一个东东,看了2小时,敲了2小时,调了2小时... 平衡树某一节点的左右子树高度相差大于1的时候即需要调整,调整可分为四中情况 ll,rr,lr,rl其中lr,rl是由 ...
- 数据结构与算法—Trie树
Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...
- Android版数据结构与算法(六):树与二叉树
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 之前的篇章主要讲解了数据结构中的线性结构,所谓线性结构就是数据与数据之间是一对一的关系,接下来我们就要进入非线性结构的世界了,主要是树与图,好了接 ...
随机推荐
- elasticsearch配置详解
一.说明 使用的是新版本5.1,直接从官网下载rpm包进行安装,https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5 ...
- poj 1330 Nearest Common Ancestors(LCA 基于二分搜索+st&rmq的LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30147 Accept ...
- ShellExecute函数的问题
情境:自己写了一个loading画面,定时器到时间后调用shellexecute函数调用真正的程序. 问题:调用时出错,说找不到dll资源,但是用鼠标双击确可以打开. 经过分析之后,应该是路径的问题, ...
- 为何 Delphi的 Local Variables 突然没有值显示了
可能是上次编译后 code未再修改过. 试试 随便 输入一个空格,然后F9
- flask(十)使用alembic,进行数据库结构管理,升级,加表,加项
1.安装扩展,在虚拟环境中安装 alembic,不懂可以去看pycharm的系列文章. 2.初始化, 使用 Alembic 前需要通过 alembic init 命令创建一个 alembic 项目,该 ...
- easyui常用属性
属性分为CSS片段和JS片段. CSS类定义:1.div easyui-window 生成一个window窗口样式. 属性如下: 1)mod ...
- ODBC的基础架构
*) 基本概念:1. 应用程序(Application)2. ODBC驱动管理器(ODBC Driver Manager) 负责管理应用程序和驱动程序间的通信,主要功能包括:解析DSN (数据源名称, ...
- 利用asynchttpclient开源项目来把数据提交给服务器
可以通过github去查找asynchttpclient,并下载源代码,并加载到自己的工程中. 1.利用get方法提交 2.利用post方法来提交
- hdu 1203 dp(关于概率的```背包?)
题意:一个人手里有一笔钱 n ,有 m 所大学,分别知道这些大学的投简历花费和被录取概率,因为钱数有限,只能投一部分学校,问被录取的概率最大有多大. 这题除去计算概率以外就是一个 0 1 背包问题,所 ...
- HDU5373 The shortest problem (YY)
http://acm.hdu.edu.cn/showproblem.php?pid=5373 YY题,模拟下计算过程就好了,计算中并不要保存实际数(这个数会非常大),只要保存到目前为止的数字位上的和 ...