红黑树是一种自平衡的二叉查找树,它在插入和删除节点时能够保持树的平衡,从而在实际应用中具有高效的查找、插入和删除操作。以下是关于C++红黑树的介绍,包括其基本概念、实现原理、代码实现等内容。
一、基本概念
红黑树是一种特殊的二叉查找树,它满足以下性质:
- 每个节点要么是红色,要么是黑色。
- 根节点是黑色。
- 所有叶子节点(通常为NULL节点)是黑色。
- 如果一个节点是红色的,则它的两个子节点都是黑色。
- 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
二、实现原理
红黑树的实现原理主要涉及到旋转和颜色调整等操作。在插入和删除节点时,红黑树通过旋转和颜色调整来保持树的平衡。红黑树的旋转操作包括左旋、右旋和左右旋、右左旋等。
红黑树的插入操作主要分为以下步骤:
- 将新节点插入到树中,并赋予其颜色。
- 如果新节点的父节点是黑色的,则不需要进行调整。
- 如果新节点的父节点是红色的,则需要进行颜色调整和旋转操作,以保持红黑树的性质。
红黑树的删除操作主要分为以下步骤:
- 将要删除的节点标记为红色,以便后续处理。
- 将要删除的节点的后继节点(即最右边的黑色节点)标记为要删除的节点。
- 删除要删除的节点,并进行颜色调整和旋转操作,以保持红黑树的性质。
三、代码实现
以下是C++实现红黑树的示例代码:
#include <iostream>
enum Color { RED, BLACK };
struct Node {
int data;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int data) : data(data), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
class RedBlackTree {
private:
Node* root;
void rotateLeft(Node* node) {
Node* rightChild = node->right;
node->right = rightChild->left;
if (rightChild->left != nullptr) {
rightChild->left->parent = node;
}
rightChild->parent = node->parent;
if (node->parent == nullptr) {
root = rightChild;
} else if (node == node->parent->left) {
node->parent->left = rightChild;
} else {
node->parent->right = rightChild;
}
rightChild->left = node;
node->parent = rightChild;
}
void rotateRight(Node* node) {
Node* leftChild = node->left;
node->left = leftChild->right;
if (leftChild->right != nullptr) {
leftChild->right->parent = node;
}
leftChild->parent = node->parent;
if (node->parent == nullptr) {
root = leftChild;
} else if (node == node->parent->left) {
node->parent->left = leftChild;
} else {
node->parent->right = leftChild;
}
leftChild->right = node;
node->parent = leftChild;
}
void fixInsert(Node* node) {
while (node != root && node->parent->color == RED) {
if (node->parent == node->parent->parent->left) {
Node* uncle = node->parent->parent->right;
if (uncle != nullptr && uncle->color == RED) {
node->parent->color = BLACK;
uncle->color = BLACK;
node->parent->parent->color = RED;
node = node->parent->parent;
} else {
if (node == node->parent->right) {
node = node->parent;
rotateLeft(node);
}
node->parent->color = BLACK;
node->parent->parent->color = RED;
rotateRight(node->parent->parent);
}
} else {
Node* uncle = node->parent->parent->left;
if (uncle != nullptr && uncle->color == RED) {
node->parent->color = BLACK;
uncle->color = BLACK;
node->parent->parent->color = RED;
node = node->parent->parent;
} else {
if (node == node->parent->left) {
node = node->parent;
rotateRight(node);
}
node->parent->color = BLACK;
node->parent->parent->color = RED;
rotateLeft(node->parent->parent);
}
}
}
root->color = BLACK;
}
public:
RedBlackTree() : root(nullptr) {}
void insert(int data) {
Node* newNode = new Node(data);
Node* current = root;
Node* parent = nullptr;
while (current != nullptr) {
parent = current;
if (data < current->data) {
current = current->left;
} else {
current = current->right;
}
}
newNode->parent = parent;
if (parent == nullptr) {
root = newNode;
} else if (data < parent->data) {
parent->left = newNode;
} else {
parent->right = newNode;
}
fixInsert(newNode);
}
void printInorder(Node* node) {
if (node == nullptr) {
return;
}
printInorder(node->left);
std::cout << node->data << " ";
printInorder(node->right);
}
void printTree() {
printInorder(root);
}
};
int main() {
RedBlackTree tree;
tree.insert(7);
tree.insert(3);
tree.insert(18);
tree.insert(10);
tree.insert(22);
tree.insert(8);
tree.insert(11);
tree.insert(26);
tree.insert(2);
tree.insert(6);
tree.insert(13);
std::cout << "树";
tree.printTree();
return 0;
}