您的位置:首页 > 运维架构

AVL Operation

2013-01-05 16:09 162 查看
AVL本质是一棵二叉搜索树,为了改进二叉搜索树的效率,将其平衡化处理。所谓的AVL算法是又两名俄罗斯人在20世纪60年代提出,由他们的名字命名的。数据结构书上都会介绍这个算法,其原理比较直观,但是好像完整实现的源码不算多,此处补上一份。贴出的大部分源码来自由Mark Allen Weiss所著的由冯舜玺所译的《数据结构与算法分析——C语言描述》一书,删除算法(delete)则由我自己独立思考完成。

/*
* szlavltree.h
*/
#ifndef Avl_Tree_H
#define Avl_Tree_H

#define ElementType int

struct AvlNode;
typedef struct AvlNode* Position;
typedef struct AvlNode* AvlTree;

void 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 Print(AvlTree T);
int TreeHeight(AvlTree T);

#endif

/*
* szlavltree.c
*/
#include "szlavltree.h"
#include "stdio.h"
#include <assert.h>
#include <stdlib.h>
#define Max(a,b) ((a)>(b)?(a):(b)) //the outermost paratheses are necessary

static int Height(Position );
static Position SingleRotateWithLeft(Position );
static Position SingleRotateWithRight(Position );
static Position DoubleRotateWithLeft(Position );
static Position DoubleRotateWithRight(Position );
static void PrintA(AvlTree T, int layer);

struct AvlNode{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};

int
TreeHeight(AvlTree T){
return Height(T);
}

AvlTree
Insert(ElementType X, AvlTree T){
if(NULL == T){
T=(AvlTree)malloc(sizeof(struct AvlNode));
assert(NULL != T);
T->Left=NULL;
T->Right=NULL;
T->Element=X;
T->Height=0;
return T;
}
else if(X<T->Element){
T->Left=Insert(X,T->Left);
if(Height(T->Left)-Height(T->Right)==2){
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)==2){
if(X>=T->Right->Element){
T=SingleRotateWithRight(T);
}
else{
T=DoubleRotateWithRight(T);
}
}
}
//else X is in the tree, we will do nothing.
T->Height=Max(Height(T->Left),Height(T->Right))+1;
return T;
}

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))+1;
K1->Height=Max(Height(K1->Left),K2->Height)+1;
return K1;
}

static Position
SingleRotateWithRight(Position K2){
Position K1;
K1=K2->Right;
K2->Right=K1->Left;
K1->Left=K2;
K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Right),K2->Height)+1;
return K1;
}

static Position
DoubleRotateWithLeft(Position K3){
K3->Left=SingleRotateWithRight(K3->Left);
return SingleRotateWithLeft(K3);
}

static Position
DoubleRotateWithRight(Position K1){
K1->Right=SingleRotateWithLeft(K1->Right);
return SingleRotateWithRight(K1);
}

static int
Height(Position P){
if(NULL == P){
return -1;
}
else{
return P->Height;
}
}

void MakeEmpty(AvlTree T){
if(NULL!=T){
AvlTree left=T->Left;
AvlTree right=T->Right;
free(T);
MakeEmpty(left);
MakeEmpty(right);
}
}

Position
Find(ElementType X, AvlTree T){
if(NULL==T){
return NULL;
}
if(X==T->Element){
return T;
}
else if(X<T->Element){
return Find(X,T->Left);
}
else{
return Find(X,T->Right);
}
}

Position
FindMin(AvlTree T){
if(NULL==T){
return NULL;
}
else if(NULL==T->Left){
return T;
}
else{
return FindMin(T->Left);
}
}

Position
FindMax(AvlTree T){
if(NULL==T){
return NULL;
}
else if(NULL==T->Right){
return T;
}
else{
return FindMax(T->Right);
}
}

