2025-11-27 C++ AVL树深度解析:平衡之道与旋转实现

# C++ AVL树深度解析:平衡之道与旋转实现

AVL树是最早发明的自平衡二叉搜索树,以其发明者Adelson-Velsky和Landis的名字命名。它通过维护平衡因子来确保树的高度始终保持在O(log n)范围内,为各种操作提供了稳定的性能保证。

## AVL树的基本概念

### 平衡因子定义

AVL树要求每个节点的左右子树高度差(平衡因子)的绝对值不超过1。平衡因子的计算公式为:

```

平衡因子 = 左子树高度 - 右子树高度

```

当平衡因子的绝对值大于1时,需要通过旋转操作来恢复平衡。

### AVL树的性质

1. 是一棵二叉搜索树

2. 每个节点的平衡因子绝对值不超过1

3. 每个子树也都是AVL树

4. 搜索、插入、删除操作的时间复杂度均为O(log n)

## AVL树节点设计

```cpp

template<typename T>

struct AVLTreeNode {

    T data;

    AVLTreeNode* left;

    AVLTreeNode* right;

    AVLTreeNode* parent;

    int height;


    AVLTreeNode(const T& val)

        : data(val), left(nullptr), right(nullptr),

          parent(nullptr), height(1) {}


    // 更新节点高度

    void updateHeight() {

        int left_height = left ? left->height : 0;

        int right_height = right ? right->height : 0;

        height = std::max(left_height, right_height) + 1;

    }


    // 获取平衡因子

    int getBalanceFactor() const {

        int left_height = left ? left->height : 0;

        int right_height = right ? right->height : 0;

        return left_height - right_height;

    }

};

```

## AVL树核心框架

```cpp

template<typename K, typename V, typename KeyOfValue>

class AVLTree {

public:

    using Node = AVLTreeNode<V>;


    AVLTree() : root(nullptr), size_(0) {}

    ~AVLTree() { clear(); }


    // 基本操作接口

    bool insert(const V& value);

    bool erase(const K& key);

    Node* find(const K& key) const;

    void clear();


    // 工具函数

    size_t size() const { return size_; }

    bool empty() const { return size_ == 0; }

    int height() const { return root ? root->height : 0; }


    // 遍历接口

    template<typename Func>

    void inorder(Func func) const { inorder(root, func); }


private:

    Node* root;

    size_t size_;

    KeyOfValue keyOfValue;


    // 旋转操作

    Node* leftRotate(Node* y);

    Node* rightRotate(Node* x);


    // 平衡维护

    Node* balance(Node* node);


    // 辅助函数

    Node* insert(Node* node, const V& value, bool& inserted);

    Node* erase(Node* node, const K& key, bool& deleted);

    Node* find(Node* node, const K& key) const;

    Node* minimum(Node* node) const;

    void destroy(Node* node)<"8N.2597.HK">;


    template<typename Func>

    void inorder(Node* node, Func func) const;

};

```

## 旋转操作详解

### 左旋操作

左旋用于处理右子树过高的情况:

```cpp

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::leftRotate(Node* y) {

    if (!y || !y->right) return y;


    Node* x = y->right;

    Node* T2 = x->left;


    // 执行旋转

    x->left = y;

    y->right = T2;


    // 更新父指针

    if (T2) {

        T2->parent = y;

    }

    x->parent = y->parent;

    y->parent = x;


    // 更新高度

    y->updateHeight();

    x->updateHeight();


    return x;

}

```

### 右旋操作

右旋用于处理左子树过高的情况:

```cpp

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::rightRotate(Node* x) {

    if (!x || !x->left) return x;


    Node* y = x->left;

    Node* T2 = y->right;


    // 执行旋转

    y->right = x;

    x->left = T2;


    // 更新父指针

    if (T2) {

        T2->parent = x;

    }

    y->parent = x->parent;

    x->parent = y;


    // 更新高度

    x->updateHeight();

    y->updateHeight();


    return y;

}

```

## 四种不平衡情况处理

### LL情况(左左情况)

当节点的左子树的左子树过高时,需要单次右旋:

```cpp

// 在balance函数中处理LL情况

if (balance_factor > 1 && node->left->getBalanceFactor() >= 0) {

    return rightRotate(node);

}

```

### RR情况(右右情况)

当节点的右子树的右子树过高时,需要单次左旋:

```cpp

// 在balance函数中处理RR情况

if (balance_factor < -1 && node->right->getBalanceFactor() <= 0) {

    return leftRotate(node);

}

```

