高级数据结构02AVL树

1.数据结构实现

#include <iostream>
using namespace std;

template<typename T>
class AVL {
public:
    AVL() { _root = nullptr; }

    // 递归实现AVL树的插入操作  BST + 平衡
    void insert(const T &val) {
        _root = _insert(_root, val);
    }

    // 递归实现AVL树的删除操作  BST + 平衡
    void remove(const T &val) {
        _root = _remove(_root, val);
    }

    // 判断一颗二叉搜索树是不是平衡树,是返回true,否则返回false
    bool isAVL() {
        return _isAVL(_root);
    }

    // 中序遍历
    void inorder() {
        _inorder(_root);
        cout << endl;
    }

private:
    struct AVLNode {
        AVLNode(T data = T())
            : _data(data), _left(nullptr), _right(nullptr), _height(1) {}
        T _data;
        AVLNode *_left;
        AVLNode *_right;
        int _height; // 存储的就是节点的高度
    };

    // 返回节点的高度
    int height(AVLNode *node) const {
        return node == nullptr ? 0 : node->_height;
    }

    // 返回左右子树最高的层数
    int maxHeight(AVLNode *node1, AVLNode *node2) {
        return height(node1) > height(node2) ? height(node1) : height(node2);
    }

    // 左旋转操作 以node为根节点进行左旋转,返回旋转后的根节点
    AVLNode* leftRotate(AVLNode *node) {
        AVLNode *child = node->_right;
        node->_right = child->_left;
        child->_left = node;
        node->_height = maxHeight(node->_left, node->_right) + 1;
        child->_height = maxHeight(child->_left, child->_right) + 1;
        return child;
    }

    // 右旋转操作
    AVLNode* rightRotate(AVLNode *node) {
        AVLNode *child = node->_left;
        node->_left = child->_right;
        child->_right = node;
        node->_height = maxHeight(node->_left, node->_right) + 1;
        child->_height = maxHeight(child->_left, child->_right) + 1;
        return child;
    }

    // 左平衡  左-右旋转
    AVLNode* leftBalance(AVLNode *node) {
        leftRotate(node->_left);
        return rightRotate(node);
    }

    // 右平衡  右-左旋转
    AVLNode* rightBalance(AVLNode *node) {
        rightRotate(node->_right);
        return leftRotate(node);
    }

    // 插入辅助函数
    AVLNode* _insert(AVLNode* node, const T& val) {
        if (node == nullptr) {
            return new AVLNode(val);
        }
        if (val < node->_data) {
            node->_left = _insert(node->_left, val);
        } else if (val > node->_data) {
            node->_right = _insert(node->_right, val);
        } else {
            return node; // 不允许插入重复值
        }

        node->_height = maxHeight(node->_left, node->_right) + 1;

        int balance = height(node->_left) - height(node->_right);
        if (balance > 1) { // 左重
            if (val < node->_left->_data) {
                return rightRotate(node); // 左左
            } else {
                return leftBalance(node); // 左右
            }
        } else if (balance < -1) { // 右重
            if (val > node->_right->_data) {
                return leftRotate(node); // 右右
            } else {
                return rightBalance(node); // 右左
            }
        }
        return node;
    }

    // 删除辅助函数
    AVLNode* _remove(AVLNode* node, const T& val) {
        if (node == nullptr) {
            return node;
        }
        if (val < node->_data) {
            node->_left = _remove(node->_left, val);
        } else if (val > node->_data) {
            node->_right = _remove(node->_right, val);
        } else {
            if (node->_left == nullptr || node->_right == nullptr) {
                AVLNode* temp = node->_left ? node->_left : node->_right;
                if (temp == nullptr) {
                    temp = node;
                    node = nullptr;
                } else {
                    *node = *temp;
                }
                delete temp;
            } else {
                AVLNode* temp = node->_right;
                while (temp->_left != nullptr) {
                    temp = temp->_left;
                }
                node->_data = temp->_data;
                node->_right = _remove(node->_right, temp->_data);
            }
        }

        if (node == nullptr) {
            return node;
        }

        node->_height = maxHeight(node->_left, node->_right) + 1;

        int balance = height(node->_left) - height(node->_right);
        if (balance > 1) { // 左重
            if (height(node->_left->_left) >= height(node->_left->_right)) {
                return rightRotate(node); // 左左
            } else {
                return leftBalance(node); // 左右
            }
        } else if (balance < -1) { // 右重
            if (height(node->_right->_right) >= height(node->_right->_left)) {
                return leftRotate(node); // 右右
            } else {
                return rightBalance(node); // 右左
            }
        }
        return node;
    }

    // 判断是否平衡辅助函数
    bool _isAVL(AVLNode* node) {
        if (node == nullptr) {
            return true;
        }
        int balance = height(node->_left) - height(node->_right);
        if (abs(balance) > 1) {
            return false;
        }
        return _isAVL(node->_left) && _isAVL(node->_right);
    }

    // 中序遍历辅助函数
    void _inorder(AVLNode* node) {
        if (node == nullptr) {
            return;
        }
        _inorder(node->_left);
        cout << node->_data << " ";
        _inorder(node->_right);
    }

    AVLNode *_root;
};

int main() {
    AVL<int> tree;
    tree.insert(10);
    tree.insert(20);
    tree.insert(30);
    tree.insert(40);
    tree.insert(50);
    tree.insert(25);

    cout << "Inorder traversal of the constructed AVL tree is \n";
    tree.inorder();

    tree.remove(30);
    cout << "\nInorder traversal after deletion of 30 \n";
    tree.inorder();

    return 0;
}

2.代码说明

2.1. 插入操作:

• 使用递归的方式将新值插入到合适的位置。
• 插入后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 根据失衡的类型(左左、左右、右右、右左),进行相应的旋转操作。

2. 2删除操作:

• 使用递归的方式找到要删除的节点。
• 删除后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 同样根据失衡的类型进行旋转操作。

2.3.平衡检查:

• 通过计算每个节点的平衡因子来判断是否平衡。
. • 如果平衡因子的绝对值大于1,则说明树不平衡。

2.4. 中序遍历:

• 使用递归的方式进行中序遍历,输出树中的所有节点。
测试在 main 函数中,插入了一些节点并进行了删除操作,最后输出了中序遍历的结果,可以用来验证AVL树的正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的sun&shine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值