数据结构与算法分析-AVL树
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树的更多相关文章
- 数据结构与算法——AVL树类的C++实现
关于AVL树的简单介绍能够參考:数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额外 ...
- 【数据结构】平衡二叉树—AVL树
(百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 数据结构(三)实现AVL树
AVL树的定义 一种自平衡二叉查找树,中面向内存的数据结构. 二叉搜索树T为AVL树的满足条件为: T是空树 T若不是空树,则TL.TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高 ...
- 数据结构——二叉查找树、AVL树
二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...
- 数据结构与算法分析java——树2(二叉树类型)
1. 二叉查找树 二叉查找树(Binary Search Tree)/ 有序二叉树(ordered binary tree)/ 排序二叉树(sorted binary tree) 1). 若任意节点 ...
- [数据结构与算法] : AVL树
头文件 typedef int ElementType; #ifndef _AVLTREE_H_ #define _AVLTREE_H_ struct AvlNode; typedef struct ...
- 数据结构与算法分析java——树1
1. 基本术语 度(degree):一个节点的子树个数称为该节点的度: 树中结点度的最大值称为该树的度. 层数(level):从根结点开始算,根节点为1 高度(height)/深度(depth):节点 ...
- AVL树和伸展树 -数据结构(C语言实现)
读数据结构与算法分析 AVL树 带有平衡条件的二叉树,通常要求每颗树的左右子树深度差<=1 可以将破坏平衡的插入操作分为四种,最后通过旋转恢复平衡 破坏平衡的插入方式 描述 恢复平衡旋转方式 L ...
- 《数据结构与算法分析——C语言描述》ADT实现(NO.04) : AVL树(AVL-Tree)
上次我们已经实现了普通的二叉查找树.利用二叉查找树,可以用O(logN)高度的树状结构存储和查找数据,提高了存储和查找的效率. 然而,考虑一种极端情形:依次插入1,2,3,4,5,6,7,8,9九个元 ...
随机推荐
- WCF初探文章列表
WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...
- 为iOS的mobileconfig文件进行签名
本文主要讲,使用苹果开发者证书进行签名达到目的,本文两种方法,一种是刀耕火种的一步步操作,一种使用脚本签名 一.导出苹果证书进行签名 1.从钥匙串(keychain)中导出证书 实用工具->钥匙 ...
- 高性能Web服务器Nginx的配置与部署研究系列(1)-- 入门 hello work
简介: Nginx 是一个基于 BSD-like 协议.开源.高性能.轻量级的HTTP服务器.反向代理服务器以及电子邮件(SMTP.POP3.IMAP)服务器.Nginx 是由一个俄罗斯的名叫“Igo ...
- Sublime Text 3 中文乱码的解决方法
Sublime Text 3 中文乱码表现如下图: 解决方法很简单,三步搞定: 步骤一: 下载ConvertToUTF8,下载地址:http://pan.baidu.com/s/1gd5SWmB 步骤 ...
- TRANSPOSE的DATA步实现
data a; input name $ a b ; cards; x x x y y y ; run; %macro transpose; proc sql noprint ; select cou ...
- RHEL6.6 PXE安装-基于VMWare WorkStation
///////////第一部分:安装安装服务器 1.先安装一台RHEL6.6的服务器A(地址为192.168.139.132),作为安装服务器.这样后面的机器就可以指向这台服务器进行自动安装 2.在A ...
- Unity3d获取APK签名及公钥的方法
在Unity3d项目中获取APK包签名公钥的方法,核心思想就是通过JNI调用Android提供的方法.不过Unity3d提供了比JNI更上一层的类AndroidJavaObject以及继承它的Andr ...
- 更新App版本的流程
上班一年了还没有自己打包上传过APP,周五下班时项目经理手把手教了我一遍,我大致把流程在这里回顾一下: 1.首先要将svn上的代码拷贝一份到分支上,用终端操作:svn cp https://192.1 ...
- jQuery深层次复制对象
<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min. ...
- HTML 5 <script> 标签
HTML 4.01 与 HTML 5 之间的差异 async 属性是 HTML 5 中的新属性. 在 HTML 5 中,不再支持 HTML 4.01 中的一些属性. 提示和注释 注释:脚本按照如下方式 ...