本文主对以前在优快云上发表的平衡树进行改进,修正了一个bug,并且树节点数据改为void*.另外平衡树的内存管理采用了非分页的内存,应用在驱动编程中.此算法已经应用于一个map的实现,经过了测试.如果想将平衡树应用于用户模式下,可以把头文件中的_KERNAL_MODE_定义去掉,然后包含头文件 stdlib.h .如果还有bug,欢迎联系我修正 msn:felix_lzq@hotmail.com
//
/// @file _AVLTree.h
/// @author liuzongqiang
/// @date 2008-8-19-17:00
///
/// @brief AVL平衡树的c语言实现,采用非分页内存
//
#ifndef ___AVLTREE___
#define ___AVLTREE___
#define _KERNAL_MODE_
#ifdef _KERNAL_MODE_
#include "wdm.h"
#define AVL_Allocate(size) ExAllocatePool( NonPagedPool , (size))
#define AVL_Free(paddr) ExFreePool(paddr)
#else
#define AVL_Allocate(size) malloc((size))
#define AVL_Free(paddr) free(paddr)
#endif
#ifdef __cplusplus
#define _AVL_INLENE inline
#else
#define _AVL_INLENE
#endif
typedef void* AVL_Element;
typedef ULONG AVL_Key ;
extern struct AVL_TreeNode;
typedef struct AVL_TreeNode *AVL_Tree;
typedef struct AVL_TreeNode *AVL_Position;
typedef size_t AVL_Size;
AVL_Tree AVL_MakeEmpty(AVL_Tree t);
AVL_Position AVL_Find(AVL_Key e,AVL_Tree t);
AVL_Position AVL_FindMin(AVL_Tree t);
AVL_Position AVL_FindMax(AVL_Tree t);
AVL_Tree AVL_Delete(AVL_Key e ,AVL_Tree t);
AVL_Tree AVL_Insert(AVL_Element e ,AVL_Tree t);
AVL_Element AVL_Retrieve(AVL_Position p);
AVL_Size AVL_GetSize(AVL_Tree t );
#endif
//
/// @file _AVLTree.cpp
/// @author liuzongqiang
/// @date 2008-8-19-17:00
///
/// @brief AVL平衡树的c语言实现,采用非分页内存
//
#include "_AVLTree.h"
#define MAX(a,b) ((a>b)?a:b)
/*Assume that e is a "void *" pointer*/
#define AVL_KEY(e) (*((ULONG*)(e)))
struct AVL_TreeNode
{
int height;
AVL_Element e;
AVL_Tree left;
AVL_Tree right;
};
static _AVL_INLENE int Height(AVL_Position p)
{
if(p)
return p->height;
return -1;
}
/*rotate function*/
AVL_Position AVL_SingleRotateLeft(AVL_Position p)
{
AVL_Position tmp;
tmp = p->left;
p->left = tmp->right;
tmp->right = p;
p->height = MAX(Height(p->left) , Height(p->right)) + 1;
tmp->height = MAX(Height(tmp->left) , p->height);
return tmp;
}
AVL_Position AVL_SingleRotateRight(AVL_Position p)
{
AVL_Position tmp;
tmp = p->right;
p->right = tmp->left;
tmp->left = p;
p->height = MAX(Height(p->left) , Height(p->right))+1;
tmp->height = MAX(p->height , Height(tmp->right));
return tmp;
}
AVL_Position AVL_DoubleRotateRight(AVL_Position p)
{
p->right = AVL_SingleRotateLeft(p->right);
return AVL_SingleRotateRight(p);
}
AVL_Position AVL_DoubleRotateLeft(AVL_Position p)
{
p->left = AVL_SingleRotateRight(p->left);
return AVL_SingleRotateLeft(p);
}
AVL_Tree AVL_MakeEmpty(AVL_Tree t)
{
if(t)
{
AVL_MakeEmpty(t->left);
AVL_MakeEmpty(t->right);
AVL_Free(t);
}
return NULL;
}
AVL_Position AVL_Find(AVL_Key key , AVL_Tree t)
{
if(t)
{
if(key>AVL_KEY(t->e))
return AVL_Find(key , t->right);
else if(key<AVL_KEY(t->e))
return AVL_Find(key , t->left);
else
return (AVL_Position)t;
}
else return NULL;
}
/*find the minimum element*/
AVL_Position AVL_FindMin(AVL_Tree t)
{
if(t)
while(t->left)
t = t->left;
return (AVL_Position)t;
}
/*find the maximum element*/
AVL_Position AVL_FindMax(AVL_Tree t)
{
if(t)
while(t->right)
t = t->right;
return (AVL_Position)t;
}
static AVL_Tree AVL_Rebalance(AVL_Position p)
{
if ( NULL == p)
{
return NULL ;
}
if(Height(p->left)-Height(p->right)==2)
{
if(Height(p->left->left)>Height(p->left->right))/*LL**/
{
return AVL_SingleRotateLeft(p);
}
else/*LR*/
{
return AVL_DoubleRotateLeft(p);
}
}
else
if(Height(p->left)-Height(p->right)==-2)
{
if(Height(p->right->right)>Height(p->right->left))/*RR**/
{
return AVL_SingleRotateRight(p);
}/*RL*/
else
{
return AVL_DoubleRotateRight(p);
}
}
return p;
}
static AVL_Tree AVL_DeleteMin(AVL_Tree t)
{
if(t->left){
t = AVL_DeleteMin(t->left);
return AVL_Rebalance(t);
}
else
{
AVL_Free(t);
return NULL;
}
}
AVL_Tree AVL_Delete(AVL_Key key , AVL_Tree t)
{
AVL_Position p = NULL ;
if(t)
{
if(key>AVL_KEY(t->e))
t->right = AVL_Delete(key , t->right);
else if(key<AVL_KEY(t->e))
t->left = AVL_Delete(key , t->left);
/*find it*/
else if(t->left&&t->right)
{
p = AVL_FindMin(t->right);
t->e = p->e;
t->right = AVL_DeleteMin(t->right);
}
else
{
p = t;
if(t->left==NULL)
t = t->right;
else
t = t->left;
AVL_Free(p);
}
}
return AVL_Rebalance(t);
}
AVL_Tree AVL_Insert(AVL_Element e , AVL_Tree t)
{
ASSERT( NULL != e );
if(t==NULL)/*insert as leaf child*/
{
t = (AVL_Tree)AVL_Allocate(NonPagedPool , sizeof(struct AVL_TreeNode));
if ( NULL == t)
return NULL;
t->e = e;
t->left = t->right = NULL;
t->height = 0;
}
else
if(AVL_KEY(e)>AVL_KEY(t->e))
{
t->right = AVL_Insert(e , t->right);
if(Height(t->right)-Height(t->left)==2)
{
if(AVL_KEY(e)>AVL_KEY(t->right->e))
t = AVL_SingleRotateRight(t);
else
t = AVL_DoubleRotateRight(t);
}
}
else if(AVL_KEY(e)<AVL_KEY(t->e))
{
t->left = AVL_Insert(e , t->left);
if(Height(t->left)-Height(t->right)==2)
{
if(AVL_KEY(e)<AVL_KEY(t->left->e))
t = AVL_SingleRotateLeft(t);
else
t = AVL_DoubleRotateLeft(t);
}
}
else
{
t->e = e;
}
t->height = MAX(Height(t->left) , Height(t->right))+1;
return t;
}
AVL_Element AVL_Retrieve(AVL_Position p)
{
ASSERT( NULL != p ) ;
return p->e;
}
AVL_Size AVL_GetSize(AVL_Tree t )
{
if ( NULL == t )
{
return 0 ;
}
return AVL_GetSize(t->left) + AVL_GetSize(t->right) + 1;
}