AVL 树实现

AVL树是一种带平衡条件的查找树。一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树。前一篇文章给出了二叉树查找树的基本实现,AVL树的大部分实现都与普通的二叉查找树相同。

参考《数据结构与算法分析——C语言描述》。

avlTree.h

/*
 * =====================================================================================
 *
 *       Filename:  avlTree.h
 *
 *    Description:  AVL tree implemention
 *
 *        Version:  1.0
 *        Created:  11/09/2012 08:44:53 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  xhzuoxin (), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */
#ifndef _AVLTREE_H
#define _AVLTREE_H

#include <stdio.h>
#include <stdlib.h>
#include "types.h"

typedef UINT16 EleType;
struct AvlNode
{
	EleType ele;
	struct AvlNode* left;
	struct AvlNode* right;
	UINT16 height;
};
typedef struct AvlNode* Position;
typedef struct AvlNode* AvlTree;

extern AvlTree MakeEmpty(AvlTree T);
extern Position Find(EleType X, AvlTree T);
extern Position FindMax(AvlTree T);
extern Position FindMin(AvlTree T);
extern AvlTree Insert(EleType X, AvlTree T);
extern AvlTree Delete(EleType X, AvlTree T);

#endif

avlTree.c

/*
 * =====================================================================================
 *
 *       Filename:  avlTree.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  11/09/2012 08:51:16 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  xhzuoxin (), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */
#include "avlTree.h"


#define MAX(A, B)           ((A > B) ? (A) : (B))
#define MIN(A, B)           ((A < B) ? (A) : (B))
/*-----------------------------------------------------------------------------
 *  local functions
 *-----------------------------------------------------------------------------*/
static int Height(Position P);
static Position SRL(Position K2);
static Position DRL(Position K3);
static Position SRR(Position K2);
static Position DRR(Position K3);

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  MakeEmpty
 *  Description:  Init AvlTree as NULL
 * =====================================================================================
 */
