一、红黑树的一般概念
红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它在插入和删除操作时通过一系列规则来保持平衡。红黑树具有以下特点:
1、二叉搜索树性质:红黑树是一棵二叉搜索树,意味着每个节点有两个子节点,左子节点的值小于当前节点的值,右子节点的值大于当前节点的值。
2、节点着色:每个节点都有一个颜色,可以是红色或黑色。
3、根节点是黑色:根节点必须是黑色的,这是红黑树的第一条规则。
4、红色节点不能相连:红色节点不能连续出现,也就是说,不能有两个相邻的红色节点。
5、每个叶子节点是黑色的:红黑树中的叶子节点(NIL 节点或空节点)都被认为是黑色的。
6、从任何节点到其每个叶子的每条路径都具有相同数量的黑色节点:这是红黑树的关键性质,它确保了树的平衡性。因为从根节点到叶子节点的最长路径不会超过最短路径的两倍,所以红黑树的高度是 O(log n)。
这些规则确保了红黑树的平衡性,因此在插入和删除操作后,树的高度仍然保持相对较小,从而保持了搜索、插入和删除操作的平均时间复杂度为 O(log n)。
二、红黑树的基本操作
1、插入操作:
插入一个节点后,树可能会违反红黑树的性质,需要通过一系列的旋转和着色操作来恢复平衡。
插入操作的关键在于确保新插入的节点是红色的,然后根据父节点和叔节点的颜色来进行不同类型的旋转和着色。
2、删除操作:
删除一个节点后,树可能会违反红黑树的性质,需要通过一系列的旋转和着色操作来恢复平衡。
删除操作的关键在于将节点的删除转化为将某个后继节点或前驱节点移动到删除节点的位置上,然后删除后继节点或前驱节点。
3、查找操作:
红黑树的查找操作与普通二叉搜索树相同,通过比较节点的值来向左或向右移动,直到找到目标节点或发现节点不存在。
4、旋转操作:
旋转操作用于维护红黑树的平衡,有左旋和右旋两种类型。它们被用于解决插入和删除操作后破坏的平衡。
红黑树的平衡性质使其成为一种非常有效的数据结构,适用于各种情况,特别是在需要高效的插入和删除操作时。许多编程语言和标准库中都包含了红黑树的实现,用于实现诸如字典、集合等数据结构。
三、红黑树的缺陷
红黑树是一种非常有效的自平衡二叉搜索树,但它也有一些缺点和限制是需要在使用时考虑到的。尽管红黑树有这些缺点,但它仍然是一种非常有用的数据结构,尤其是在需要高效的插入和删除操作以及平衡搜索操作的情况下。在许多编程语言和标准库中,红黑树被广泛使用,因为它提供了可靠的性能和平衡。然而,在选择数据结构时,应根据特定的应用场景和需求考虑是否使用红黑树,或者是否有更适合的替代方案。
1、复杂性:
红黑树的插入和删除操作相对复杂,需要考虑多种情况和执行多个旋转和着色操作以维持平衡性。这种复杂性使得实现和维护红黑树的代码可能比其他平衡二叉搜索树更难理解和调试。
2、性能开销:
红黑树的插入和删除操作通常需要进行多次旋转和着色操作,这些操作涉及多次指针重定向和数据的移动,可能引入性能开销,尤其是在频繁插入和删除的情况下。
3、不适合大量读取操作:
虽然红黑树的查找操作在平均情况下具有较好的性能(O(log n)),但对于大量的读取操作而言,与无序数组相比,它可能有较高的性能开销,因为它需要维护平衡。
4、空间开销:
红黑树需要存储额外的颜色信息,这会占用额外的存储空间。相对于普通的二叉搜索树,红黑树的节点需要额外的一个比特来表示颜色信息。
5、不支持高并发写入:
红黑树的自平衡特性可能导致多个线程在进行插入和删除操作时需要频繁地争夺锁,这可能成为高并发写入场景下的性能瓶颈。在高度并发的情况下,可能需要使用其他数据结构来提高性能,例如跳表或哈希表。
6、不适用于某些特殊用途:
红黑树的平衡性质使其适用于一般的数据存储和搜索操作,但对于某些特殊用途,如内存分配器或实时系统,可能不是最佳选择。在这些情况下,可能需要更专门的数据结构。
四、linux内核里使用红黑树的例子
Linux内核中使用红黑树(Red-Black Tree)数据结构的功能非常广泛,这种自平衡二叉搜索树有助于高效地管理和检索数据(查找、插入和删除),给内核在各个子系统中提供高性能和高效率的功能。这是一种在高性能和高效率方面非常有用的数据结构,用于管理和检索各种内核数据。
它的自平衡性质确保了高效的数据操作,在各种情况下维护数据结构的平衡,从而提高了内核的性能和可靠性。因此在操作系统内核中的应用非常多。
下面是linux内核中红黑树相关函数操作:
1、数据结构定义:
内核定义了红黑树的数据结构,包括 struct rb_node 用于表示树节点,以及 struct rb_root 用于表示树的根节点。这些数据结构被用于在内核中创建和操作红黑树。
2、初始化和销毁:
内核提供了初始化和销毁红黑树的函数,例如 RB_ROOT 宏用于初始化树的根节点,rb_insert_color() 用于向树中插入节点,rb_erase() 用于从树中删除节点。
3、插入和删除操作:
Linux 内核使用红黑树来高效地管理各种数据结构,如进程描述符、文件描述符、内存页等。插入和删除操作的实现确保了树的平衡性,并且在 O(log n) 时间内完成。
4、查找操作:
rb_find() 和 rb_find_closest() 函数允许内核通过关键字查找树中的节点。这些函数在各种内核子系统中用于查找目标数据,如进程、文件、网络路由等。
5、范围查找:
内核提供了一些函数,如 rb_first() 和 rb_last(),用于执行范围查找操作,以查找树中特定范围内的节点。
6、迭代遍历:
内核支持使用 rbtree_postorder_for_each_entry() 和 rbtree_inorder_for_each_entry() 等宏来遍历红黑树中的节点。这对于执行特定操作或收集信息非常有用。
下面是Linux内核中使用红黑树的一些相关功能和应用:
1、进程调度:Linux内核使用红黑树来管理进程调度。每个运行中的进程都有一个进程控制块(进程描述符struct task_struct),这些块通过红黑树进行组织和调度,进程们都在进程调度器的红黑树中维护一个节点,通过对红黑树进行适当的旋转和平衡,这样可以根据进程的优先级和其他因素轻松地查找和选择下一个要运行的进程。红黑树的平衡特性确保了进程调度的高效性。
2、文件系统:Linux文件系统中的inode对象也使用红黑树来组织和管理。这允许系统快速地查找文件和目录,并支持高效的文件系统操作。例如,dentry 结构表示一个目录项,这些目录项可以添加到红黑树中,每个目录都可以用一个红黑树来组织其中的文件和子目录,以便高效地查找和访问它们。
3、定时器管理:内核中的定时器管理通常也使用红黑树来实现。这可以用于管理各种定时事件,如进程超时、I/O超时等。红黑树的自平衡特性确保了定时器事件的高效处理,提高定时器查找和触发的效率。例如,struct timer_list 结构体表示一个定时器,这些定时器可以添加到红黑树中,以便按计划触发回调函数,其中的 expires 字段被用作关键字,使得内核能够在 O(log n) 时间内查找和触发定时器。
4、虚拟内存管理:红黑树可用于管理虚拟内存中的页表项,用于快速查找和映射虚拟地址到物理地址的操作。
5、设备驱动:Linux内核中的设备驱动程序通常也使用红黑树来维护设备列表。这样可以在设备数量增加时提供快速的查找和访问。例如 USB 设备管理和块设备驱动程序可以使用红黑树来管理设备列表。
6、系统调用表:红黑树可以用于维护系统调用表,以便系统可以快速查找和执行系统调用。
7、网络子系统:在网络子系统中,红黑树通常用于管理连接状态、套接字或路由表,以实现高性能和高效的网络通信,加速查找和操作。路由表中的路由项可以根据目的地址添加到红黑树中,以便快速查找目标主机的路由信息然后发送对应路由的数据包。这对于数据包的高效路由非常重要。
8、内存管理:红黑树也可用于内存分配和管理,以跟踪可用内存块或页面。红黑树在内核中用于管理内存页后,可以有效地分配和释放内存。这有助于内核避免内存碎片,以及高效地查找可用的内存页。例如,struct page 结构用于表示内存页,这些页可以根据地址添加到红黑树中,以便高效地查找可用的内存页。
9、调度器:红黑树被用于调度器的实现,以便根据优先级和其他因素高效地选择要运行的任务。进程控制块(struct task_struct)通过红黑树进行排序,根据进程的优先级和其他因素选择下一个要运行的任务。
10、虚拟文件系统:Linux 内核中的虚拟文件系统(如ext4、XFS、VFS)使用红黑树来管理打开的文件,管理目录项和索引节点,以及与文件路径相关的操作。struct file 结构表示一个打开的文件,这些文件可以添加到红黑树中,以便高效地查找和操作文件。
11、安全策略:安全模块(如 SELinux、AppArmor)使用红黑树来存储安全策略规则,以加速访问和决策。
12、事件通知:Linux 内核中的事件通知机制(如 epoll)使用红黑树来管理文件描述符,以便高效地检查和响应事件。
五、红黑树的C++示例
1、插入操作
#include <iostream>
// 红黑树节点的颜色
enum class Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int k) : key(k), color(Color::RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
class RedBlackTree {
private:
Node* root; // 红黑树的根节点
// 插入修复函数
void insertFixup(Node* z) {
while (z->parent && z->parent->color == Color::RED) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y && y->color == Color::RED) {
// 情况1: 父节点是红色的
z->parent->color = Color::BLACK;
y->color = Color::BLACK;
z->parent->parent->color = Color::RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是右子节点
if (z == z->parent->right) {
z = z->parent;
// 左旋代码
leftRotate(z);
}
// 情况3: 父节点是黑色的,且z是左子节点
z->parent->color = Color::BLACK;
z->parent->parent->color = Color::RED;
// 右旋代码
rightRotate(z->parent->parent);
}
} else {
// 对称的情况
if (z->parent) {
Node* y = z->parent->parent->left;
if (y && y->color == Color::RED) {
// 情况1: 父节点是红色的
z->parent->color = Color::BLACK;
y->color = Color::BLACK;
z->parent->parent->color = Color::RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是左子节点
if (z == z->parent->left) {
z = z->parent;
// 右旋代码
rightRotate(z);
}
// 情况3: 父节点是黑色的,且z是右子节点
z->parent->color = Color::BLACK;
z->parent->parent->color = Color::RED;
// 左旋代码
leftRotate(z->parent->parent);
}
}
}
}
root->color = Color::BLACK;
}
// 插入辅助函数
void insertHelper(int key) {
Node* z = new Node(key);
Node* y = nullptr;
Node* x = root;
while (x != nullptr) {
y = x;
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->parent = y;
if (y == nullptr)
root = z;
else if (z->key < y->key)
y->left = z;
else
y->right = z;
insertFixup(z);
}
// 左旋函数
void leftRotate(Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != nullptr)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// 右旋函数
void rightRotate(Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != nullptr)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == nullptr)
root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
public:
RedBlackTree() : root(nullptr) {}
// 公共插入函数
void insert(int key) {
insertHelper(key);
}
};
int main() {
RedBlackTree tree;
// 插入一些示例数据
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(2);
tree.insert(15);
tree.insert(30);
// 这里只包括了插入操作,你可以根据需要扩展其他操作,如删除和遍历。
return 0;
}
2、删除操作,包括删除节点和修复红黑树
#include <iostream>
// 红黑树节点的颜色
enum class Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int k) : key(k), color(Color::RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
class RedBlackTree {
private:
Node* root; // 红黑树的根节点
Node* nil; // 空节点,用于叶子节点的标记
// 左旋函数
void leftRotate(Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != nil)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// 右旋函数
void rightRotate(Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != nil)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == nullptr)
root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
// 删除修复函数
void deleteFixup(Node* x) {
while (x != root && x->color == Color::BLACK) {
if (x == x->parent->left) {
Node* w = x->parent->right;
if (w->color == Color::RED) {
// 情况1: 兄弟节点是红色的
w->color = Color::BLACK;
x->parent->color = Color::RED;
leftRotate(x->parent);
w = x->parent->right;
}
if (w->left->color == Color::BLACK && w->right->color == Color::BLACK) {
// 情况2: 兄弟节点是黑色的,兄弟节点的两个子节点也是黑色的
w->color = Color::RED;
x = x->parent;
} else {
if (w->right->color == Color::BLACK) {
// 情况3: 兄弟节点是黑色的,兄弟节点的左子节点是红色的,右子节点是黑色的
w->left->color = Color::BLACK;
w->color = Color::RED;
rightRotate(w);
w = x->parent->right;
}
// 情况4: 兄弟节点是黑色的,兄弟节点的右子节点是红色的
w->color = x->parent->color;
x->parent->color = Color::BLACK;
w->right->color = Color::BLACK;
leftRotate(x->parent);
x = root; // 跳出循环
}
} else {
// 对称的情况
// ...
}
}
x->color = Color::BLACK;
}
// 删除辅助函数
void deleteNode(Node* z) {
Node* y = z;
Node* x;
Color yOriginalColor = y->color;
if (z->left == nil) {
x = z->right;
transplant(z, z->right);
} else if (z->right == nil) {
x = z->left;
transplant(z, z->left);
} else {
y = getMinimum(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
transplant(y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if (yOriginalColor == Color::BLACK) {
deleteFixup(x);
}
delete z; // 释放节点内存
}
// 辅助函数:获取红黑树的最小节点
Node* getMinimum(Node* node) {
while (node->left != nil)
node = node->left;
return node;
}
// 用v节点替换u节点
void transplant(Node* u, Node* v) {
if (u->parent == nullptr)
root = v;
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
v->parent = u->parent;
}
public:
RedBlackTree() : root(nullptr), nil(new Node(0)) {
nil->color = Color::BLACK;
}
// 公共插入函数
void insert(int key) {
insertHelper(key);
}
// 公共删除函数
void remove(int key) {
Node* node = searchNode(key, root);
if (node != nullptr)
deleteNode(node);
}
// 中序遍历辅助函数
void inorderTraversal(Node* node) {
if (node != nil) {
inorderTraversal(node->left);
std::cout << node->key << "(" << (node->color == Color::RED ? "红" : "黑") << ") ";
inorderTraversal(node->right);
}
}
// 中序遍历并打印红黑树
void printTree() {
inorderTraversal(root);
std::cout << std::endl;
}
};
int main() {
RedBlackTree tree;
// 插入一些示例数据
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(2);
tree.insert(15);
tree.insert(30);
// 删除示例数据
tree.remove(5);
tree.remove(15);
// 打印红黑树
tree.printTree();
return 0;
}
3、遍历操作,包括中序、前序和后序遍历示例
#include <iostream>
// 红黑树节点的颜色
enum class Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int k) : key(k), color(Color::RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
class RedBlackTree {
private:
Node* root; // 红黑树的根节点
// 左旋函数
void leftRotate(Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != nullptr)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// 右旋函数
void rightRotate(Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != nullptr)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == nullptr)
root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
// 插入修复函数
void insertFixup(Node* z) {
while (z->parent && z->parent->color == Color::RED) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y && y->color == Color::RED) {
// 情况1: 父节点是红色的
z->parent->color = Color::BLACK;
y->color = Color::BLACK;
z->parent->parent->color = Color::RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是右子节点
if (z == z->parent->right) {
z = z->parent;
leftRotate(z);
}
// 情况3: 父节点是黑色的,且z是左子节点
z->parent->color = Color::BLACK;
z->parent->parent->color = Color::RED;
rightRotate(z->parent->parent);
}
} else {
// 对称的情况
if (z->parent) {
Node* y = z->parent->parent->left;
if (y && y->color == Color::RED) {
// 情况1: 父节点是红色的
z->parent->color = Color::BLACK;
y->color = Color::BLACK;
z->parent->parent->color = Color::RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是左子节点
if (z == z->parent->left) {
z = z->parent;
rightRotate(z);
}
// 情况3: 父节点是黑色的,且z是右子节点
z->parent->color = Color::BLACK;
z->parent->parent->color = Color::RED;
leftRotate(z->parent->parent);
}
}
}
}
root->color = Color::BLACK;
}
public:
RedBlackTree() : root(nullptr) {}
// 中序遍历辅助函数
void inorderTraversal(Node* node) {
if (node != nullptr) {
inorderTraversal(node->left);
std::cout << node->key << "(" << (node->color == Color::RED ? "红" : "黑") << ") ";
inorderTraversal(node->right);
}
}
// 前序遍历辅助函数
void preorderTraversal(Node* node) {
if (node != nullptr) {
std::cout << node->key << "(" << (node->color == Color::RED ? "红" : "黑") << ") ";
preorderTraversal(node->left);
preorderTraversal(node->right);
}
}
// 后序遍历辅助函数
void postorderTraversal(Node* node) {
if (node != nullptr) {
postorderTraversal(node->left);
postorderTraversal(node->right);
std::cout << node->key << "(" << (node->color == Color::RED ? "红" : "黑") << ") ";
}
}
// 中序遍历并打印红黑树
void printInorder() {
inorderTraversal(root);
std::cout << std::endl;
}
// 前序遍历并打印红黑树
void printPreorder() {
preorderTraversal(root);
std::cout << std::endl;
}
// 后序遍历并打印红黑树
void printPostorder() {
postorderTraversal(root);
std::cout << std::endl;
}
};
int main() {
RedBlackTree tree;
// 插入一些示例数据
tree.insert(10);
tree.insert(20);
tree.insert(5);
tree.insert(2);
tree.insert(15);
tree.insert(30);
// 中序遍历并打印红黑树
std::cout << "中序遍历结果:" << std::endl;
tree.printInorder();
// 前序遍历并打印红黑树
std::cout << "前序遍历结果:" << std::endl;
tree.printPreorder();
// 后序遍历并打印红黑树
std::cout << "后序遍历结果:" << std::endl;
tree.printPostorder();
return 0;
}
六、红黑树的C语言示例
1、插入操作
#include <stdio.h>
#include <stdlib.h>
// 红黑树节点的颜色
enum Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
enum Color color;
struct Node* left;
struct Node* right;
struct Node* parent;
};
// 创建一个新节点
struct Node* createNode(int key) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->key = key;
newNode->color = RED; // 新插入的节点默认为红色
newNode->left = newNode->right = newNode->parent = NULL;
return newNode;
}
// 左旋函数
void leftRotate(struct Node** root, struct Node* x) {
struct Node* y = x->right;
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
*root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// 右旋函数
void rightRotate(struct Node** root, struct Node* y) {
struct Node* x = y->left;
y->left = x->right;
if (x->right != NULL)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == NULL)
*root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
// 插入修复函数
void insertFixup(struct Node** root, struct Node* z) {
while (z->parent && z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
struct Node* y = z->parent->parent->right;
if (y && y->color == RED) {
// 情况1: 父节点是红色的
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是右子节点
if (z == z->parent->right) {
z = z->parent;
leftRotate(root, z);
}
// 情况3: 父节点是黑色的,且z是左子节点
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(root, z->parent->parent);
}
} else {
// 对称的情况
if (z->parent) {
struct Node* y = z->parent->parent->left;
if (y && y->color == RED) {
// 情况1: 父节点是红色的
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
// 情况2: 父节点是黑色的,且z是左子节点
if (z == z->parent->left) {
z = z->parent;
rightRotate(root, z);
}
// 情况3: 父节点是黑色的,且z是右子节点
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(root, z->parent->parent);
}
}
}
}
(*root)->color = BLACK;
}
// 插入操作
void insert(struct Node** root, int key) {
// 创建新节点
struct Node* z = createNode(key);
// BST插入操作
struct Node* y = NULL;
struct Node* x = *root;
while (x != NULL) {
y = x;
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->parent = y;
if (y == NULL)
*root = z; // 树为空,直接将z作为根节点
else if (z->key < y->key)
y->left = z;
else
y->right = z;
// 修复红黑树性质
insertFixup(root, z);
}
// 中序遍历并打印红黑树
void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d(%s) ", root->key, (root->color == RED ? "红" : "黑"));
inorderTraversal(root->right);
}
}
int main() {
struct Node* root = NULL;
// 插入一些示例数据
insert(&root, 10);
insert(&root, 20);
insert(&root, 5);
insert(&root, 2);
insert(&root, 15);
insert(&root, 30);
// 中序遍历并打印红黑树
printf("中序遍历结果:\n");
inorderTraversal(root);
printf("\n");
return 0;
}
2、删除操作,包括删除节点和修复红黑树
#include <stdio.h>
#include <stdlib.h>
// 红黑树节点的颜色
enum Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
enum Color color;
struct Node* left;
struct Node* right;
struct Node* parent;
};
// 创建一个新节点
struct Node* createNode(int key) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->key = key;
newNode->color = RED; // 新插入的节点默认为红色
newNode->left = newNode->right = newNode->parent = NULL;
return newNode;
}
// 左旋函数
void leftRotate(struct Node** root, struct Node* x) {
struct Node* y = x->right;
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
*root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// 右旋函数
void rightRotate(struct Node** root, struct Node* y) {
struct Node* x = y->left;
y->left = x->right;
if (x->right != NULL)
x->right->parent = y;
x->parent = y->parent;
if (y->parent == NULL)
*root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
// 删除修复函数
void deleteFixup(struct Node** root, struct Node* x) {
while (x != *root && x->color == BLACK) {
if (x == x->parent->left) {
struct Node* w = x->parent->right;
if (w->color == RED) {
// 情况1: 兄弟节点是红色的
w->color = BLACK;
x->parent->color = RED;
leftRotate(root, x->parent);
w = x->parent->right;
}
if (w->left->color == BLACK && w->right->color == BLACK) {
// 情况2: 兄弟节点是黑色的,兄弟节点的两个子节点也是黑色的
w->color = RED;
x = x->parent;
} else {
if (w->right->color == BLACK) {
// 情况3: 兄弟节点是黑色的,兄弟节点的左子节点是红色的,右子节点是黑色的
w->left->color = BLACK;
w->color = RED;
rightRotate(root, w);
w = x->parent->right;
}
// 情况4: 兄弟节点是黑色的,兄弟节点的右子节点是红色的
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
leftRotate(root, x->parent);
x = *root; // 跳出循环
}
} else {
// 对称的情况
// ...
}
}
x->color = BLACK;
}
// 删除节点
void deleteNode(struct Node** root, struct Node* z) {
struct Node* y = z;
struct Node* x;
enum Color yOriginalColor = y->color;
if (z->left == NULL) {
x = z->right;
transplant(root, z, z->right);
} else if (z->right == NULL) {
x = z->left;
transplant(root, z, z->left);
} else {
y = getMinimum(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
transplant(root, y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(root, z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if (yOriginalColor == BLACK) {
deleteFixup(root, x);
}
free(z); // 释放节点内存
}
// 辅助函数:获取红黑树的最小节点
struct Node* getMinimum(struct Node* node) {
while (node->left != NULL)
node = node->left;
return node;
}
// 用v节点替换u节点
void transplant(struct Node** root, struct Node* u, struct Node* v) {
if (u->parent == NULL)
*root = v;
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
if (v != NULL)
v->parent = u->parent;
}
// 中序遍历并打印红黑树
void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d(%s) ", root->key, (root->color == RED ? "红" : "黑"));
inorderTraversal(root->right);
}
}
int main() {
struct Node* root = NULL;
// 创建3个示例节点
struct Node* node1 = createNode(10);
struct Node* node2 = createNode(20);
struct Node* node3 = createNode(5);
// 构建示例红黑树结构
node1->color = BLACK;
node1->left = node3;
node1->right = node2;
// 删除节点
deleteNode(&root, 5);
return 0;
}
3、遍历操作,包括前序遍历、中序遍历和后序遍历
#include <stdio.h>
#include <stdlib.h>
// 红黑树节点的颜色
enum Color { RED, BLACK };
// 红黑树节点结构
struct Node {
int key;
enum Color color;
struct Node* left;
struct Node* right;
struct Node* parent;
};
// 创建一个新节点
struct Node* createNode(int key) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->key = key;
newNode->color = RED; // 新插入的节点默认为红色
newNode->left = newNode->right = newNode->parent = NULL;
return newNode;
}
// 前序遍历红黑树
void preorderTraversal(struct Node* root) {
if (root != NULL) {
printf("%d(%s) ", root->key, (root->color == RED ? "红" : "黑"));
preorderTraversal(root->left);
preorderTraversal(root->right);
}
}
// 中序遍历红黑树
void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d(%s) ", root->key, (root->color == RED ? "红" : "黑"));
inorderTraversal(root->right);
}
}
// 后序遍历红黑树
void postorderTraversal(struct Node* root) {
if (root != NULL) {
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d(%s) ", root->key, (root->color == RED ? "红" : "黑"));
}
}
int main() {
// 创建一个示例红黑树
struct Node* node1 = createNode(10);
struct Node* node2 = createNode(20);
struct Node* node3 = createNode(5);
struct Node* node4 = createNode(15);
struct Node* node5 = createNode(25);
// 构建示例红黑树结构
node1->color = BLACK;
node1->left = node3;
node1->right = node2;
node2->color = BLACK;
node2->left = node4;
node2->right = node5;
printf("前序遍历结果: ");
preorderTraversal(node1);
printf("\n");
printf("中序遍历结果: ");
inorderTraversal(node1);
printf("\n");
printf("后序遍历结果: ");
postorderTraversal(node1);
printf("\n");
return 0;
}