### LR情况(左右情况)

当节点的左子树的右子树过高时,需要先左旋再右旋:

```cpp

// 在balance函数中处理LR情况

if (balance_factor > 1 && node->left->getBalanceFactor() < 0) {

    node->left = leftRotate(node->left);

    return rightRotate(node);

}

```

### RL情况(右左情况)

当节点的右子树的左子树过高时,需要先右旋再左旋:

```cpp

// 在balance函数中处理RL情况

if (balance_factor < -1 && node->right->getBalanceFactor() > 0) {

    node->right <"2T.2597.HK">= rightRotate(node->right);

    return leftRotate(node);

}

```

## 完整的平衡函数

```cpp

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::balance(Node* node) {

    if (!node) return nullptr;


    node->updateHeight();

    int balance_factor = node->getBalanceFactor();


    // LL情况

    if (balance_factor > 1 && node->left->getBalanceFactor() >= 0) {

        return rightRotate(node);

    }


    // RR情况

    if (balance_factor < -1 && node->right->getBalanceFactor() <= 0) {

        return leftRotate(node);

    }


    // LR情况

    if (balance_factor > 1 && node->left->getBalanceFactor() < 0) {

        node->left = leftRotate(node->left);

        return rightRotate(node);

    }


    // RL情况

    if (balance_factor < -1 && node->right->getBalanceFactor() > 0) {

        node->right = rightRotate(node->right);

        return leftRotate(node);

    }


    return node;

}

```

## 插入操作实现

```cpp

template<typename K, typename V, typename KeyOfValue>

bool AVLTree<K, V, KeyOfValue>::insert(const V& value) {

    bool inserted = false;

    root = insert(root, value, inserted);

    if (inserted) size_++;

    return inserted;

}

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::insert(Node* node, const V& value, bool& inserted) {

    if (!node) {

        inserted = true;

        return new Node(value);

    }


    K key_val = keyOfValue(value);

    K node_key = keyOfValue(node->data);


    if (key_val < node_key) {

        node->left = insert(node->left, value, inserted);

        if (node->left) node->left->parent = node;

    } else if (key_val > node_key) {

        node->right = insert(node->right, value, inserted);

        if (node->right) node->right->parent = node;

    } else {

        // 键值已存在,不插入

        inserted = false;

        return node;

    }


    // 更新高度并平衡树

    return balance(node);

}

```

## 删除操作实现

```cpp

template<typename K, typename V, typename KeyOfValue>

bool AVLTree<K, V, KeyOfValue>::erase(const K& key) {

    bool deleted = false;

    root = erase(root, key, deleted);

    if (deleted) size_--;

    return deleted;

}

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::erase(Node* node, const K& key, bool& deleted) {

    if (!node) {

        deleted = false;

        return nullptr;

    }


    K node_key = keyOfValue(node->data);


    if (key<"5A.2597.HK"> < node_key) {

        node->left = erase(node->left, key, deleted);

        if (node->left) node->left->parent = node;

    } else if (key > node_key) {

        node->right = erase(node->right, key, deleted);

        if (node->right) node->right->parent = node;

    } else {

        // 找到要删除的节点

        deleted = true;


        if (!node->left || !node->right) {

            // 有一个子节点或没有子节点

            Node* temp = node->left ? node->left : node->right;


            if (!temp) {

                // 没有子节点

                delete node;

                return nullptr;

            } else {

                // 有一个子节点

                temp->parent = node->parent;

                delete node;

                return temp;

            }

        } else {

            // 有两个子节点,找到中序后继

            Node* temp = minimum(node->right);

            node->data = temp->data;

            node->right = erase(node->right, keyOfValue(temp->data), deleted);

        }

    }


    return balance(node);

}

```

## 查找和遍历操作

```cpp

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::find(const K& key) const {

    return find(root, key);

}

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::find(Node* node, const K& key) const {

    while (node) {

        K node_key = keyOfValue(node->data);

        if (key < node_key) {

            node = node->left;

        } else if (key > node_key) {

            node = node->right;

        } else {

            return node;

        }

    }

    return nullptr;

}

template<typename K, typename V, typename KeyOfValue>

template<typename Func>

void AVLTree<K, V, KeyOfValue>::inorder(Node* node, Func func) const {

    if (!node) return;


    inorder(node->left, func);

    func(node->data);

    inorder(node->right, func);

}

```

## 实用工具函数

