在计算机科学中,红黑树(Red-Black tree)是一种自平衡的二叉搜索树,它是在B树的基础上添加了颜色标记,用以保证其在插入和删除等操作后能够保持平衡。红黑树的特点是:
首先,我们定义一个Node
结构体来表示红黑树的节点:
cppCopy codestruct Node {
int data;
bool isBlack;
Node* left;
Node* right;
Node* parent;
};
其中,data
字段表示节点存储的数据,isBlack
字段表示节点的颜色(黑色为true,红色为false),left
和right
字段分别指向节点的左子节点和右子节点,parent
字段指向节点的父节点。 接下来,我们定义一个RedBlackTree
类来实现红黑树的操作:
cppCopy codeclass RedBlackTree {
public:
RedBlackTree();
~RedBlackTree();
bool search(int key);
void insert(int key);
void remove(int key);
void printTree();
private:
void insertFixup(Node* node);
void deleteFixup(Node* node, Node* parent);
void rotateLeft(Node* node);
void rotateRight(Node* node);
void transplant(Node* u, Node* v);
void destroyTree(Node* node);
void printTreeHelper(Node* node, int indent);
Node* root;
};
接下来,我们来实现红黑树的插入操作。插入操作分为两个步骤:首先按照二叉搜索树的规则找到插入位置,然后根据红黑树的规则进行调整。 在RedBlackTree
类中,我们添加一个insert
方法用于插入新节点:
cppCopy codevoid RedBlackTree::insert(int key) {
Node* newNode = new Node();
newNode->data = key;
newNode->isBlack = false;
newNode->left = NULL;
newNode->right = NULL;
Node* current = root;
Node* parent = NULL;
// 找到插入位置
while (current != NULL) {
parent = current;
if (key < current->data) {
current = current->left;
}
else if (key > current->data) {
current = current->right;
}
else {
// 若节点已存在,则直接返回
delete newNode;
return;
}
}
newNode->parent = parent;
// 插入新节点
if (parent == NULL) {
// 空树,直接将新节点设为根节点
root = newNode;
}
else if (key < parent->data) {
parent->left = newNode;
}
else {
parent->right = newNode;
}
// 调整红黑树
insertFixup(newNode);
}
在插入节点后,我们可能需要进行一系列的旋转和颜色调整来满足红黑树的规则。具体的插入调整逻辑包括以下几种情况:
cppCopy codevoid RedBlackTree::insertFixup(Node* node) {
Node* parent = NULL;
Node* grandparent = NULL;
while (node != root && node->isBlack == false && node->parent->isBlack == false) {
parent = node->parent;
grandparent = parent->parent;
if (parent == grandparent->left) {
Node* uncle = grandparent->right;
if (uncle != NULL && uncle->isBlack == false) {
parent->isBlack = true;
uncle->isBlack = true;
grandparent->isBlack = false;
node = grandparent;
}
else {
if (node == parent->right) {
rotateLeft(parent);
node = parent;
parent = node->parent;
}
rotateRight(grandparent);
std::swap(parent->isBlack, grandparent->isBlack);
node = parent;
}
}
else {
Node* uncle = grandparent->left;
if (uncle != NULL && uncle->isBlack == false) {
parent->isBlack = true;
uncle->isBlack = true;
grandparent->isBlack = false;
node = grandparent;
}
else {
if (node == parent->left) {
rotateRight(parent);
node = parent;
parent = node->parent;
}
rotateLeft(grandparent);
std::swap(parent->isBlack, grandparent->isBlack);
node = parent;
}
}
}
root->isBlack = true;
}
除了插入操作,我们还可以实现红黑树的搜索、删除和打印等操作。这里为了篇幅,省略了这些方法的实现。感兴趣的读者可以尝试自己实现或者参考其他资料。 为了方便调试和验证,我们还提供了一个打印红黑树的方法:
cppCopy codevoid RedBlackTree::printTree() {
if (root == NULL) {
std::cout << "Empty tree" << std::endl;
return;
}
printTreeHelper(root, 0);
}
void RedBlackTree::printTreeHelper(Node* node, int indent) {
if (node == NULL) {
return;
}
printTreeHelper(node->right, indent + 4);
if (indent > 0) {
std::cout << std::setw(indent) << " ";
}
std::cout << node->data << (node->isBlack ? "B" : "R") << std::endl;
printTreeHelper(node->left, indent + 4);
}
红黑树是一种自平衡的二叉查找树,在面试中常被问及。了解红黑树的实现细节,可以帮助你更好地理解其原理和特性。下面我将介绍红黑树的一般实现流程,帮助你对其有更全面的了解。 红黑树的实现细节包括以下几个方面:
pythonCopy codeclass Node:
def __init__(self, data, color):
self.data = data
self.left = None
self.right = None
self.parent = None
self.color = color
pythonCopy codedef insert(self, data):
node = Node(data, "RED")
# 将节点插入合适的位置
# ...
# 插入后对树进行修复
self._insert_fixup(node)
插入修复操作的伪代码如下:
pythonCopy codedef _insert_fixup(self, node):
while node.parent and node.parent.color == "RED":
if node.parent == node.parent.parent.left:
uncle = node.parent.parent.right
if uncle and 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
self._left_rotate(node)
node.parent.color = "BLACK"
node.parent.parent.color = "RED"
self._right_rotate(node.parent.parent)
else:
# 类似处理右边对称的情况
# ...
self.root.color = "BLACK"
pythonCopy codedef delete(self, data):
node = self._search(data) # 先找到待删除的节点
if not node:
return
self._remove(node) # 删除节点
self._remove_fixup(node.parent) # 修复红黑树
删除修复操作的伪代码如下:
pythonCopy codedef _remove_fixup(self, node):
while node != self.root and node.color == "BLACK":
if node == node.parent.left:
sibling = node.parent.right
if sibling.color == "RED":
sibling.color = "BLACK"
node.parent.color = "RED"
self._left_rotate(node.parent)
sibling = node.parent.right
if (not sibling.left or sibling.left.color == "BLACK") and \
(not sibling.right or sibling.right.color == "BLACK"):
sibling.color = "RED"
node = node.parent
else:
if not sibling.right or sibling.right.color == "BLACK":
sibling.left.color = "BLACK"
sibling.color = "RED"
self._right_rotate(sibling)
sibling = node.parent.right
sibling.color = node.parent.color
node.parent.color = "BLACK"
sibling.right.color = "BLACK"
self._left_rotate(node.parent)
node = self.root
else:
# 类似处理右边对称的情况
# ...
node.color = "BLACK"
这是红黑树的一个基本实现,但实际上还有许多细节需要考虑,例如树的查找、旋转等操作,以及对应的辅助函数的实现。红黑树的实现还有很多变种和优化,涉及更多的特殊情况处理和平衡性维护。但是通过了解这个基本的实现流程,你应该可以更好地理解红黑树的原理和特性,并能够自己实现一个简单的红黑树。
至此,我们完成了红黑树的基本操作和打印方法的实现。红黑树是一种重要的自平衡二叉搜索树,在很多场景下都有广泛的应用。通过手写实现红黑树,我们不仅能够更深入地理解红黑树的原理和操作,还能够提升自己的编程能力。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。