AVL(二叉平衡搜索树)的概念和思路
- 任意一个节点 左子树高度 - 右子树高度 <= 1
- 要想让BST保持平衡,必须在每一次插入、删除之后,检查是否其左右子树满足平衡的定义
- 如果不满足,就做“旋转”操作,使其恢复平衡
- 加入以上平衡策略算法后的BST,称为AVL,AVL是一种绝对平衡的二叉树
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX(a,b) (a)>(b)?(a):(b)
typedef struct node_tree
{
int data;
struct node_tree *l,*r;
int height;
}tree,*linktree;
int height(linktree root)
{
if(root == NULL)
return 0;
return root->height;
}
linktree new_node(int num)
{
linktree ne = (linktree)malloc(sizeof(tree));
if(ne != NULL)
{
ne->data = num;
ne->l = ne->r = NULL;
}
return ne;
}
linktree left_rotate(linktree root)
{
if(root == NULL)
return NULL;
linktree tmp = root->r;
root->r = tmp->l;
tmp->l = root;
root->height = MAX(height(root->l), height(root->r)) + 1;
tmp->height = MAX(height(tmp->l), height(tmp->r)) + 1;
return tmp;
}
linktree right_rotate(linktree root)
{
if(root == NULL)
return NULL;
linktree tmp = root->l;
root->l = tmp->r;
tmp->r = root;
root->height = MAX(height(root->l), height(root->r)) + 1;
tmp->height = MAX(height(tmp->l), height(tmp->r)) + 1;
return tmp;
}
linktree left_right_rotate(linktree root)
{
root->l = left_rotate(root->l);
return right_rotate(root);
}
linktree right_left_rotate(linktree root)
{
root->r = right_rotate(root->r);
return left_rotate(root);
}
linktree insert_tree(linktree root, linktree ne)
{
if(root == NULL)
return ne;
if(ne->data < root->data)
root->l = insert_tree(root->l, ne);
else
root->r = insert_tree(root->r, ne);
if(height(root->l) - height(root->r) >= 2)
{
if(ne->data < root->l->data)
{
root = right_rotate(root);
}
else if(ne->data > root->l->data)
{
root = left_right_rotate(root);
}
}
if(height(root->r) - height(root->l) >= 2)
{
if(ne->data > root->r->data)
{
root = left_rotate(root);
}
else if(ne->data < root->r->data)
{
root = right_left_rotate(root);
}
}
root->height = MAX((height(root->l)), (height(root->r))) + 1;
return root;
}
linktree remove_tree(linktree root, int num)
{
if(root == NULL)
return NULL;
if(num < root->data)
root->l = remove_tree(root->l, num);
else if(num > root->data)
root->r = remove_tree(root->r, num);
else
{
linktree tmp;
if(root->l != NULL)
{
for(tmp = root->l; tmp->r != NULL; tmp = tmp->r);
root->data = tmp->data;
root->l = remove_tree(root->l, tmp->data);
}
else if(root->r != NULL)
{
for(tmp = root->r; tmp->l != NULL; tmp = tmp->l);
root->data = tmp->data;
root->r = remove_tree(root->r, tmp->data);
}
else
{
free(root);
return NULL;
}
}
if(height(root->l) - height(root->r) >= 2)
{
if(height(root->l->l) > height(root->l->r))
{
root = right_rotate(root);
}
else
{
root = left_right_rotate(root);
}
}
if(height(root->r) - height(root->l) >= 2)
{
if(height(root->r->r) > height(root->r>l))
{
root = left_rotate(root);
}
else
{
root = right_left_rotate(root);
}
}
root->height = MAX((height(root->l)), (height(root->r))) + 1;
return root;
}
int main()
{
linktree root = NULL;
int n;
while(1)
{
scanf("%d", &n);
if(n == 0)
break;
linktree ne = new_node(n);
root = insert_tree(root, ne);
}
while(1)
{
scanf("%d", &n);
if(n == 0)
break;
root = remove_tree(root, n);
}
return 0;
}