一種AVL樹實現

       二叉搜索樹的時間複雜度爲O(logN),但是在最壞情況下,其時間複雜度卻爲O(N),爲了保證即使在最壞情況下時間複雜度也接近O(logN),AVL樹就應運而生了。

AVL樹,只是一種特殊的二叉搜索樹,特殊之處在於:“任意節點的左子樹高度和右子樹高度最多差1”,所以這樣的二叉搜索樹基本是平衡的。


#include<stdio.h>
#include<stdlib.h>

struct avl_tree_node {
	char data;
	struct avl_tree_node *lchild;
	struct avl_tree_node *rchild;
	int height;
};

static int max(int a,int b)
{
	return a > b ? a : b;
}

static int get_height(struct avl_tree_node *T)
{
	if(NULL == T)
		return -1;
	else
		return T->height;
}

static struct avl_tree_node *single_rotate_right(struct avl_tree_node *T)
{
	struct avl_tree_node *temp;

	temp = T->rchild;
	T->rchild = temp->lchild;
	temp->lchild = T;
	T->height = max(get_height(T->lchild),get_height(T->rchild)) + 1;
	temp->height = max(get_height(temp->lchild),get_height(temp->rchild)) + 1;
	return temp;
}

static struct avl_tree_node *double_rotate_right(struct avl_tree_node *k3)
{
	struct avl_tree_node *k1,*k2;
	k1 = k3->rchild;
	k2 = k1->lchild;

	k3->rchild = k2->lchild;
	k2->lchild = k3;
	k1->lchild = k2->rchild;
	k2->rchild = k1;
	k1->height = max(get_height(k1->lchild),get_height(k1->rchild)) + 1;
	k2->height = max(get_height(k2->lchild),get_height(k2->rchild)) + 1;
	k3->height = max(get_height(k3->lchild),get_height(k3->rchild)) + 1;
	return k2;
}

static struct avl_tree_node *single_rotate_left(struct avl_tree_node *T)
{
	struct avl_tree_node *temp;

	temp = T->lchild;
	T->lchild = temp->rchild;
	temp->rchild = T;
	T->height = max(get_height(T->lchild),get_height(T->rchild)) + 1;
	temp->height = max(get_height(temp->lchild),get_height(temp->rchild)) + 1;
	return temp;
}

static struct avl_tree_node *double_rotate_left(struct avl_tree_node *k3)
{
	struct avl_tree_node *k1,*k2;
	k1 = k3->lchild;
	k2 = k1->rchild;

	k3->lchild = k2->rchild;
	k2->rchild = k3;
	k1->rchild = k2->lchild;
	k2->lchild = k1;
	k1->height = max(get_height(k1->lchild),get_height(k1->rchild)) + 1;
	k2->height = max(get_height(k2->lchild),get_height(k2->rchild)) + 1;
	k3->height = max(get_height(k3->lchild),get_height(k3->rchild)) + 1;
	return k2;
}

static struct avl_tree_node *insert(struct avl_tree_node*T, char c)
{
	if(T == NULL)
	{
		T = malloc(sizeof(struct avl_tree_node));
		if(T == NULL)
		{
			printf("Error: out of memory!!\n");
			return NULL;
		}
		else
		{
			T->data = c;
			T->lchild = T->rchild = NULL;
			T->height = 0;
		}
	}
	else
	{
		if(c > T->data)
		{
			T->rchild = insert(T->rchild,c);
			if(get_height(T->rchild) - get_height(T->lchild) == 2)
			{
				if(c > T->rchild->data)
					T = single_rotate_right(T);
				else if(c < T->rchild->data)
					T = double_rotate_right(T);
			}
		}
		else if(c < T->data)
		{
			T->lchild = insert(T->lchild,c);
			if(get_height(T->lchild) - get_height(T->rchild) == 2)
			{
				if(c < T->lchild->data)
					T = single_rotate_left(T);
				else if(c > T->lchild->data)
					T = double_rotate_left(T);
			}
		}
	}
	T->height = max(get_height(T->lchild),get_height(T->rchild)) + 1;
	return T;
}

static struct avl_tree_node *findMin(struct avl_tree_node *T)
{
	if(T == NULL)
		return NULL;
	else
	{
		while(T->lchild != NULL)
		{	
			T = T->lchild;
		}
		return T;
	}
}

static struct avl_tree_node *delete(struct avl_tree_node *T,char c)
{
	struct avl_tree_node *temp;
	if(T == NULL)
		return NULL;
	if(c < T->data)
		T->lchild = delete(T->lchild,c);
	else if(c > T->data)
		T->rchild = delete(T->rchild,c);
	else
	{
		if(T->lchild && T->rchild)
		{
			temp = findMin(T->rchild);
			T->data = temp->data;
			T->rchild = delete(T->rchild,temp->data);
		}
		else 
		{	
			if(T->lchild == NULL)
				T = T->rchild;
			else if(T->rchild == NULL)
				T = T->lchild;
		}
	}
	if(T != NULL)
	{
		T->height = max(get_height(T->lchild),get_height(T->rchild)) + 1;
		if(get_height(T->lchild) - get_height(T->rchild) == 2)
		{
			T = single_rotate_left(T);
		}
		if(get_height(T->rchild) - get_height(T->lchild) == 2)
		{
			T = single_rotate_right(T);
		}
	}
	return T;
}

static void print_preorder(struct avl_tree_node *T)
{
	if(T == NULL)
		return;
	printf("  %d  ",T->data);
	print_preorder(T->lchild);
	print_preorder(T->rchild);
}

static void print_midorder(struct avl_tree_node *T)
{
	if(T == NULL)
		return;
	print_midorder(T->lchild);
	printf("  %d  ",T->data);
	print_midorder(T->rchild);
}

int main(void)
{
	struct avl_tree_node *T = NULL;
	struct avl_tree_node *temp = NULL;
	T = insert(T,1);
	T = insert(T,2);
	T = insert(T,3);
	T = insert(T,4);
	T = insert(T,5);
	T = insert(T,6);
	T = insert(T,7);
	T = insert(T,16);
	T = insert(T,15);
	T = insert(T,14);
	T = insert(T,13);
	T = insert(T,12);
	T = insert(T,11);
	T = insert(T,10);
	T = insert(T,8);
	T = insert(T,9);
	printf("當前樹的前序遍歷爲:");
	print_preorder(T);
	printf("\n");
	printf("當前樹的中序遍歷爲:");
	print_midorder(T);
	printf("\n");
	printf("----------start findMin()------------\n");
	temp = findMin(T);
	printf("----------%d is Min in current tree------------\n",temp->data);

	printf("----------start---delete------------\n");
	//T = delete(T,16);
	//T = delete(T,14);
	T = delete(T,7);
	printf("----------after---delete------------\n");
	printf("當前樹的前序遍歷爲:");
	print_preorder(T);
	printf("\n");
	printf("當前樹的中序遍歷爲:");
	print_midorder(T);
	printf("\n");
	return 0;
}


發佈了36 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章