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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVL树是一种自平衡二叉搜索树,可以用来实现字典类型。在实现字典类型时,我们可以将键值对存储在AVL树的节点中,其中键作为节点的关键字,值则作为节点的附加数据。 下面是一个简单的AVL树实现字典类型的Python代码: ```python class AVLNode: def __init__(self, key, val): self.key = key self.val = val self.left = None self.right = None self.height = 1 class AVLTree: def __init__(self): self.root = None def insert(self, key, val): self.root = self._insert(self.root, key, val) def _insert(self, node, key, val): if not node: return AVLNode(key, val) if key < node.key: node.left = self._insert(node.left, key, val) elif key > node.key: node.right = self._insert(node.right, key, val) else: node.val = val node.height = 1 + max(self._height(node.left), self._height(node.right)) balance = self._get_balance(node) if balance > 1 and key < node.left.key: return self._right_rotate(node) if balance < -1 and key > node.right.key: return self._left_rotate(node) if balance > 1 and key > node.left.key: node.left = self._left_rotate(node.left) return self._right_rotate(node) if balance < -1 and key < node.right.key: node.right = self._right_rotate(node.right) return self._left_rotate(node) return node def search(self, key): node = self._search(self.root, key) if node: return node.val else: return None def _search(self, node, key): if not node: return None if key == node.key: return node if key < node.key: return self._search(node.left, key) else: return self._search(node.right, key) def _height(self, node): if not node: return 0 return node.height def _get_balance(self, node): if not node: return 0 return self._height(node.left) - self._height(node.right) def _left_rotate(self, node): new_root = node.right node.right = new_root.left new_root.left = node node.height = 1 + max(self._height(node.left), self._height(node.right)) new_root.height = 1 + max(self._height(new_root.left), self._height(new_root.right)) return new_root def _right_rotate(self, node): new_root = node.left node.left = new_root.right new_root.right = node node.height = 1 + max(self._height(node.left), self._height(node.right)) new_root.height = 1 + max(self._height(new_root.left), self._height(new_root.right)) return new_root ``` 在这个实现中,我们定义了AVLNode类来表示AVL树的节点。每个节点包含一个键、一个值、左右子树指针以及节点高度。AVLTree类是AVL树实现,包含了插入、搜索、左旋和右旋等基本操作。 在insert操作中,我们首先按照二叉搜索树的规则找到要插入的位置。然后更新节点高度,并计算平衡因子。如果平衡因子超过了1或-1,我们就需要进行旋转来保持AVL树的平衡。 在search操作中,我们按照二叉搜索树的规则搜索键值对应的节点,并返回其值。 这个AVL树实现可以用来实现字典类型。我们可以将键值对存储在AVL树的节点中,并通过搜索操作来查找键对应的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值