c语言编程笔录

首页 >   > 笔记大全

笔记大全

C如何实现AVL树

更新时间:2023-09-29

什么是AVL树

AVL树是一种自平衡二叉搜索树,它的名称来源于发明人 Georgy Adelson-Velsky 和 Evgenii Landis。它的特点是每个节点的左右子树高度差最多为1,保证了它的搜索、插入和删除的时间复杂度均为 O(log n)。

AVL树的实现

AVL树的实现相比于普通的二叉搜索树要复杂一些,因为我们需要在插入和删除节点时保证树平衡,也就是调整节点的位置和高度以保证高度差最多为1。以下是一个简单的 C++ 实现:

#include 

struct Node {
    int value;
    int height;
    Node* left;
    Node* right;
    
    Node(int v) {
        value = v;
        height = 1;
        left = nullptr;
        right = nullptr;
    }
};
    
class AVLTree {
public:
    AVLTree() {
        root = nullptr;
    }
    
    void insert(int value) {
        root = insert(root, value);
    }
    
    void remove(int value) {
        root = remove(root, value);
    }
    
private:
    Node* root;
    
    int height(Node* node) {
        return node == nullptr ? 0 : node->height;
    }
    
    int balance(Node* node) {
        return node == nullptr ? 0 : height(node->left) - height(node->right);
    }
    
    void update_height(Node* node) {
        node->height = std::max(height(node->left), height(node->right)) + 1;
    }
    
    Node* rotate_left(Node* node) {
        Node* new_root = node->right;
        node->right = new_root->left;
        new_root->left = node;
        update_height(node);
        update_height(new_root);
        return new_root;
    }
    
    Node* rotate_right(Node* node) {
        Node* new_root = node->left;
        node->left = new_root->right;
        new_root->right = node;
        update_height(node);
        update_height(new_root);
        return new_root;
    }
    
    Node* balance_node(Node* node) {
        if (balance(node) > 1) {
            if (balance(node->left) < 0) {
                node->left = rotate_left(node->left);
            }
            return rotate_right(node);
        } else if (balance(node) < -1) {
            if (balance(node->right) > 0) {
                node->right = rotate_right(node->right);
            }
            return rotate_left(node);
        }
        update_height(node);
        return node;
    }
    
    Node* insert(Node* node, int value) {
        if (node == nullptr) {
            return new Node(value);
        } else if (value < node->value) {
            node->left = insert(node->left, value);
        } else if (value > node->value) {
            node->right = insert(node->right, value);
        } else {
            return node;
        }
        return balance_node(node);
    }
    
    Node* remove(Node* node, int value) {
        if (node == nullptr) {
            return nullptr;
        } else if (value < node->value) {
            node->left = remove(node->left, value);
        } else if (value > node->value) {
            node->right = remove(node->right, value);
        } else {
            if (node->left == nullptr || node->right == nullptr) {
                Node* temp = node->left != nullptr ? node->left : node->right;
                delete node;
                return temp;
            } else {
                Node* temp = node->right;
                while (temp->left != nullptr) {
                    temp = temp->left;
                }
                node->value = temp->value;
                node->right = remove(node->right, temp->value);
            }
        }
        return balance_node(node);
    }
};

AVL树的使用

使用 AVL 树可以在需要快速搜索、插入和删除元素的场景下提高程序性能。以下是一个简单的代码示例:

int main() {
    AVLTree tree;
    tree.insert(5);
    tree.insert(2);
    tree.insert(8);
    tree.insert(1);
    tree.insert(3);
    tree.remove(2);
    return 0;
}

总结

AVL树是一种自平衡二叉搜索树,它可以在 O(log n) 时间复杂度内完成搜索、插入和删除节点等操作。实现 AVL 树需要保证每个节点的左右子树高度差最多为 1,因此需要在插入和删除节点时对整棵树进行平衡调整。在实际项目中,可以使用 C++ 等编程语言来实现 AVL 树,提高程序在频繁操作数据的场景下的性能。