AVL树是经典的数据结构,它的操作效率很高,一般情况下与红黑树性能相当,而且实现起来没有红黑树繁琐。以前数据结构课上听老师讲过,但没注意听。而最近我在写一个数据库的数据字典部分恰好用到了AVL树,自己把每种情况都推导了一遍,下面是我封装的avl树,可以用于高效存储key/value键值对。
avl.h
#ifndef avl_tree_h
#define avl_tree_h
typedef struct tree_node_t tree_node;
struct tree_node_t {
tree_node_t *left ,*right;
struct {
void *key;
void *value;
}kv;
int height;
int lccount;
int rccount;
};
typedef int(*AVL_KEY_CMP)(void*,void*);
typedef void (*AVL_KEY_FREE)(void*,void*);
typedef struct avl_tree AVL_TREE;
struct avl_tree {
tree_node *root;
int key_num;
AVL_KEY_CMP cmp_func;
AVL_KEY_FREE kv_free;
};
void avl_tree_create(AVL_TREE *tree ,AVL_KEY_CMP cmp ,AVL_KEY_FREE fre);
void avl_tree_free(AVL_TREE *tree);
void avl_tree_insert(AVL_TREE *tree ,void *key ,void *value);
void avl_tree_delete(AVL_TREE *tree ,void *key);
void *avl_tree_search_key(AVL_TREE *tree ,void *key);
tree_node *avl_tree_rank(tree_node *root ,int k);
#define _SWAP_(a,b,type) \
do { \
type _t; \
_t = a; \
a = b; \
b = _t; }while(0)
#endif
avl.cc
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <assert.h>
#include "avl.h"
/*--------------------------------------------------
AVL树实现
树中不允许出现重复关键字
插入,删除,查询,查找第k小的时间复杂度
都为O(log(n))
http://blog.csdn.net/xinghongduo
----------------------------------------------------*/
/*----------------------------
获得一个avl树节点
------------------------------*/
static inline tree_node *avl_tree_node_with_key(void *key ,void *value)
{
tree_node *n = (tree_node*)malloc(sizeof(tree_node));
n->kv.key = key;
n->kv.value = value;
n->height = 1;
n->lccount = 0;
n->rccount = 0;
n->left = n->right = NULL;
return n;
}
/*-------------------------------
计算node结点的高度
---------------------------------*/
inline
int avl_tree_get_node_height(tree_node *node)
{
int m = 0;
if(NULL == node)
return 0;
if(node->left && node->left->height > m) {
m = node->left->height;
}
if(node->right && node->right->height > m) {
m = node->right->height;
}
return m+1;
}
/*-----------------------------------------
以node为根的子树节点数量
-------------------------------------------*/
inline
int avl_tree_node_get_child_count(tree_node *node)
{
int a = 1;
if(NULL == node)
return 0;
if(NULL != node->left) {
a += node->left->lccount + node->left->rccount + 1;
}
if(NULL != node->right) {
a += node->right->lccount + node->right->rccount + 1;
}
return a;
}
/*------------------------
更新节点信息
--------------------------*/
inline
void avl_tree_node_update(tree_node *node)
{
node->height = avl_tree_get_node_height(node);
node->lccount = avl_tree_node_get_child_count(node->left);
node->rccount = avl_tree_node_get_child_count(node->right);
}
/*
调整平衡
*/
static inline tree_node *avl_tree_make_balance(tree_node *root)
{
int balance ,lh ,rh;
tree_node *lc ,*rc ,*t;
lh = avl_tree_get_node_height(root->left);
rh = avl_tree_get_node_height(root->right);
balance = lh - rh;
if(2 == balance) {
lc = root->left;
rc = root->right;
if(avl_tree_get_node_height(root->left->left) >
avl_tree_get_node_height(root->left->right)) {
root->left = lc->right;
lc->right = root;
root = lc;
avl_tree_node_update(root->right);
} else {
t = lc->right;
root->left = t->right;
lc->right = t->left;
t->right = root;
t->left = lc;
root = t;
avl_tree_node_update(lc);
avl_tree_node_update(root->right);
}
} else if(-2 == balance) {
lc = root->left;
rc = root->right;
if(avl_tree_get_node_height(root->right->left) >
avl_tree_get_node_height(root->right->right)) {
t = rc->left;
root->right = t->left;
rc->left = t->right;
t->left = root;
t->right = rc;
root = t;
avl_tree_node_update(root->left);
avl_tree_node_update(root->right);
} else {
root->right = rc->left;
rc->left = root;
root = rc;
avl_tree_node_update(root->left);
}
}
avl_tree_node_update(root);
return root;
}
/*------------------------------------
向avl树中插入一个结点
--------------------------------------*/
static tree_node *avl_tree_insert_(AVL_TREE *tree ,tree_node *root ,tree_node *ins)
{
int cmp_res;
tree_node **p;
assert(tree && ins &&
tree->cmp_func && tree->kv_free);
if(NULL == root) {
tree->key_num++;
return ins;
}
p = &root->left;
cmp_res = tree->cmp_func(ins->kv.key ,root->kv.key);
if(0 == cmp_res) {
/*插入了重复的关键字*/
tree->kv_free(ins->kv.key ,ins->kv.value);
free(ins);
assert(0);
return root;
}
if(0 < cmp_res) {
p = &root->right;
}
if(NULL == *p) {
*p = ins;
tree->key_num++;
} else {
*p = avl_tree_insert_(tree ,*p ,ins);
}
root = avl_tree_make_balance(root);
return root;
}
tree_node *avl_tree_get_max_key(tree_node *root)
{
tree_node *p = root;
while(NULL != p->right) {
p = p->right;
}
return p;
}
tree_node *avl_tree_get_min_key(tree_node *root)
{
tree_node *p = root;
while(NULL != p->left) {
p = p->left;
}
return p;
}
/*--------------------------------------
在avl树中删除一个关键字
----------------------------------------*/
static tree_node *avl_tree_delete_(AVL_TREE *tree ,tree_node *root ,void *key)
{
int cmp_res;
tree_node *t ,**p;
if(NULL == root) return NULL;
p = &root->left;
cmp_res = tree->cmp_func(key ,root->kv.key);
if(0 == cmp_res) {
if(NULL == root->left && NULL == root->right) {
/*删到了叶节点*/
tree->kv_free(root->kv.key ,root->kv.value);
free(root);
tree->key_num--;
return NULL;
}
if(avl_tree_get_node_height(root->left) >=
avl_tree_get_node_height(root->right)) {
t = avl_tree_get_max_key(root->left);
} else {
t = avl_tree_get_min_key(root->right);
p = &root->right;
}
_SWAP_(root->kv.key ,t->kv.key ,void*);
_SWAP_(root->kv.value ,t->kv.value ,void*);
} else {
if(0 < cmp_res) {
p = &root->right;
}
}
*p = avl_tree_delete_(tree ,*p ,key);
root = avl_tree_make_balance(root);
return root;
}
/*
释放avl树的每个结点
*/
static void avl_tree_free_(AVL_TREE *tree ,tree_node *root)
{
if(NULL == root) return;
if(NULL != root->left) {
avl_tree_free_(tree ,root->left);
}
if(NULL != root->right) {
avl_tree_free_(tree ,root->right);
}
tree->kv_free(root->kv.key ,root->kv.value);
free(root);
}
/*--------------------------------
建立空的avl树
----------------------------------*/
void avl_tree_create(AVL_TREE *tree ,AVL_KEY_CMP cmp ,AVL_KEY_FREE fre)
{
assert(tree && cmp && fre);
tree->root = NULL;
tree->cmp_func = cmp;
tree->kv_free = fre;
tree->key_num = 0;
}
/*---------------------------------
释放avl树
----------------------------------*/
void avl_tree_free(AVL_TREE *tree)
{
assert(tree);
avl_tree_free_(tree ,tree->root);
tree->root = NULL;
tree->key_num = 0;
tree->kv_free = NULL;
tree->cmp_func = NULL;
}
/*---------------------------------------
在AVL树中插入一个键值对
-----------------------------------------*/
void avl_tree_insert(AVL_TREE *tree ,void *key ,void *value)
{
tree_node *ins = avl_tree_node_with_key(key ,value);
tree->root = avl_tree_insert_(tree ,tree->root ,ins);
}
/*-------------------------------------
在AVL树中删除一个键值对
---------------------------------------*/
void avl_tree_delete(AVL_TREE *tree ,void *key)
{
tree->root = avl_tree_delete_(tree ,tree->root ,key);
}
/*-------------------------------------
在AVL树中查找关键字
返回key对应的value
--------------------------------------*/
void *avl_tree_search_key(AVL_TREE *tree ,void *key)
{
int cmp_res;
tree_node *p = tree->root;
assert(tree->cmp_func);
while(NULL != p) {
cmp_res = tree->cmp_func(key ,p->kv.key);
if(0 == cmp_res) {
return p->kv.value;
}
if(0 > cmp_res) {
p = p->left;
} else {
p = p->right;
}
}
return NULL;
}
/*
中序遍历
*/
void walk_tree(tree_node *root)
{
if(NULL == root) return;
if(NULL != root->left)
walk_tree(root->left);
printf("%d " ,(int)root->kv.key);
if(NULL != root->right)
walk_tree(root->right);
}
/*--------------------------------
返回第k大个节点
---------------------------------*/
tree_node *avl_tree_rank(tree_node *root ,int k)
{
int lcn = 0;
if(NULL == root)
return NULL;
if(NULL != root->left) {
lcn = root->lccount;
}
if(1 == k-lcn) {
return root;
} else if(1 < k-lcn) {
return avl_tree_rank(root->right ,k-lcn-1);
}
return avl_tree_rank(root->left ,k);
}
int cmp(void *a ,void *b)
{
int ta = (int)a;
int tb = (int)b;
if(a < b) return -1;
else if(a == b) return 0;
return 1;
}
void mfree(void *key ,void *value)
{
}
int main()
{
int i ,t;
AVL_TREE avl;
avl_tree_create(&avl ,cmp ,mfree);
t = clock();
for(i = 1;i <= 10000000 ;i ++) {
avl_tree_insert(&avl ,(void*)i ,(void*)i);
}
for(i = 1;i <= 10000000 ;i ++) {
if(NULL == avl_tree_search_key(&avl ,(void*)i)){
puts("error!");
break;
}
}
for(i = 1 ;i <= 10000000;i ++) {
avl_tree_delete(&avl ,(void*)i);
}
printf("%d\n" ,clock()-t);
avl_tree_free(&avl);
return 0;
}