AvlTree
Delete(ElementType X, AvlTree T){
if(NULL==T){
return NULL;
}
else{
if(X==T->Element){//if the current node is what we want to delete
if(Height(T->Left)>Height(T->Right)){//delete from the subtree with larger Height, this would help protect the tree is still AVL tree.
Position leftMax=FindMax(T->Left);
T->Element=leftMax->Element;
leftMax->Element=X;
T->Left=Delete(X,T->Left);
}
else if(Height(T->Left)<Height(T->Right)){
Position rightMin=FindMin(T->Right);
T->Element=rightMin->Element;
rightMin->Element=X;
T->Right=Delete(X,T->Right);
}
else{ //Height(T->Left == Height(T->Right)
if(NULL!=T->Left){//NULL!=T->Left && NULL!=T->Right
Position rightMin=FindMin(T->Right);
T->Element=rightMin->Element;
rightMin->Element=X;
T->Right=Delete(X,T->Right);
}
else{//NULL==T->Left && NULL == T->Right
free(T);
T=NULL;
}
}
}// the deletion of current node promise that after the operation the tree is still an AVL tree.
else{//X!=T->Element
if(X<T->Element){//delete from the left sub tree, which could lead to the root tree node unbalanced. So we need to rotate it to
//	guarantee it is an AVL tree.
T->Left=Delete(X,T->Left);
if(2==Height(T->Right)-Height(T->Left)){
T=SingleRotateWithRight(T);
}
}
else{//X>T->Element, delete from the right sub tree
T->Right=Delete(X,T->Right);
if(2==Height(T->Left)-Height(T->Right)){
T=SingleRotateWithLeft(T);
}
}
}

//adjust the Height of the tree
if(NULL!=T){
T->Height=Max(Height(T->Left),Height(T->Right))+1;
}
return T;
}
}

ElementType
Retrieve(Position P){
assert(NULL!=P);
return P->Element;
}

void
Print(AvlTree T){
PrintA(T,0);
}

static void
PrintA(AvlTree T, int layer){
int l=layer;
if(NULL==T){
#ifdef MODE1
printf("%s:%d\n",__FUNCTION__, __LINE__);
#endif
return;
}
while(l!=0){
printf(" ");
if(1<l){
printf("|");
}
l--;
}
printf("|-%d\n",(int)(T->Element));
if(NULL!=T->Left){
PrintA(T->Left,layer+1);
}
if(NULL!=T->Right){
PrintA(T->Right,layer+1);
}
}

/*
* main.c
*/
#include "szlavltree.h"
#include <stdio.h>
#define MAX (10)
main(){
int i=0;
int a;
int n=MAX;
#ifdef N
n=N;
#endif
AvlTree T=NULL;
for(;i<n;i++){
//scanf("%d",&a);
a=n-i;
T=Insert(a,T);
}
if(NULL==T){
puts("Build failed.");
}
Print(T);
puts("Deletion: -1 means end of input");
while(1){
printf("Delete X=");
scanf("%d",&a);
if(-1!=a){
Delete(a,T);
}
else{
break;
}
}
Print(T);

printf("Height=%d, MAX=%d, MIN=%d\n",TreeHeight(T),Retrieve(FindMax(T)),Retrieve(FindMin(T)));
MakeEmpty(T);
}


在linux下编译:

# gcc -DN=16 szlavltree.c main.c

# ./a.out

|-9

 |-5

 | |-3

 | | |-2

 | | | |-1

 | | |-4

 | |-7

 | | |-6

 | | |-8

 |-13

 | |-11

 | | |-10

 | | |-12

 | |-15

 | | |-14

 | | |-16

Deletion: -1 means end of input

Delete X=9

Delete X=13

Delete X=7

Delete X=-1

|-8

 |-3

 | |-2

 | | |-1

 | |-5

 | | |-4

 | | |-6

 |-14

 | |-11

 | | |-10

 | | |-12

 | |-15

 | | |-16

Height=3, MAX=16, MIN=1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  avl