二叉搜索樹的時間複雜度爲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;
}