Skip to content

Advanced Trees(高级树)

remove from a BST(删除 BST 中的节点)

如果要删除的节点没有子节点,那么直接将其删除即可。

如果要删除的节点只有一个子节点,那么直接将其子节点替换为其位置即可。

如果要删除的节点有两个子节点,那么找到后继节点,然后将其替换为要删除的节点,然后删除后继节点。

C++
void deleteNode(TreeNode*& node, int value) {
    if (node == nullptr) return;
    if (node->data == value) {
        if (node->left == nullptr && node->right == nullptr) {
            delete node;
            node = nullptr;
        } else if (node->left == nullptr) {
            TreeNode* temp = node;
            node = node->right;
            delete temp;
        } else if (node->right == nullptr) {
            TreeNode* temp = node;
            node = node->left;
            delete temp;
        } else {
            TreeNode* temp = getSuccessor(node->right);
            node->data = temp->data;
            delete temp;
        }
    } else if (node->data > value) {
        deleteNode(node->left, value);
    } else {
        deleteNode(node->right, value);
    }
}

TreeNode* getSuccessor(TreeNode* node) {
    while (node->left != nullptr) {
        node = node->left;
    }
    return node;
}

Stanford Set(斯坦福集合)

使用(略微修改的)二叉树实现

  • 有序元素

  • O(log N)时间搜索、添加和删除元素


树成员模板

C++
returnType TreeSet::functionName(parameters)
{
    helper(root, parameters);
}

returnType helperName(TreeNode* node, parameters){
    ...
}

Tree maps(树映射)

  • 每个树节点将同时存储一个键(key)和一个值(value)

  • 树是按其键(key)的二叉搜索树(BST)顺序排列

  • 键必须是可比较的(具备 < 运算符)以便进行排序

C++
struct TreeMapNode {
    string key;
    int value;
    TreeMapNode* left;
    TreeMapNode* right;
};

Balanced Trees(平衡树)

当你的二叉搜索树不平衡的时候,你将会失去(log n)的性质.

就像如果你存入了 10000 个元素,但是你却只用了 100 个,那么你就失去了对这 100 个元素的快速查找的能力.

为了解决这个问题,我们需要使用一种平衡树,比如 AVL 树,红黑树,或者伸展树.

Red-Black Trees(红黑树)

给每个节点赋予红色或黑色的“颜色”。

  • 根节点是黑色。根节点的直接子节点是红色。所有叶子节点是黑色。

  • 如果一个节点是红色,则它的所有子节点必须都是黑色。

  • 从一个节点向下到最底部的每条路径必须包含相同数量的“黑色”节点。

树旋转(Tree Rotations)

  • 左旋(Left Rotation):将一个节点的右子树上移,使其成为父节点的左子树。

  • 右旋(Right Rotation):将一个节点的左子树上移,使其成为父节点的右子树。

  • 左右旋(Left-Right Rotation):先左旋,再右旋。

  • 右左旋(Right-Left Rotation):先右旋,再左旋。

Tries(Prefix Trees)

非常适合用于查找前缀或作为字典使用

  • 每个节点对应于一个单词的字母,通过遍历树来追溯这个单词

  • 每个节点知道到该节点的字母是否能拼成一个单词

c++
struct TrieNode{
    bool isWord;
    trieNode* children[26];
};

## 扩展(哈夫曼树)

哈夫曼树(Huffman Tree)是一种用于数据压缩的树形结构,主要用于生成哈夫曼编码。其主要特点和构建方法如下:

1. 构造一棵二叉树,每个节点对应于一个字符,树的高度为字符的个数。

2. 构造一棵带权路径最短的二叉树,权值即字符出现的频率。

3. 合并两个二叉树,权值较大的树作为左子树,权值较小的树作为右子树。

4. 重复步骤3,直到得到一棵只有一个节点的树,即哈夫曼树。