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); }
/* * ===================================================================================== * * 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