```cpp

template<typename K, typename V, typename KeyOfValue>

typename AVLTree<K, V, KeyOfValue>::Node*

AVLTree<K, V, KeyOfValue>::minimum(Node* node) const {

    if (!node) return nullptr;

    while (node->left) {

        node = node->left;

    }

    return node;

}

template<typename K, typename V, typename KeyOfValue>

void AVLTree<K, V, KeyOfValue>::clear() {

    destroy(root);

    root = nullptr;

    size_ = 0;

}

template<typename K, typename V, typename KeyOfValue>

void AVLTree<K, V, KeyOfValue>::destroy(Node* node) {

    if (!node) return;

    destroy(node->left);

    destroy(node->right);

    delete node;

}

```

## 使用示例

### 实现学生成绩管理系统

```cpp

#include <iostream>

#include <string>

struct Student {

    int id;

    std::string name;

    double score;


    Student(int i, const std::string& n, double s)

        : id(i), name(n), score(s) {}


    bool operator<(const Student& other) const {

        return id <"9E.2597.HK">< other.id;

    }

};

struct StudentKey {

    int operator()(const Student& s) const {

        return s.id;

    }

};

void student_management_example() {

    AVLTree<int, Student, StudentKey> student_db;


    // 插入学生记录

    student_db.insert(Student(1001, "Alice", 85.5));

    student_db.insert(Student(1002, "Bob", 92.0));

    student_db.insert(Student(1003, "Charlie", 78.5));

    student_db.insert(Student(1004, "Diana", 88.0));


    // 查找学生

    auto student = student_db.find(1002);

    if (student) {

        std::cout << "Found student: " << student->name

                  << ", Score: " << student->score << std::endl;

    }


    // 中序遍历输出所有学生(按学号排序)

    std::cout << "All students (sorted by ID):" << std::endl;

    student_db.inorder([](const Student& s) {

        std::cout << "ID: " << s.id << ", Name: " << s.name

                  << ", Score: " << s.score << std::endl;

    });


    std::cout << "Tree height: " << student_db.height() << std::endl;

    std::cout << "Total students: " << student_db.size() << std::endl;

}

```

## 性能分析与验证

### 平衡性检查

```cpp

template<typename K, typename V, typename KeyOfValue>

class AVLTreeValidator {

public:

    static bool isBalanced(const AVLTree<K, V, KeyOfValue>& tree) {

        return checkBalance(tree.getRoot());

    }


    static bool isBST(const AVLTree<K, V, KeyOfValue>& tree) {

        return checkBST(tree.getRoot(), nullptr, nullptr);

    }


private:

    static bool checkBalance(typename AVLTree<K, V, KeyOfValue>::Node* node) {

        if (!node) return true;


        int balance_factor = node->getBalanceFactor();

        if (balance_factor < -1 || balance_factor > 1) {

            return false;

        }


        return checkBalance(node->left) && checkBalance(node->right);

    }


    static bool checkBST(typename AVLTree<K, V, KeyOfValue>::Node* node,

                        const K* min_val, const K* max_val) {

        if (!node) return true;


        K current_key = KeyOfValue()(node->data);


        if (min_val && current_key <= *min_val) return false;

        if (max_val && current_key >= *max_val) return false;


        return checkBST(node->left, min_val, &current_key) &&

              checkBST(node->right, &current_key, max_val);

    }

};

```

## 与红黑树的比较

### 适用场景分析

```cpp

// AVL树的优势:

// - 查找操作性能更优(更严格的平衡)

// - 适用于查找密集型的应用

// - 高度始终保持在最小范围内

// AVL树的劣势:

// - 插入和删除操作可能更慢(需要更多旋转)

// - 实现相对复杂

// - 内存开销稍大(需要存储高度信息)

// 红黑树的优势:

// - 插入和删除操作更快

// - 实现相对简单

// - 适用于频繁修改的场景

// 选择建议:

// - 如果查找操作远多于修改操作,选择AVL树

// - 如果插入删除操作频繁,选择红黑树

// - 对于内存敏感的场景,考虑红黑树

```

## 总结

AVL树通过精妙的旋转操作维护严格的平衡条件,为需要高效查找操作的场景提供了理想的数据结构解决方案。其四种旋转情况(LL、RR、LR、RL)涵盖了所有可能的不平衡状态,确保了树的平衡性。

理解AVL树的实现不仅有助于掌握自平衡树的基本原理,还能为学习更复杂的数据结构打下坚实基础。在实际应用中,应根据具体的操作频率和性能要求,在AVL树和红黑树之间做出合适的选择。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容