AVL树
来源:http://www.cnblogs.com/JCSU/articles/2026617.html
/*******************************************************************************
/* <PRE>
/* 版权所有 : -
/* 模块名 : 查找
/* 文件名 : avlTree.cpp
/* 功能描述 : 平衡二叉树
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************
/* 数据类型和常量定义
/******************************************************************************/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define LH 1 /* 左高 */
#define EH 0 /* 等高 */
#define RH -1 /* 右高 */
typedef int Status;
typedef int KeyType;
typedef unsigned char Boolean;
/* 数值型关键字的比较 */
#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
/******************************************************************************
/* 数据结构定义
/******************************************************************************/
typedef struct {
KeyType key;
}ElemType;
/* 二叉排序树的类型定义 */
typedef struct BSTNode {
ElemType data;
int bf; /* 结点的平衡因子 */
struct BSTNode *lchild, *rchild; /* 左右孩子指针 */
} BSTNode, *BSTree;
/******************************************************************************
/* 函数原型声明
/******************************************************************************/
void R_Rotate(BSTree &p);
void L_Rotate(BSTree &p);
void RightBalance(BSTree &T);
void LeftBalance(BSTree &T);
Status InsertAVL(BSTree &T, ElemType e, Boolean &taller);
Status Visit(ElemType e);
Status InOrderTraverse(BSTree &T, Status (*Visit)(ElemType));
/*******************************************************************************
/* <FUNC>
/* 函数名 : R_Rotate
/* 功能 : 右旋处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以*p为根的二叉排序树作右旋处理, 处理之后p指向新的树根结点, 即
/* 旋转处理之前的左子树的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void R_Rotate(BSTree &p)
{
BSTree lc;
lc = p->lchild; //lc指向的*p的左子树根结点
p->lchild = lc->rchild; //lc的右子树挂接为*p的左子树
lc->rchild = p; p = lc; //p指向新的根结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : L_Rotate
/* 功能 : 左旋处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以*p为根的二叉排序树作左旋处理, 处理之后p指向新的树根结点, 即
/* 旋转处理之前的右子树的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void L_Rotate(BSTree &p)
{
BSTree rc;
rc = p->rchild; //rc指向的*p的右子树根结点
p->rchild = rc->lchild; //rc的左子树挂接为*p的右子树
rc->lchild = p; p = rc; //p指向新的根结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : InsertBST
/* 功能 : 插入元素到二叉排序树中
/* 参数 : -
/* 返回值 : -
/* 备注 : 当二叉排序树T中不存在关键字等于e.key的数据元素时, 插入e并返回TRUE,
/* 否则返回FALSE
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status InsertAVL(BSTree &T, ElemType e, Boolean &taller)
{
if (!T) { //插入新结点, 树长高, taller为TRUE
T = (BSTree)malloc(sizeof(BSTNode)); T->data = e;
T->lchild = T->rchild = NULL; T->bf = EH; taller = TRUE;
}
else {
if (EQ(e.key, T->data.key)) { taller = FALSE; return 0; } //树中已存在和e有相同关键字的结点, 则不再插入
if (LT(e.key, T->data.key)) { //应继续在*T的左子树中进行搜索
if (!InsertAVL(T->lchild, e, taller)) return 0; //未插入
if (taller) //已插入到*T的左子树中且左子树长高
switch (T->bf) { //检查*T的平衡度
case LH: //原本左子树比右子树高, 需要做左平衡处理
LeftBalance(T); taller = FALSE; break;
case EH: //原本左、右子树等高, 现因左子树增高而使树增高
T->bf = LH; taller = TRUE; break;
case RH: //原本右子树比左子树高, 现在左、右子树等高
T->bf = EH; taller = FALSE; break;
}
}
else { //应继续在*T的右子树中进行搜索
if (!InsertAVL(T->rchild, e, taller)) return 0; //未插入
if (taller) //已插入到*T的右子树中且右子树长高
switch (T->bf) { //检查*T的平衡度
case LH: //原本左子树比右子树高, 现在左、右子树等高
T->bf = EH; taller = FALSE; break;
case EH: //原本左、右子树等高, 现因右子树增高而使树增高
T->bf = RH; taller = TRUE; break;
case RH: //原本右子树比左子树高, 需要做右平衡处理
RightBalance(T); taller = FALSE; break;
}
}
}
return 1;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : LeftBalance
/* 功能 : 左平衡旋转处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以指针T所指结点为根的二叉树作左平衡旋转处理, 本算法结束时, 指针
/* T指向新的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void LeftBalance(BSTree &T)
{
BSTree lc; BSTree rd;
lc = T->lchild; //lc指向*T的左子树根结点
switch (lc->bf) //检查*T的左子树的平衡度, 并作相应平衡处理
{
case LH: //新结点插入在*T的左孩子的左子树上, 要作单右旋处理
T->bf = lc->bf = EH;
R_Rotate(T); break;
case RH: //新结点插入在*T的左孩子的右子树上, 要作双旋处理
rd = lc->rchild; //rd指向*T人左孩子的右子树根
switch (rd->bf) //修正*T及其左孩子的平衡因子
{
case LH: T->bf = RH; lc->bf = EH; break;
case EH: T->bf = lc->bf = EH; break;
case RH: T->bf = EH; lc->bf = LH; break;
}
rd->bf = EH;
L_Rotate(T->lchild); //对*T的左子树作左旋平衡处理
R_Rotate(T); //对*T作右旋平衡处理
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : RightBalance
/* 功能 : 右平衡旋转处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以指针T所指结点为根的二叉树作右平衡旋转处理, 本算法结束时, 指针
/* T指向新的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void RightBalance(BSTree &T)
{
BSTree rc; BSTree ld;
rc = T->rchild; //lc指向*T的右子树根结点
switch (rc->bf) //检查*T的右子树的平衡度, 并作相应平衡处理
{
case RH: //新结点插入在*T的右孩子的左子树上, 要作单左旋处理
T->bf = rc->bf = EH;
L_Rotate(T); break;
case LH: //新结点插入在*T的右孩子的右子树上, 要作双旋处理
ld = rc->lchild; //ld指向*T人右孩子的右子树根
switch (ld->bf) //修正*T及其右孩子的平衡因子
{
case RH: T->bf = RH; rc->bf = EH; break;
case EH: T->bf = rc->bf = EH; break;
case LH: T->bf = EH; rc->bf = LH; break;
}
ld->bf = EH;
R_Rotate(T->rchild); //对*T的右子树作右旋平衡处理
L_Rotate(T); //对*T作左旋平衡处理
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Visit
/* 功能 : 打印节点数据
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status Visit(ElemType e)
{
printf("%d ", e.key);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : InOrderTraverse
/* 功能 : 中序遍历二叉树
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status InOrderTraverse(BSTree &T, Status (*Visit)(ElemType))
{
if(T){
if(InOrderTraverse(T->lchild, Visit))
if(Visit(T->data))
if(InOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
BSTree T; ElemType e; Boolean taller;
T = NULL;
e.key = 13; InsertAVL(T, e, taller);
e.key = 24; InsertAVL(T, e, taller);
e.key = 37; InsertAVL(T, e, taller);
e.key = 90; InsertAVL(T, e, taller);
e.key = 53; InsertAVL(T, e, taller);
InOrderTraverse(T, Visit);
}
/* <PRE>
/* 版权所有 : -
/* 模块名 : 查找
/* 文件名 : avlTree.cpp
/* 功能描述 : 平衡二叉树
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************
/* 数据类型和常量定义
/******************************************************************************/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define LH 1 /* 左高 */
#define EH 0 /* 等高 */
#define RH -1 /* 右高 */
typedef int Status;
typedef int KeyType;
typedef unsigned char Boolean;
/* 数值型关键字的比较 */
#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
/******************************************************************************
/* 数据结构定义
/******************************************************************************/
typedef struct {
KeyType key;
}ElemType;
/* 二叉排序树的类型定义 */
typedef struct BSTNode {
ElemType data;
int bf; /* 结点的平衡因子 */
struct BSTNode *lchild, *rchild; /* 左右孩子指针 */
} BSTNode, *BSTree;
/******************************************************************************
/* 函数原型声明
/******************************************************************************/
void R_Rotate(BSTree &p);
void L_Rotate(BSTree &p);
void RightBalance(BSTree &T);
void LeftBalance(BSTree &T);
Status InsertAVL(BSTree &T, ElemType e, Boolean &taller);
Status Visit(ElemType e);
Status InOrderTraverse(BSTree &T, Status (*Visit)(ElemType));
/*******************************************************************************
/* <FUNC>
/* 函数名 : R_Rotate
/* 功能 : 右旋处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以*p为根的二叉排序树作右旋处理, 处理之后p指向新的树根结点, 即
/* 旋转处理之前的左子树的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void R_Rotate(BSTree &p)
{
BSTree lc;
lc = p->lchild; //lc指向的*p的左子树根结点
p->lchild = lc->rchild; //lc的右子树挂接为*p的左子树
lc->rchild = p; p = lc; //p指向新的根结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : L_Rotate
/* 功能 : 左旋处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以*p为根的二叉排序树作左旋处理, 处理之后p指向新的树根结点, 即
/* 旋转处理之前的右子树的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void L_Rotate(BSTree &p)
{
BSTree rc;
rc = p->rchild; //rc指向的*p的右子树根结点
p->rchild = rc->lchild; //rc的左子树挂接为*p的右子树
rc->lchild = p; p = rc; //p指向新的根结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : InsertBST
/* 功能 : 插入元素到二叉排序树中
/* 参数 : -
/* 返回值 : -
/* 备注 : 当二叉排序树T中不存在关键字等于e.key的数据元素时, 插入e并返回TRUE,
/* 否则返回FALSE
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status InsertAVL(BSTree &T, ElemType e, Boolean &taller)
{
if (!T) { //插入新结点, 树长高, taller为TRUE
T = (BSTree)malloc(sizeof(BSTNode)); T->data = e;
T->lchild = T->rchild = NULL; T->bf = EH; taller = TRUE;
}
else {
if (EQ(e.key, T->data.key)) { taller = FALSE; return 0; } //树中已存在和e有相同关键字的结点, 则不再插入
if (LT(e.key, T->data.key)) { //应继续在*T的左子树中进行搜索
if (!InsertAVL(T->lchild, e, taller)) return 0; //未插入
if (taller) //已插入到*T的左子树中且左子树长高
switch (T->bf) { //检查*T的平衡度
case LH: //原本左子树比右子树高, 需要做左平衡处理
LeftBalance(T); taller = FALSE; break;
case EH: //原本左、右子树等高, 现因左子树增高而使树增高
T->bf = LH; taller = TRUE; break;
case RH: //原本右子树比左子树高, 现在左、右子树等高
T->bf = EH; taller = FALSE; break;
}
}
else { //应继续在*T的右子树中进行搜索
if (!InsertAVL(T->rchild, e, taller)) return 0; //未插入
if (taller) //已插入到*T的右子树中且右子树长高
switch (T->bf) { //检查*T的平衡度
case LH: //原本左子树比右子树高, 现在左、右子树等高
T->bf = EH; taller = FALSE; break;
case EH: //原本左、右子树等高, 现因右子树增高而使树增高
T->bf = RH; taller = TRUE; break;
case RH: //原本右子树比左子树高, 需要做右平衡处理
RightBalance(T); taller = FALSE; break;
}
}
}
return 1;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : LeftBalance
/* 功能 : 左平衡旋转处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以指针T所指结点为根的二叉树作左平衡旋转处理, 本算法结束时, 指针
/* T指向新的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void LeftBalance(BSTree &T)
{
BSTree lc; BSTree rd;
lc = T->lchild; //lc指向*T的左子树根结点
switch (lc->bf) //检查*T的左子树的平衡度, 并作相应平衡处理
{
case LH: //新结点插入在*T的左孩子的左子树上, 要作单右旋处理
T->bf = lc->bf = EH;
R_Rotate(T); break;
case RH: //新结点插入在*T的左孩子的右子树上, 要作双旋处理
rd = lc->rchild; //rd指向*T人左孩子的右子树根
switch (rd->bf) //修正*T及其左孩子的平衡因子
{
case LH: T->bf = RH; lc->bf = EH; break;
case EH: T->bf = lc->bf = EH; break;
case RH: T->bf = EH; lc->bf = LH; break;
}
rd->bf = EH;
L_Rotate(T->lchild); //对*T的左子树作左旋平衡处理
R_Rotate(T); //对*T作右旋平衡处理
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : RightBalance
/* 功能 : 右平衡旋转处理
/* 参数 : -
/* 返回值 : -
/* 备注 : 对以指针T所指结点为根的二叉树作右平衡旋转处理, 本算法结束时, 指针
/* T指向新的根结点
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void RightBalance(BSTree &T)
{
BSTree rc; BSTree ld;
rc = T->rchild; //lc指向*T的右子树根结点
switch (rc->bf) //检查*T的右子树的平衡度, 并作相应平衡处理
{
case RH: //新结点插入在*T的右孩子的左子树上, 要作单左旋处理
T->bf = rc->bf = EH;
L_Rotate(T); break;
case LH: //新结点插入在*T的右孩子的右子树上, 要作双旋处理
ld = rc->lchild; //ld指向*T人右孩子的右子树根
switch (ld->bf) //修正*T及其右孩子的平衡因子
{
case RH: T->bf = RH; rc->bf = EH; break;
case EH: T->bf = rc->bf = EH; break;
case LH: T->bf = EH; rc->bf = LH; break;
}
ld->bf = EH;
R_Rotate(T->rchild); //对*T的右子树作右旋平衡处理
L_Rotate(T); //对*T作左旋平衡处理
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Visit
/* 功能 : 打印节点数据
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status Visit(ElemType e)
{
printf("%d ", e.key);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : InOrderTraverse
/* 功能 : 中序遍历二叉树
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status InOrderTraverse(BSTree &T, Status (*Visit)(ElemType))
{
if(T){
if(InOrderTraverse(T->lchild, Visit))
if(Visit(T->data))
if(InOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
BSTree T; ElemType e; Boolean taller;
T = NULL;
e.key = 13; InsertAVL(T, e, taller);
e.key = 24; InsertAVL(T, e, taller);
e.key = 37; InsertAVL(T, e, taller);
e.key = 90; InsertAVL(T, e, taller);
e.key = 53; InsertAVL(T, e, taller);
InOrderTraverse(T, Visit);
}
【参考】
微信公众号:
猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。