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;}
- AVL树的实现
- AVL平衡树实现
- AVL树的实现
- AVL树递归实现
- AVL平衡树实现
- AVL树 实现代码
- AVL树的实现
- AVL树实现代码
- AVL 树的实现
- AVL树及其实现
- AVL树C实现
- AVL 树实现
- AVL树的实现
- AVL树 实现代码!
- AVL树实现
- AVL树实现
- AVL树的实现
- AVL树的实现
- Android——进程与线程
- 1015_题目
- 分享:CSS3&HTML5各浏览器支持情况一览表
- GitHub上提供的一个翻页控件
- The process cannot access the file because it is being used by another process.
- AVL树实现
- 如何在Android应用里对HTTP请求头部添加适当的User-Agent字段
- C#序列化与反序化
- Qt学习笔记(二)布局管理
- python学习教程(十一)scrapy框架的搭建
- CAD总算是完整了
- 使用 Antlr 开发领域语言
- java作业代码的分析
- 1014(1)原题目