AVL tree | 平衡二叉树

2019-08-03  本文已影响0人  zilla

参考:胡凡,曾磊《算法笔记》

引子

使用有序序列构建BST会形成链式的二叉树,此时查找的复杂度会达到O(n),达不到查询优化的效果。因此需要调整树的结构,使得树的高度在每次插入后仍保持O(log n)级别,使查询操作仍保持O(log n)复杂度。

概念

AVL tree是一棵平衡的二叉查找树

AVL tree要求任意结点平衡因子绝对值不超过1

AVL tree的基本操作

*以下操作前提是各结点value均不同。

查找void search(Node* root, int value)

做法同BST的查找。
复杂度O(log n)

插入void insert(Node* &root, int value)

插入新结点可能会使从根结点到插入结点的路径上的结点的平衡因子绝对值大于1。
只要把最靠近插入结点的失衡结点调整到正常,路径上所有结点就都会平衡。
⚠️传Node*的引用
⚠️插入后注意更新结点高度
⚠️调整操作中注意更新结点高度

步骤

调整用到的操作 ⚠️传引用

  • 左旋void L(Node* &root)
  • 右旋void R(Node* &root)
左旋、右旋互为逆操作。
需调整的树形可分为
LL、RR(一次旋转)

LL需右旋,RR需左旋

LR、RL(两次旋转)

LR需左旋左子树(变成LL),再右旋
RL需右旋右子树(变成RR),再左旋

AVL tree的建立

依次insert结点即可。
Node* createAVL(int data[], int nn)

删除

暂时跳过🤮

1066 Root of AVL Tree (25 分)

#include <cstdio>
#include <algorithm>

using namespace std;
struct Node {
    int value, height;
    Node *lchild, *rchild;
};

int getHeight(Node *root) {
    return root == NULL ? 0 : root->height;
}

void updateHeight(Node *root) {
    root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
}

int getBalanceFactor(Node *root) {
    return getHeight(root->lchild) - getHeight(root->rchild);
}

void LeftRotation(Node *&root) {
    Node *temp = root->rchild;
    root->rchild = temp->lchild;
    temp->lchild = root;
    updateHeight(root);
    updateHeight(temp);
    root = temp;
}

void RightRotation(Node *&root) {
    Node *temp = root->lchild;
    root->lchild = temp->rchild;
    temp->rchild = root;
    updateHeight(root);
    updateHeight(temp);
    root = temp;
}

void insertNode(Node *&root, int value) {
    if (root == NULL) {
        root = new Node{value, 1, NULL, NULL};
    } else if (value < root->value) {
        insertNode(root->lchild, value);
        updateHeight(root);
        if (getBalanceFactor(root) == 2) {
            if (getBalanceFactor(root->lchild) == 1) { //LL
                RightRotation(root);
            } else if (getBalanceFactor(root->lchild) == -1) { //LR
                LeftRotation(root->lchild);
                RightRotation(root);
            }
        }
    } else if (value > root->value) {
        insertNode(root->rchild, value);
        updateHeight(root);
        if (getBalanceFactor(root) == -2) {
            if (getBalanceFactor(root->rchild) == -1) { //RR
                LeftRotation(root);
            } else if (getBalanceFactor(root->rchild) == 1) { //RL
                RightRotation(root->rchild);
                LeftRotation(root);
            }

        }
    }
}

Node *createAVL(int n_node) {
    Node *root = NULL;
    int curr;
    for (int i = 0; i < n_node; ++i) {
        scanf("%d", &curr);
        insertNode(root, curr);
    }
    return root;
}

int main() {
    int nn;
    scanf("%d", &nn);
    Node *root = createAVL(nn);
    printf("%d\n", root->value);
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读