AVL树实现

来源:互联网 发布:淘宝店数据包怎么做 编辑:程序博客网 时间:2024/06/11 17:58

AVL树是经典的数据结构,它的操作效率很高,一般情况下与红黑树性能相当,而且实现起来没有红黑树繁琐。以前数据结构课上听老师讲过,但没注意听可怜。而最近我在写一个数据库的数据字典部分恰好用到了AVL树,自己把每种情况都推导了一遍,下面是我封装的avl树,可以用于高效存储key/value键值对。

 

avl.h

#ifndef avl_tree_h#define avl_tree_htypedef 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结点的高度---------------------------------*/inlineint 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为根的子树节点数量-------------------------------------------*/inlineint 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;}/*------------------------更新节点信息--------------------------*/inlinevoid 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;}


 

原创粉丝点击