C语言这个红黑树,用链表实现
时间: 2024-01-21 08:44:05 浏览: 19
红黑树是一种自平衡的二叉搜索树,而链表是一种线性数据结构,它们的本质是不同的,所以不能直接用链表来实现红黑树。但是,我们可以用链表来实现红黑树中的节点。
红黑树的节点需要存储颜色、键值、左子节点、右子节点和父节点等信息,我们可以定义一个结构体来表示一个节点:
```c
typedef struct RBTreeNode {
int key; // 键值
int color; // 颜色,0表示黑色,1表示红色
struct RBTreeNode *left; // 左子节点
struct RBTreeNode *right; // 右子节点
struct RBTreeNode *parent; // 父节点
} RBTreeNode;
```
接下来,我们可以定义一些基本操作,比如创建节点、插入节点、删除节点等。这些操作都需要维护红黑树的性质,可以参考标准的红黑树实现方法来实现。
以下是一个简单的红黑树实现示例,其中节点使用链表来表示:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct RBTreeNode {
int key;
int color;
struct RBTreeNode *left;
struct RBTreeNode *right;
struct RBTreeNode *parent;
} RBTreeNode;
RBTreeNode* createNode(int key) {
RBTreeNode *node = (RBTreeNode*) malloc(sizeof(RBTreeNode));
node->key = key;
node->color = 1; // 新插入的节点默认为红色
node->left = NULL;
node->right = NULL;
node->parent = NULL;
return node;
}
void insertNode(RBTreeNode **root, RBTreeNode *node) {
// 插入节点
RBTreeNode *parent = NULL;
RBTreeNode *current = *root;
while (current != NULL) {
parent = current;
if (node->key < current->key) {
current = current->left;
} else {
current = current->right;
}
}
node->parent = parent;
if (parent == NULL) {
*root = node; // 树为空,插入根节点
} else if (node->key < parent->key) {
parent->left = node;
} else {
parent->right = node;
}
// 调整红黑树
while (node != *root && node->parent->color == 1) {
if (node->parent == node->parent->parent->left) {
RBTreeNode *uncle = node->parent->parent->right;
if (uncle != NULL && uncle->color == 1) {
// case 1: 父节点和叔节点都是红色
node->parent->color = 0;
uncle->color = 0;
node->parent->parent->color = 1;
node = node->parent->parent;
} else {
if (node == node->parent->right) {
// case 2: 父节点是红色,叔节点是黑色,当前节点是父节点的右子节点
node = node->parent;
leftRotate(root, node);
}
// case 3: 父节点是红色,叔节点是黑色,当前节点是父节点的左子节点
node->parent->color = 0;
node->parent->parent->color = 1;
rightRotate(root, node->parent->parent);
}
} else {
RBTreeNode *uncle = node->parent->parent->left;
if (uncle != NULL && uncle->color == 1) {
// case 1: 父节点和叔节点都是红色
node->parent->color = 0;
uncle->color = 0;
node->parent->parent->color = 1;
node = node->parent->parent;
} else {
if (node == node->parent->left) {
// case 2: 父节点是红色,叔节点是黑色,当前节点是父节点的左子节点
node = node->parent;
rightRotate(root, node);
}
// case 3: 父节点是红色,叔节点是黑色,当前节点是父节点的右子节点
node->parent->color = 0;
node->parent->parent->color = 1;
leftRotate(root, node->parent->parent);
}
}
}
(*root)->color = 0; // 根节点为黑色
}
void leftRotate(RBTreeNode **root, RBTreeNode *node) {
RBTreeNode *right = node->right;
node->right = right->left;
if (right->left != NULL) {
right->left->parent = node;
}
right->parent = node->parent;
if (node->parent == NULL) {
*root = right;
} else if (node == node->parent->left) {
node->parent->left = right;
} else {
node->parent->right = right;
}
right->left = node;
node->parent = right;
}
void rightRotate(RBTreeNode **root, RBTreeNode *node) {
RBTreeNode *left = node->left;
node->left = left->right;
if (left->right != NULL) {
left->right->parent = node;
}
left->parent = node->parent;
if (node->parent == NULL) {
*root = left;
} else if (node == node->parent->left) {
node->parent->left = left;
} else {
node->parent->right = left;
}
left->right = node;
node->parent = left;
}
void deleteNode(RBTreeNode **root, RBTreeNode *node) {
// TODO: 实现删除节点操作
}
void printTree(RBTreeNode *root) {
if (root != NULL) {
printf("%d%c ", root->key, root->color == 0 ? 'B' : 'R');
printTree(root->left);
printTree(root->right);
}
}
int main() {
RBTreeNode *root = NULL;
insertNode(&root, createNode(10));
insertNode(&root, createNode(20));
insertNode(&root, createNode(30));
insertNode(&root, createNode(15));
insertNode(&root, createNode(18));
insertNode(&root, createNode(25));
insertNode(&root, createNode(35));
printTree(root); // 输出: 20B 15R 10B 18B 30B 25R 35R
return 0;
}
```
注意,这只是一个简单的示例,实际上红黑树的实现比这个复杂得多。如果需要使用红黑树实现某个功能,建议使用现成的库或者参考标准实现方法来实现。