📜  如何将字符串插入 AVL 树(1)

📅  最后修改于: 2023-12-03 15:09:07.144000             🧑  作者: Mango

如何将字符串插入AVL树

AVL树是一种自平衡二叉查找树,它的每个节点的左子树和右子树的高度差不超过1。在插入和删除节点时,AVL树会通过旋转和重构的操作来维护平衡性。

下面介绍如何将字符串插入AVL树。我们假设有一个节点结构体定义如下:

struct AVLNode {
    string val;
    int height;
    AVLNode* left;
    AVLNode* right;
    AVLNode(string v) : val(v), height(1), left(nullptr), right(nullptr) {}
};

其中,val存储节点的值,height存储节点的高度,leftright分别指向左子树和右子树。

插入字符串

在将字符串插入AVL树之前,需要先实现一个函数来计算节点的高度。具体实现如下:

int getHeight(AVLNode* node) {
    if (node == nullptr)
        return 0;
    else
        return node->height;
}

函数getHeight接受一个AVL节点指针node作为参数,如果节点为空,则返回0;否则返回节点的高度。

下面是将字符串插入AVL树的代码实现:

AVLNode* insert(AVLNode* root, string val) {
    if (root == nullptr)
        return new AVLNode(val);

    if (val < root->val)
        root->left = insert(root->left, val);
    else if (val > root->val)
        root->right = insert(root->right, val);
    else
        return root;  // 值已存在

    int left_height = getHeight(root->left);
    int right_height = getHeight(root->right);
    root->height = 1 + max(left_height, right_height);  // 更新节点高度

    int balance = left_height - right_height;

    // 左子树高度大于右子树
    if (balance > 1) {
        // 判断需要进行的旋转类型,LL型或LR型
        if (val < root->left->val) {
            root = right_rotate(root);
        } else {
            root->left = left_rotate(root->left);
            root = right_rotate(root);
        }
    }
    // 右子树高度大于左子树
    else if (balance < -1) {
        // 判断需要进行的旋转类型,RR型或RL型
        if (val > root->right->val) {
            root = left_rotate(root);
        } else {
            root->right = right_rotate(root->right);
            root = left_rotate(root);
        }
    }

    return root;
}

函数insert接受AVL树的根节点指针root和要插入的字符串值val作为参数。如果根节点为空则返回新节点,否则按照二叉查找树的规则将节点插入到左子树或右子树中,直到找到一个空节点。如果节点的值已经存在,则直接返回该节点。

在插入节点后,需要更新节点的高度。然后检查节点是否失衡,如果失衡则进行旋转。旋转分为4种类型:LL型、LR型、RR型和RL型。具体的旋转实现详见相关教程。

总结

AVL树是一种自平衡二叉查找树,可以用来高效地维护有序集合。在插入节点时,需要递归地按照二叉查找树的规则将节点插入到左子树或右子树中,并进行平衡操作。本文介绍了如何将字符串插入AVL树,并提供了完整的代码实现。