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. TypeError: window.open is not a function

    想必大家现在都已经到家了,而苦逼的我还要坐在办公室混拿微薄的工资,技不如人,平常不努力给自己充电,年终一毛钱都没多给.不说这扫兴的话题了,在这给同样在苦逼坚守岗位的同志们节日的问候,新的一年,好运连连 ...

  2. oracle dbms_JOB

    添加一个任务,怎么老是报错 [SQL] DECLARE job1 number; begin dbms_job.submit(job1,'RESTUDY_SCORE_IMPORT',sysdate,' ...

  3. (转)Tomcat数据源连接池加密

    文章来源 :http://my.oschina.net/cimu/blog/164757 我们在使用Tomcat数据库连接池的时候都是明文存储数据库用户名和密码的,例如: <Resource n ...

  4. 1千万英国用户被Cryptolocker勒索软件瞄准

    英国国家打击犯罪调查局(NCA)发布国家紧急警报,警报一场大规模的垃圾邮件,这些邮件中包含了一款名为CryptoLocker的勒索程序,把目标瞄准了1千万英国的email用户,该程序会加密用户的文档, ...

  5. Selenium的延迟等待

    http://my.oschina.net/u/928852/blog/98885 Selenium的延迟等待分为 显式等待(Explicit Wait) & 隐式等待(Implicit Wa ...

  6. Ubuntu下Nutch1.2的使用

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeMAAABpCAIAAACGSdxlAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4Xu ...

  7. C#枚举中的位运算权限分配浅谈

    常用的位运算主要有与(&), 或(|)和非(~), 比如: 1 & 0 = 0, 1 | 0 = 1, ~1 = 0 在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理. 第 ...

  8. 《JavaScript高级程序设计》读书笔记--前言

    起因 web编程过程使用javascript时感觉很吃力,效率很低.根本原因在于对javascript整个知识体系不熟,看来需要找些书脑补一下,同时欢迎众网友监督. 大神推荐书籍 看了博客大神们推荐的 ...

  9. codeforces problem 140E New Year Garland

    排列组合题 题意 用m种颜色的彩球装点n层的圣诞树.圣诞树的第i层恰由l[i]个彩球串成一行,且同一层内的相邻彩球颜色不同,同时相邻两层所使用彩球的颜色集合不同.求有多少种装点方案,答案对p取模. 只 ...

  10. Python3学习(二)-递归函数、高级特性、切片

    ##import sys ##sys.setrecursionlimit(1000) ###关键字参数(**关键字参数名) ###与可变参数不同的是,关键字参数可以在调用函数时,传入带有参数名的参数, ...