AvlTree MakeEmpty(AvlTree T)
{
	if(T != NULL)
	{
		MakeEmpty(T->left);
		MakeEmpty(T->right);
		free(T);
	}

	return T;
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Find
 *  Description:  Find element X from AvlTree, return pointer of the element
 * =====================================================================================
 */
Position Find(EleType X, AvlTree T)
{
	if(T == NULL)
	{
		return NULL;
	}
	else if(X < T->ele)
	{
		return Find(X, T->left);
	}
	else if(X > T->right)
	{
		return Find(X, T->right);
	}
	else
	{
		return T;
	}
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  FindMax
 *  Description:  Find max element's pointer in a AvlTree
 * =====================================================================================
 */
Position FindMax(AvlTree T)
{
	if(T == NULL)
	{
		return NULL;
	}
	else if(T->right == NULL)
	{
		return T;
	}
	else
	{
		return FindMax(T->right);
	}
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  FindMin
 *  Description:  Find min element's pointer in a AvlTree
 * =====================================================================================
 */
Position FindMin(AvlTree T)
{
	if(T == NULL)
	{
		return NULL;
	}
	else if(T->left == NULL)
	{
		return T;
	}
	else 
	{
		return FindMin(T->left);
	}
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Insert
 *  Description:  Insert a element to the AvlTree, be sure to keep the banlance of tree
 * =====================================================================================
 */
AvlTree Insert(EleType X, AvlTree T)
{
	if(T == NULL)
	{
		/* create and return a one-node tree */
		T = (AvlTree)malloc(sizeof(struct AvlNode));
		if(T == NULL)
		{
			printf("error:alloc space failure!\n");
			return NULL;
		}
		T->ele = X;
		T->height = 0;
		T->left = T->right = NULL;
	}
	else if(X < T->ele)
	{
		T->left = Insert(X, T->left);
		if((Height(T->left) - Height(T->right)) >= 2)
		{
			if(X < T->left->ele)
			{
				T = SRL(T);
			}
			else
			{
				T = DRL(T);
			}
		}
	
	}	
	else if(X > T->ele)
	{
		T->right = Insert(X, T->right);
		if((Height(T->right) - Height(T->left)) >= 2)
		{
			if(X > T->right->ele)
			{
				T = SRR(T);
			}
			else
			{
				T = DRR(T);
			}
		}
	}
	else
	{
		// do nothing for the Element is already in the tree
	}

	T->height = MAX(Height(T->left), Height(T->right)) + 1;

	return T;
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  Height
 *  Description:  reurn height of position P
 * =====================================================================================
 */
static int Height(Position P)
{
	if(P == NULL)
	{
		return -1;
	}
	else
	{
		return P->height;
	}
}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  SRL
 *  Description:  Single Rotate with Left
 *  K2 - the node that not keep balance
 *  K1 - new root repalce K2
 * =====================================================================================
 */
static Position SRL(Position K2)
{
	Position K1 = NULL;

	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), Height(K2)) + 1;

	return K1;  /* new root */
}


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  SRR
 *  Description:  Single Rotate With Right
 *  K2 - the node that not keep balance after insert
 *  K1 - return new root replace K2
 * =====================================================================================
 */
static Position SRR(Position K2)
{
	Position K1 = NULL;

	K1 = K2->right;
	K2->right = K1->left;
	K1->left = K2;

	K2->height = MAX(Height(K2->left), Height(K2->right)) + 1;
	K1->height = MAX(Height(K2), Height(K1->right)) + 1;

	return K1;  /* new root */
}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  DRL
 *  Description:  This function can be called only if K3 has a left child 
 *  and K3's left child has a right child.
 *  Do the left-right double rotation.
 *  Update heights, then return new root.
 * =====================================================================================
 */
static Position DRL(Position K3)
{
	/* Rotate between K1 and K2 */
	K3->left = SRR(K3->left);

	/* Rotate between K3 and K2 */
	return SRL(K3);
}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  DRL
 *  Description:  This function can be called only if K3 has a right child 
 *  and K3's right child has a left child.
 *  Do the left-right double rotation.
 *  Update heights, then return new root.
 * =====================================================================================
 */
static Position DRR(Position K3)
{
	/* Rotate between K1 and K2 */
	K3->right = SRL(K3->right);

	/* Rotate between K3 and K2 */
	return SRR(K3);
}

test.c

/*
 * =====================================================================================
 *
 *       Filename:  test.c
 *
 *    Description:  test avlTree file
 *
 *        Version:  1.0
 *        Created:  11/12/2012 06:37:34 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  xhzuoxin (), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */
#include <stdio.h>
#include "avlTree.h"

void PrintTree(AvlTree T)
{
	if(T != NULL)
	{
		PrintTree(T->left);
		printf("h=%d, e=%d\n", T->height, T->ele);
		PrintTree(T->right);
	}
}

int main(void)
{
	AvlTree T = NULL;

	T = MakeEmpty(T);
	T = Insert(3, T);
	T = Insert(2, T);
	T = Insert(1, T);
	T = Insert(4, T);
	T = Insert(5, T);
	T = Insert(6, T);
	T = Insert(7, T);
	T = Insert(16, T);
	T = Insert(15, T);
	T = Insert(14, T);
	T = Insert(13, T);
	T = Insert(12, T);
	T = Insert(11, T);
	T = Insert(10, T);
	T = Insert(8, T);
	T = Insert(9, T);

	PrintTree(T);

	return 0;
}

gcc编译所使用的makefile文件如下:

SRC=avlTree.c avlTree.h test.c

all:$(SRC)
	gcc -g -Wall $^ -o $@

.PHONY:clean tags run
clean:
	rm *.o all *~
tags:
	ctags -R --c++-kinds=+p --fields=+iaS --extra=+q
run:
	./all
最终输出结果(h表示节点高度,e表示节点元素值): h=0, e=1
h=1, e=2
h=0, e=3
h=2, e=4
h=0, e=5
h=1, e=6
h=4, e=7
h=0, e=8
h=1, e=9
h=0, e=10
h=2, e=11
h=0, e=12
h=3, e=13
h=0, e=14
h=1, e=15
h=0, e=16

你可能感兴趣的:(实现)