红黑树的C语言简单实现与代码解析
2023-12-23 23:33:26
红黑树 C 语言的简单实现与代码解析
红黑树是计算机科学中一种重要的自平衡二叉搜索树。它确保了在最坏情况下,基本的动态集合操作(如插入、删除和查找)具有对数时间复杂度。在这篇博客中,我们将介绍一个简化的C语言红黑树实现,并对代码进行详细解析。
1、示例代码
#include <stdio.h>
#include <stdlib.h>
typedef enum { RED, BLACK } color_t;
typedef struct Node {
int data;
color_t color;
struct Node *left, *right, *parent;
} Node;
typedef struct RedBlackTree {
Node *root;
} RedBlackTree;
// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->left = newNode->right = newNode->parent = NULL;
newNode->color = RED; // 默认为红色
return newNode;
}
// 左旋
void leftRotate(RedBlackTree* tree, Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != NULL) y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL) tree->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(RedBlackTree* tree, Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != NULL) x->right->parent = y;
x->parent = y->parent;
if (y->parent == NULL) tree->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(RedBlackTree* tree, Node* z) {
while (z->parent && z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(tree, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(tree, z->parent->parent);
}
} else {
// 类似地处理右侧情况
// ...
}
}
tree->root->color = BLACK;
}
// 插入节点
void insert(RedBlackTree* tree, int data) {
Node* z = createNode(data);
Node* y = NULL;
Node* x = tree->root;
while (x != NULL) {
y = x;
if (z->data < x->data) x = x->left;
else x = x->right;
}
z->parent = y;
if (y == NULL) tree->root = z;
else if (z->data < y->data) y->left = z;
else y->right = z;
insertFixup(tree, z);
}
// 其他操作(如删除、查找等)可以根据上述模式扩展
int main() {
RedBlackTree tree = {NULL};
int arr[] = {7, 3, 18, 10, 22, 8, 11, 26, 2, 6, 13};
int n = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < n; i++) {
insert(&tree, arr[i]);
}
// 执行其他操作或打印树结构
return 0;
}
2、代码解析
2.1. 基本结构
我们首先定义了两个基本结构:Node
和 RedBlackTree
。
typedef enum { RED, BLACK } color_t;
typedef struct Node {
int data;
color_t color;
struct Node *left, *right, *parent;
} Node;
typedef struct RedBlackTree {
Node *root;
} RedBlackTree;
Node
结构包含一个整数数据、一个颜色(红色或黑色)以及左、右子节点和父节点的指针。RedBlackTree
结构只包含一个根节点指针。
2.2 左旋与右旋操作
红黑树的核心操作之一是旋转,这有助于维护树的平衡性。
leftRotate
和rightRotate
函数分别实现了左旋和右旋操作。
2.2 1. 左旋操作
左旋操作是为了将一个节点旋转到其右子节点的位置。这个操作旨在维护红黑树的平衡性。以下是左旋操作的步骤:
- 选择节点:假设要进行左旋的节点为 x,并且其右子节点为 y。
- 更新子节点:将 x 的右子节点 y 的左子节点(y 的左子节点)作为 x 的新右子节点。
- 更新父节点:如果 x 有父节点,更新其父节点以指向 y 而不是 x。
- 更新 y 的左子节点:将 y 的左子节点设置为 x。
- 更新 x 的父节点:将 y 的父节点设置为 x 的父节点。
2.2.2 右旋操作
右旋操作与左旋相反。它是为了将一个节点旋转到其左子节点的位置。以下是右旋操作的步骤:
右旋步骤:
- 选择节点:假设要进行右旋的节点为 y,并且其左子节点为 x。
- 更新子节点:将 y 的左子节点 x 的右子节点(x 的右子节点)作为 y 的新左子节点。
- 更新父节点:如果 y 有父节点,更新其父节点以指向 x 而不是 y。
- 更新 x 的右子节点:将 x 的右子节点设置为 y。
- 更新 y 的父节点:将 x 的父节点设置为 y 的父节点。
3. 插入与修复操作
当向红黑树中插入新节点时,可能会破坏红黑树的性质。因此,我们需要进行修复操作。
insertFixup
函数实现了在插入后修复红黑树的逻辑。
4. 插入操作
为了简化,我们只展示了如何向红黑树中插入新节点。其他操作(如删除、查找等)可以基于相似的原理进行扩展。
5. 示例
在主函数中,我们展示了如何使用上述功能来创建和填充一个红黑树。
int main() {
RedBlackTree tree = {NULL};
int arr[] = {7, 3, 18, 10, 22, 8, 11, 26, 2, 6, 13};
int n = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < n; i++) {
insert(&tree, arr[i]);
}
return 0;
}
3、结论
虽然上述代码提供了一个基本的红黑树实现,但实际上红黑树的设计和实现要复杂得多。在实际应用中,需要考虑许多其他细节和情况。然而,通过这个简化的示例,我们可以更好地理解红黑树的基本原理和操作。
文章来源:https://blog.csdn.net/StoryZX/article/details/135176294
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!