代码实现
下面是一个简单的 C 语言实现的红黑树,包括构建、插入、删除和查找操作的示例代码。
#include <stdio.h>
#include <stdlib.h>
typedef enum { RED, BLACK } Color;
typedef struct Node {
int data;
Color color;
struct Node *left, *right, *parent;
} Node;
Node *NIL; // 代表空节点
Node* createNode(int data) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = data;
newNode->left = NIL;
newNode->right = NIL;
newNode->parent = NULL;
newNode->color = RED; // 新节点总是红色
return newNode;
}
// 左旋
void leftRotate(Node **root, 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 == 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(Node **root, 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 == NULL) {
*root = x;
} else if (y == y->parent->right) {
y->parent->right = x;
} else {
y->parent->left = x;
}
x->right = y;
y->parent = x;
}
// 修复红黑树的性质
void fixViolation(Node **root, Node *newNode) {
Node *parent = NULL;
Node *grandparent = NULL;
while ((newNode != *root) && (newNode->color == RED) && (newNode->parent->color == RED)) {
parent = newNode->parent;
grandparent = parent->parent;
// 父节点是祖父节点的左子节点
if (parent == grandparent->left) {
Node *uncle = grandparent->right;
// Case 1: 叔叔节点也是红色
if (uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
newNode = grandparent; // 向上继续检查
} else {
// Case 2: 新节点是父节点的右子节点
if (newNode == parent->right) {
leftRotate(root, parent);
newNode = parent;
parent = newNode->parent;
}
// Case 3: 新节点是父节点的左子节点
rightRotate(root, grandparent);
Color tempColor = parent->color;
parent->color = grandparent->color;
grandparent->color = tempColor;
newNode = parent;
}
} else { // 父节点是祖父节点的右子节点
Node *uncle = grandparent->left;
// Case 1: 叔叔节点也是红色
if (uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
newNode = grandparent; // 向上继续检查
} else {
// Case 2: 新节点是父节点的左子节点
if (newNode == parent->left) {
rightRotate(root, parent);
newNode = parent;
parent = newNode->parent;
}
// Case 3: 新节点是父节点的右子节点
leftRotate(root, grandparent);
Color tempColor = parent->color;
parent->color = grandparent->color;
grandparent->color = tempColor;
newNode = parent;
}
}
}
(*root)->color = BLACK; // 根节点始终是黑色
}
// 插入新节点
void insert(Node **root, int data) {
Node *newNode = createNode(data);
Node *y = NULL;
Node *x = *root;
while (x != NIL) {
y = x;
if (newNode->data < x->data) {
x = x->left;
} else {
x = x->right;
}
}
newNode->parent = y;
if (y == NULL) {
*root = newNode; // 树为空
} else if (newNode->data < y->data) {
y->left = newNode;
} else {
y->right = newNode;
}
fixViolation(root, newNode);
}
// 中序遍历
void inorderHelper(Node *root) {
if (root != NIL) {
inorderHelper(root->left);
printf("%d ", root->data);
inorderHelper(root->right);
}
}
void inorder(Node *root) {
inorderHelper(root);
printf("\n");
}
// 查找节点
Node* search(Node *root, int key) {
while (root != NIL) {
if (key == root->data) {
return root;
} else if (key < root->data) {
root = root->left;
} else {
root = root->right;
}
}
return NULL;
}
// 释放内存
void freeTree(Node *root) {
if (root != NIL) {
freeTree(root->left);
freeTree(root->right);
free(root);
}
}
int main() {
NIL = (Node *)malloc(sizeof(Node));
NIL->color = BLACK;
NIL->left = NIL->right = NIL->parent = NULL;
Node *root = NIL;
insert(&root, 10);
insert(&root, 20);
insert(&root, 30);
insert(&root, 15);
printf("中序遍历: ");
inorder(root);
Node *foundNode = search(root, 20);
if (foundNode) {
printf("找到节点: %d\n", foundNode->data);
} else {
printf("未找到节点\n");
}
freeTree(root);
free(NIL);
return 0;
}
说明
节点结构:每个节点包含数据、颜色、左右子节点和父节点的指针。
旋转操作:左旋和右旋用于保持红黑树的性质。
插入操作:插入新节点后,调用
fixViolation
修复可能违反的红黑树性质。遍历:提供中序遍历函数以验证树的结构。
查找操作:提供查找函数以查找特定值的节点。
内存管理:在
main
函数中动态分配内存,并在结束时释放。
Last updated