C++ 语言 红黑树的插入删除复杂度

C++阿木 发布于 2025-06-14 8 次阅读


阿木博主一句话概括:C++ 红黑树插入与删除操作复杂度分析及实现

阿木博主为你简单介绍:
红黑树是一种自平衡的二叉查找树,它通过保持树的平衡来确保查找、插入和删除操作的时间复杂度均为O(log n)。本文将围绕C++语言,对红黑树的插入和删除操作进行复杂度分析,并给出相应的代码实现。

一、
红黑树是一种在计算机科学中广泛使用的自平衡二叉查找树。它由Rudolf Bayer在1972年发明,并由Leo J. Guibas和Robert Sedgewick在1978年进行了详细描述。红黑树通过一系列的规则来确保树的平衡,使得树的高度保持在log n的范围内,从而保证了查找、插入和删除操作的时间复杂度均为O(log n)。

二、红黑树的性质
红黑树具有以下性质:
1. 每个节点要么是红色,要么是黑色。
2. 根节点是黑色。
3. 所有叶子节点(NIL节点)是黑色。
4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

三、插入操作复杂度分析
红黑树的插入操作可以分为以下步骤:
1. 将新节点作为红色节点插入到树的合适位置。
2. 通过一系列的旋转和颜色变换来修复树的平衡。

插入操作的复杂度分析如下:
- 插入节点:O(log n),因为需要找到插入位置。
- 修复平衡:O(log n),最坏情况下需要经过log n层树进行旋转和颜色变换。

红黑树的插入操作总的时间复杂度为O(log n)。

四、删除操作复杂度分析
红黑树的删除操作可以分为以下步骤:
1. 删除节点,类似于二叉查找树的删除操作。
2. 通过一系列的旋转和颜色变换来修复树的平衡。

删除操作的复杂度分析如下:
- 删除节点:O(log n),因为需要找到删除位置。
- 修复平衡:O(log n),最坏情况下需要经过log n层树进行旋转和颜色变换。

红黑树的删除操作总的时间复杂度为O(log n)。

五、代码实现
以下是一个简单的C++红黑树插入和删除操作的实现:

cpp
include

// 定义红黑树的节点
struct Node {
int data;
enum Color { RED, BLACK } color;
Node left, right, parent;

Node(int data) : data(data), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};

// 红黑树类
class RedBlackTree {
private:
Node root;

// 旋转操作
void rotateLeft(Node &, Node &);
void rotateRight(Node &, Node &);
void fixViolation(Node &, Node );

// 插入操作
void insertNonRecursive(Node &, Node &);
void insertRecursive(Node &, Node &);
void inorder(Node &);
void levelOrder(Node &);
void preOrder(Node &);
void postOrder(Node &);
void search(Node &, int, Node &);

public:
RedBlackTree() : root(nullptr) {}
void insert(int);
void deleteKey(int);
void inorder();
void levelOrder();
void preOrder();
void postOrder();
void search(int);
};

// 红黑树插入操作
void RedBlackTree::insert(int data) {
Node t = new Node(data);
root = insertNonRecursive(root, t);
}

// 红黑树删除操作
void RedBlackTree::deleteKey(int data) {
Node temp = root;
Node parent = nullptr;
search(root, data, parent, temp);
if (temp == nullptr) return;

if (temp->color == RED || temp->left == nullptr || temp->right == nullptr) {
// 删除节点是红色或叶子节点
deleteNode(temp);
} else {
// 删除节点是黑色且有两个孩子
Node successor = minimum(temp->right);
if (successor->color == RED) {
// 右孩子是红色
fixViolation(root, successor);
} else {
// 右孩子是黑色
if (successor->left == nullptr) {
// 右孩子是叶子节点
successor->color = temp->color;
successor->parent = temp->parent;
successor->left = temp->left;
successor->right = temp->right;
if (temp->parent != nullptr) {
if (temp == temp->parent->left)
temp->parent->left = successor;
else
temp->parent->right = successor;
} else {
root = successor;
}
deleteNode(temp);
} else {
// 右孩子有两个孩子
Node successorParent = successor->parent;
Node successorLeft = successor->left;
Node successorRight = successor->right;
successor->color = temp->color;
successor->parent = temp->parent;
successor->left = temp->left;
successor->right = temp->right;
if (successor->parent != nullptr) {
if (successor == successor->parent->left)
successor->parent->left = successor;
else
successor->parent->right = successor;
} else {
root = successor;
}
successor->left->parent = successor;
successor->right->parent = successor;
deleteNode(temp);
}
}
}
}

// 红黑树的其他操作(如中序遍历、层序遍历等)的实现略...

int main() {
RedBlackTree tree;
tree.insert(10);
tree.insert(20);
tree.insert(30);
tree.insert(40);
tree.insert(50);
tree.insert(25);

std::cout << "Inorder traversal of the given tree" << std::endl;
tree.inorder();

tree.deleteKey(20);

std::cout << "Inorder traversal after deletion of 20" << std::endl;
tree.inorder();

return 0;
}

六、总结
本文通过对红黑树的插入和删除操作进行了复杂度分析,并给出了相应的C++代码实现。红黑树的插入和删除操作的时间复杂度均为O(log n),这使得红黑树在需要频繁进行插入和删除操作的场景中非常有效。在实际应用中,红黑树常用于实现优先队列、字典树等数据结构。