一.AVL: 平衡二叉排序树
1.性质:
①左子树<根节点
②右子树>根节点
③|H(left) - H(right)| <= 1
2.优点:
对每个节点的左右子树的树高做了限制,整棵树不会退化成链表。
3.AVL树特点:
是一种平衡二叉树,查找效率非常高。
但为了维持这种高度平衡,要付出更多代价。每次插入删除都要调整,比较复杂耗时。
#include "stdlib.h"
#include "stdio.h"
typedef struct Node
{
int key, h;
struct Node *lchild, *rchild;
} Node;
Node __NIL;
#define NIL (&__NIL)
#define DEBUG
#ifdef DEBUG
#define LOG(frm, args...) { \
printf(frm, ##args); \
}
#else
#define LOG(frm, args...) {}
#endif
__attribute__((constructor))
void init_NIL()
{
NIL->key = NIL->h = 0;
NIL->lchild = NIL->rchild = NIL;
return;
}
Node *getNewNode(int key)
{
Node *p = (Node *)malloc(sizeof(Node));
p->key = key;
p->h = 1;
p->lchild = p->rchild = NIL;
return p;
}
#define max(a, b) ((a > b) ? a : b)
void update_height(Node *root)
{
root->h = max(root->lchild->h, root->rchild->h) + 1;
return ;
}
Node *left_rotate(Node *root)
{
LOG("%d left rotate\n", root->key);
Node *new_root = root->rchild;
root->rchild = new_root->lchild;
new_root->lchild = root;
update_height(root);
update_height(new_root);
return new_root;
}
Node *right_rotate(Node *root)
{
LOG("%d right rotate\n", root->key);
Node *new_root = root->lchild;
root->lchild = new_root->rchild;
new_root->rchild = root;
update_height(root);
update_height(new_root);
return new_root;
}
const char *type_str[4] = {"LL", "LR", "RR", "RL"};
Node *maintain(Node *root)
{
// LL:0 LR:1 RR:2 RL:3
if (abs(root->lchild->h - root->rchild->h) < 2) return root;
int type = -1;
if (root->lchild->h > root->rchild->h)
{
if (root->lchild->lchild->h < root->lchild->rchild->h)
{
root->lchild = left_rotate(root->lchild);
type += 1;
}
type += 1;
root = right_rotate(root);
}
else
{
type = 1;
if (root->rchild->rchild->h < root->rchild->lchild->h)
{
root->rchild = right_rotate(root->rchild);
type += 1;
}
type += 1;
root = left_rotate(root);
}
LOG("TYPE: %s\n", type_str[type]);
return root;
}
Node *insert(Node *root, int key)
{
if (root == NIL) return getNewNode(key);
if (root->key == key) return root;
if (root->key > key) root->lchild = insert(root->lchild, key);
else root->rchild = insert(root->rchild, key);
update_height(root);
return maintain(root);
}
void clear(Node *root)
{
if (root == NIL) return;
clear(root->lchild);
clear(root->rchild);
free(root);
return;
}
void print_node(Node *root)
{
printf("[ %d(%d) | %d, %d ]\n", root->key, root->h,
root->lchild->key, root->rchild->key);
return;
}
void output(Node *root)
{
if (root == NIL) return;
print_node(root);
output(root->lchild);
output(root->rchild);
return;
}
int main(int argc, char const *argv[])
{
Node *root = NIL;
int key;
while (~scanf("%d", &key))
{
printf("insert %d to AVL tree\n", key);
root = insert(root, key);
output(root);
}
return 0;
}
删除操作:
Node *erase(Node *root, int key)
{
if (root == NIL) return root;
if (root->key > key) root->lchild = erase(root->lchild, key);
else if (root->key < key) root->rchild = erase(root->rchild, key);
else {
if (root->lchild == NIL || root->rchild == NIL)
{
Node *temp = root->lchild != NIL ? root->rchild : root->rchild;
free(root);
return temp;
} else {
Node *temp = root->lchild;
while (temp->rchild != NIL) temp = temp->rchild;
root->key = temp->key;
root->rchild = erase(root->lchild, temp->key);
}
}
update_height(root);
return maintain(root);
}
//erase
while (~scanf("%d", &key))
{
if (key == -1) break;
printf("erase %d from AVL tree\n", key);
root = erase(root, key);
output(root);
}