1.AVL树是带有平衡条件的二叉查找树.

2.AVL树的每个节点高度最多相差1.

3.AVL树实现的难点在于插入或删除操作.由于插入和删除都有可能破坏AVL树高度最多相差1的特性,所以当特性被破坏时需要通过旋转方式调整树结构.具体旋转方式有以下4种,举例说明如下:

LL型:

    6                                                   5

   /            右转                         /        \

  5            ---->                      4            6

/

4

-------------------------------------------------------------------------------------------------------

RR型:

6                                                                7

\                         左转                          /         \

7                      ---->                        6           8

\

8

-------------------------------------------------------------------------------------------------------

LR型:

7                                               7                                              6

/               先左转                     /              再右转                        /      \

4                   ---->                   6                  ---->                        4         7

\                                       /

6                                  4

-------------------------------------------------------------------------------------------------------

RL型:

7                                   7                                                             8

\              先右转             \                   再左转                         /       \

9           ---->                 8                  ---->                         7         9

/                                         \

8                                             9

图形说明可参考如下链接:

http://blog.csdn.net/gabriel1026/article/details/6311339

#include <stdio.h>
#include <stdlib.h> #define ElementType int
#define Max(N1, N2) ((N1 > N2) ? (N1) : (N2)) //typedef struct TreeNode *Position;
//typedef struct TreeNode *SearchTree; struct TreeNode
{
ElementType Element;
struct TreeNode *Left;
struct TreeNode *Right;
int Height;
}; typedef struct TreeNode *Position;
typedef struct TreeNode *SearchTree; SearchTree Insert(ElementType X, SearchTree T);
SearchTree Delete(ElementType X, SearchTree T);
SearchTree MakeEmpty(SearchTree T);
SearchTree PrintTree(SearchTree T);
Position Find(ElementType X, SearchTree T);
Position FindMax(SearchTree T);
Position FindMin(SearchTree T); static int Height(Position P);
static Position SingleRotateWithRight(Position P); //RR型
static Position SingleRotateWithLeft(Position P);
static Position DoubleRotateWithRight(Position P);
static Position DoubleRotateWithLeft(Position P);
static Position Rotate(Position P); static int Height(Position P)
{
if (NULL == P)
{
return -;
}
else
{
return P->Height;
}
} static Position SingleRotateWithRight(Position P) //RR左转
{
Position M = NULL;
if (NULL == P)
{
return NULL;
}
M = P->Right;
P->Right = M->Left;
M->Left = P;
P->Height = Max(Height(P->Left), Height(P->Right)) + ;
M->Height = Max(Height(M->Left), Height(M->Right)) + ;
return M;
} static Position SingleRotateWithLeft(Position P) //LL右转
{ Position M = NULL;
if (NULL == P)
{
return NULL;
}
M = P->Left;
P->Left = M->Right;
M->Right = P;
P->Height = Max(Height(P->Left), Height(P->Right)) + ;
M->Height = Max(Height(M->Left), Height(M->Right)) + ;
return M;
} static Position DoubleRotateWithRight(Position P) //RL先右后左
{
if (NULL == P)
{
return NULL;
}
P->Right = SingleRotateWithLeft(P->Right); //LL右转
return SingleRotateWithRight(P); //RR左转
} static Position DoubleRotateWithLeft(Position P) //LR先左后右双旋
{
if (NULL == P)
{
return NULL;
}
P->Left = SingleRotateWithRight(P->Left); //RR左转
return SingleRotateWithLeft(P); //LL右转
} static Position Rotate(Position P)
{
if (NULL == P)
{
return NULL;
}
if (Height(P->Right) - Height(P->Left) == )
{
if (P->Right)
{
if (Height(P->Right->Right) > Height(P->Right->Left))
{
P = SingleRotateWithRight(P); //RR左单旋
}
else
{
P = DoubleRotateWithRight(P); //RL先右后左双旋
}
}
}
else if (Height(P->Left) - Height(P->Right) == )
{
if (P->Left)
{
if (Height(P->Left->Left) > Height(P->Left->Right))
{
P = SingleRotateWithLeft(P); //RR右单旋
}
else
{
P = DoubleRotateWithLeft(P); //RL先左后右双旋
}
}
}
else
{}
return P;
} SearchTree Insert(ElementType X, SearchTree T)
{
if (NULL == T)
{
T = (SearchTree)malloc(sizeof(struct TreeNode));
if (NULL == T)
{
printf("Malloc Error!\n");
return NULL;
}
else
{
printf("Insert %d!\n", X);
T->Element = X;
T->Left = T->Right = NULL;
}
}
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); //RR左单旋
}
else
{
T = DoubleRotateWithRight(T); //RL先右后左双旋
}
}
}
else
{
T->Left = Insert(X, T->Left);
if (Height(T->Left) - Height(T->Right) == )
{
if (X < T->Left->Element)
{
T = SingleRotateWithLeft(T); //RR 右单旋
}
else
{
T = DoubleRotateWithLeft(T); //RL先右后左双旋
}
}
}
T->Height = Max(Height(T->Left), Height(T->Right)) + ;
return T;
} SearchTree Delete(ElementType X, SearchTree T)
{
Position Temp = NULL;
if (NULL == T)
{
printf("Delete Element Not Found!\n");
return NULL;
}
else if (X > T->Element)
{
T->Right = Delete(X, T->Right);
}
else if (X < T->Element)
{
T->Left = Delete(X, T->Left);
}
else if (T->Right && T->Left)
{
Temp = FindMin(T->Right);
T->Element = Temp->Element;
T->Right = Delete(T->Element, T->Right);
}
else
{
Temp = T;
if (NULL == T->Right)
{
T = T->Left;
}
else if (NULL == T->Left)
{
T = T->Right;
}
else
{}
free(Temp);
Temp = NULL;
if (NULL == T)
{
return NULL;
}
}
//回溯重新计算父节点高度
T->Height = Max(Height(T->Left), Height(T->Right)) + ;
//删除节点后判断是否失去平衡,如果失去平衡,将树进行相应调整
T = Rotate(T);
return T;
} SearchTree MakeEmpty(SearchTree T)
{
if (NULL != T)
{
MakeEmpty(T->Right);
MakeEmpty(T->Left);
free(T);
}
return NULL;
} SearchTree PrintTree(SearchTree T)
{
if (NULL != T)
{
printf("%d,%d ", T->Element, T->Height);
if (NULL != T->Left)
{
PrintTree(T->Left);
}
if (NULL != T->Right)
{
PrintTree(T->Right);
}
}
return NULL;
} Position Find(ElementType X, SearchTree T)
{
if (NULL == T)
{
printf("Find Element Not Found!\n");
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 FindMax(SearchTree T)
{
if (NULL != T)
{
while (NULL != T->Right)
{
T = T->Right;
}
}
return T;
} Position FindMin(SearchTree T)
{
if (NULL == T)
{
return NULL;
}
else if (NULL == T->Left)
{
return T;
}
else
{
return FindMin(T->Left);
}
} int main()
{
SearchTree T = NULL;
SearchTree ptmp = NULL;
//验证各函数是否正确
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T);
T = Insert(, T); ptmp = FindMin(T);
if (NULL != ptmp)
{
printf("min:%d\n", ptmp->Element);
}
ptmp = FindMax(T);
if (NULL != ptmp)
{
printf("max:%d\n", ptmp->Element);
}
ptmp = Find(, T);
if (NULL != ptmp)
{
printf("find:%d\n", ptmp->Element);
}
PrintTree(T);
printf("\n"); T = Delete(, T);
T = Delete(, T);
T = Delete(, T);
T = Delete(, T);
T = Delete(, T);
PrintTree(T);
printf("\n");
ptmp = Find(, T);
if (NULL != ptmp)
{
printf("find:%d\n", ptmp->Element);
} T = MakeEmpty(T);
return ;
}

部分编码来自如下链接

http://blog.csdn.net/xiaofan086/article/details/8294382

数据结构与算法分析-AVL树的更多相关文章

  1. 数据结构与算法——AVL树类的C++实现

    关于AVL树的简单介绍能够參考:数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额外 ...

  2. 【数据结构】平衡二叉树—AVL树

    (百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...

  3. 数据结构(三)实现AVL树

    AVL树的定义 一种自平衡二叉查找树,中面向内存的数据结构. 二叉搜索树T为AVL树的满足条件为: T是空树 T若不是空树,则TL.TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高 ...

  4. 数据结构——二叉查找树、AVL树

    二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...

  5. 数据结构与算法分析java——树2(二叉树类型)

    1. 二叉查找树 二叉查找树(Binary Search Tree)/  有序二叉树(ordered binary tree)/ 排序二叉树(sorted binary tree) 1). 若任意节点 ...

  6. [数据结构与算法] : AVL树

    头文件 typedef int ElementType; #ifndef _AVLTREE_H_ #define _AVLTREE_H_ struct AvlNode; typedef struct ...

  7. 数据结构与算法分析java——树1

    1. 基本术语 度(degree):一个节点的子树个数称为该节点的度: 树中结点度的最大值称为该树的度. 层数(level):从根结点开始算,根节点为1 高度(height)/深度(depth):节点 ...

  8. AVL树和伸展树 -数据结构(C语言实现)

    读数据结构与算法分析 AVL树 带有平衡条件的二叉树,通常要求每颗树的左右子树深度差<=1 可以将破坏平衡的插入操作分为四种,最后通过旋转恢复平衡 破坏平衡的插入方式 描述 恢复平衡旋转方式 L ...

  9. 《数据结构与算法分析——C语言描述》ADT实现(NO.04) : AVL树(AVL-Tree)

    上次我们已经实现了普通的二叉查找树.利用二叉查找树,可以用O(logN)高度的树状结构存储和查找数据,提高了存储和查找的效率. 然而,考虑一种极端情形:依次插入1,2,3,4,5,6,7,8,9九个元 ...

随机推荐

  1. 利用flash精确定位asp.net的图像热点区域

    Asp.net的热点区域控件非常有用,但是对于热点区域如何精确定位,设定矩形,圆和多边形要素点的位置,用flash能够精确定位,在flash中制作热点区域的部分,可以是矩形,图形或者文字,然后对于这部 ...

  2. 转 : Hibernate懒加载深入分析

    懒加载可以提高性能吗? 不可以简单的说"能",因为hibernate的关系映射拖累了SQL的性能,所以想出懒加载来弥补.只是弥补而以,不会超越.所以大家不要想着使用了懒加载总体性能 ...

  3. 通过npm安装 Cordova

    通过npm安装 Cordova 首先请确保你在本地已经安装了NodeJS(可以调用npm命令), 并且是联网状态的.如果不知道如何安装NodeJS, 请参考 ”四步完成NodeJS安装,配置和测试”. ...

  4. [深度优先搜索] POJ 1426 Find The Multiple

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28550   Accepted: 118 ...

  5. mysql sql语句大全

    1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份 ...

  6. WireShark网络性能分析

    最近生产上出现一个性能问题,表现为:行情延时5s左右.从log一路追查下去,发现是我们自己写的一个行情网关(部署在xx.xx.xx.132)<->第三方的中转网关(部署在xx.xx.xx. ...

  7. 端口限制情况下php+xdebug环境配置

    PHP程序在开发的时候调试是比较方便的,大体情况下,输出,打log是可以解决几乎所有问题. 但是还不够,有些问题,用打log的形式定位问题是相当痛苦的事情,有些时候测试环境没配好的话,你可能需要做许多 ...

  8. Informatica - Powercenter 英文版资料(转载)

    Informatica - Powercenter 英文版资料 http://gerardnico.com/wiki/powercenter/powercenter

  9. AngularJs的UI组件ui-Bootstrap分享(八)——Tooltip和Popover

    tooltip和popover是轻量的.可扩展的.用于提示的指令.对于移动端来讲,这两个指令虽然可以正常工作,但是从用户体验的角度并不推荐使用. 先说tooltip,tooltip有三种使用方式: ( ...

  10. VS 工程的 输出路径和工作路径的区别

    输出路径,是vs编译项目生成可执行文件的路径:工作路径是环境变量,比如我们在程序中写相对路径,就是以这个路径为基础的.在默认情况下,输出路径和工作路径都不写的话,默认是程序的bin下面的debug或者 ...