AVL树实现

AVL树是经典的数据结构,它的操作效率很高,一般情况下与红黑树性能相当,而且实现起来没有红黑树繁琐。以前数据结构课上听老师讲过,但没注意听《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;
}

 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/xinghongduo/article/details/12713795
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