数据结构_AVL树

一.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);
    }

猜你喜欢

转载自blog.csdn.net/u011616934/article/details/124229020
今日推荐