2023_open_source_contest
This commit is contained in:
parent
85896113cb
commit
345ec3ee0c
|
@ -0,0 +1,50 @@
|
|||
# 热身赛一级赛题2:基于cortex-m4-emulator实现红黑树并测试验证##
|
||||
|
||||
## 1. 简介
|
||||
实现了红黑树数据结构,并提供了基本的插入、删除和搜索功能。红黑树是一种自平衡的二叉查找树,通过在每个节点上添加额外的颜色属性来维护平衡性。
|
||||
|
||||
|
||||
## 2. 数据结构设计说明
|
||||
本项目包含以下数据结构:
|
||||
|
||||
struct rb_node:红黑树的节点结构,包含键值、颜色(红、黑)以及左右子节点的指针。
|
||||
struct rb_tree:红黑树结构,包含根节点指针和一个特殊的空节点(nil),用于表示叶子节点。
|
||||
|
||||
|
||||
## 3. 测试程序说明
|
||||
test_rbtree.c 文件包含了测试程序的实现。测试程序演示了红黑树的基本功能,包括插入、删除和搜索操作。
|
||||
|
||||
通过shell输入数据,并使用相应的命令执行不同的操作。具体命令如下:
|
||||
|
||||
+ **i key**:插入一个具有指定键值 key 的节点到红黑树中。
|
||||
+ **d key**:删除红黑树中具有指定键值 key 的节点。
|
||||
+ **s key**:搜索红黑树中具有指定键值 key 的节点。
|
||||
+ **p**:打印红黑树
|
||||
|
||||
**注**:指令与key之间没有空格;
|
||||
例如,要向红黑树中插入键值为 5 的节点,可以执行以下命令:
|
||||
shell->i5
|
||||
|
||||
|
||||
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||
### step 1 (插入):
|
||||
1. shell输入Test_rbtree启动红黑树程序;
|
||||
2. 输入插入指令,构建红黑树,如i5,向红黑树插入key=5的值;
|
||||

|
||||
|
||||
### step 2 (打印红黑树-中序):
|
||||
1. shell中输入指令p,中序打印红黑树结点;
|
||||

|
||||
|
||||
### step 3 (删除结点)
|
||||
1. shell中输入指令d5,key=5的结点被删除;
|
||||

|
||||
|
||||
### step 4 (搜索结点)
|
||||
1. shell中输入指令s8,结果“Key 8 found”显示查询到key=8的结点;
|
||||

|
||||
|
||||
### step 5 (结果验证)
|
||||
1. shell中输入指令p按中序打印红黑树结点,验证前几步,结果如图所示:
|
||||

|
||||
|
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
|
@ -0,0 +1,312 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "test_rbtree.h"
|
||||
#include <transform.h>
|
||||
|
||||
|
||||
|
||||
// 创建红黑树节点
|
||||
struct rb_node* rb_node_create(int key, int color, struct rb_node *parent, struct rb_node *nil) {
|
||||
struct rb_node *node = (struct rb_node *)malloc(sizeof(struct rb_node));
|
||||
node->key = key;
|
||||
node->color = color;
|
||||
node->left = nil;
|
||||
node->right = nil;
|
||||
node->parent = parent;
|
||||
return node;
|
||||
}
|
||||
|
||||
// 初始化红黑树
|
||||
void rb_tree_init(struct rb_tree *tree) {
|
||||
struct rb_node *nil = rb_node_create(0, BLACK, NULL, NULL);
|
||||
tree->root = nil;
|
||||
tree->nil = nil;
|
||||
}
|
||||
|
||||
// 左旋操作
|
||||
void rb_tree_left_rotate(struct rb_tree *tree, struct rb_node *x) {
|
||||
struct rb_node *y = x->right;
|
||||
x->right = y->left;
|
||||
if (y->left != tree->nil) {
|
||||
y->left->parent = x;
|
||||
}
|
||||
y->parent = x->parent;
|
||||
if (x->parent == tree->nil) {
|
||||
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 rb_tree_right_rotate(struct rb_tree *tree, struct rb_node *y) {
|
||||
struct rb_node *x = y->left;
|
||||
y->left = x->right;
|
||||
if (x->right != tree->nil) {
|
||||
x->right->parent = y;
|
||||
}
|
||||
x->parent = y->parent;
|
||||
if (y->parent == tree->nil) {
|
||||
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 rb_tree_insert_fixup(struct rb_tree *tree, struct rb_node *z) {
|
||||
while (z->parent->color == RED) {
|
||||
if (z->parent == z->parent->parent->left) {
|
||||
struct rb_node *y = z->parent->parent->right;
|
||||
if (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;
|
||||
rb_tree_left_rotate(tree, z);
|
||||
}
|
||||
z->parent->color = BLACK;
|
||||
z->parent->parent->color = RED;
|
||||
rb_tree_right_rotate(tree, z->parent->parent);
|
||||
}
|
||||
} else {
|
||||
struct rb_node *y = z->parent->parent->left;
|
||||
if (y->color == RED) {
|
||||
z->parent->color = BLACK;
|
||||
y->color = BLACK;
|
||||
z->parent->parent->color = RED;
|
||||
z = z->parent->parent;
|
||||
} else {
|
||||
if (z == z->parent->left) {
|
||||
z = z->parent;
|
||||
rb_tree_right_rotate(tree, z);
|
||||
}
|
||||
z->parent->color = BLACK;
|
||||
z->parent->parent->color = RED;
|
||||
rb_tree_left_rotate(tree, z->parent->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
tree->root->color = BLACK;
|
||||
}
|
||||
|
||||
// 插入节点
|
||||
void rb_tree_insert(struct rb_tree *tree, int key) {
|
||||
struct rb_node *z = rb_node_create(key, RED, NULL, tree->nil);
|
||||
struct rb_node *y = tree->nil;
|
||||
struct rb_node *x = tree->root;
|
||||
while (x != tree->nil) {
|
||||
y = x;
|
||||
if (z->key < x->key) {
|
||||
x = x->left;
|
||||
} else {
|
||||
x = x->right;
|
||||
}
|
||||
}
|
||||
z->parent = y;
|
||||
if (y == tree->nil) {
|
||||
tree->root = z;
|
||||
} else if (z->key < y->key) {
|
||||
y->left = z;
|
||||
} else {
|
||||
y->right = z;
|
||||
}
|
||||
rb_tree_insert_fixup(tree, z);
|
||||
}
|
||||
|
||||
// 查找节点
|
||||
struct rb_node* rb_tree_search(struct rb_tree *tree, int key) {
|
||||
struct rb_node *x = tree->root;
|
||||
while (x != tree->nil) {
|
||||
if (key == x->key) {
|
||||
return x;
|
||||
} else if (key < x->key) {
|
||||
x = x->left;
|
||||
} else {
|
||||
x = x->right;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 删除修正
|
||||
void rb_tree_delete_fixup(struct rb_tree *tree, struct rb_node *x) {
|
||||
while (x != tree->root && x->color == BLACK) {
|
||||
if (x == x->parent->left) {
|
||||
struct rb_node *w = x->parent->right;
|
||||
if (w->color == RED) {
|
||||
w->color = BLACK;
|
||||
x->parent->color = RED;
|
||||
rb_tree_left_rotate(tree, x->parent);
|
||||
w = x->parent->right;
|
||||
}
|
||||
if (w->left->color == BLACK && w->right->color == BLACK) {
|
||||
w->color = RED;
|
||||
x = x->parent;
|
||||
} else {
|
||||
if (w->right->color == BLACK) {
|
||||
w->left->color = BLACK;
|
||||
w->color = RED;
|
||||
rb_tree_right_rotate(tree, w);
|
||||
w = x->parent->right;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = BLACK;
|
||||
w->right->color = BLACK;
|
||||
rb_tree_left_rotate(tree, x->parent);
|
||||
x = tree->root;
|
||||
}
|
||||
} else {
|
||||
struct rb_node *w = x->parent->left;
|
||||
if (w->color == RED) {
|
||||
w->color = BLACK;
|
||||
x->parent->color = RED;
|
||||
rb_tree_right_rotate(tree, x->parent);
|
||||
w = x->parent->left;
|
||||
}
|
||||
if (w->right->color == BLACK && w->left->color == BLACK) {
|
||||
w->color = RED;
|
||||
x = x->parent;
|
||||
} else {
|
||||
if (w->left->color == BLACK) {
|
||||
w->right->color = BLACK;
|
||||
w->color = RED;
|
||||
rb_tree_left_rotate(tree, w);
|
||||
w = x->parent->left;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = BLACK;
|
||||
w->left->color = BLACK;
|
||||
rb_tree_right_rotate(tree, x->parent);
|
||||
x = tree->root;
|
||||
}
|
||||
}
|
||||
}
|
||||
x->color = BLACK;
|
||||
}
|
||||
|
||||
// 删除节点
|
||||
void rb_tree_delete(struct rb_tree *tree, int key) {
|
||||
struct rb_node *z = rb_tree_search(tree, key);
|
||||
if (z == NULL) {
|
||||
return;
|
||||
}
|
||||
struct rb_node *x, *y;
|
||||
if (z->left == tree->nil || z->right == tree->nil) {
|
||||
y = z;
|
||||
} else {
|
||||
y = z->right;
|
||||
while (y->left != tree->nil) {
|
||||
y = y->left;
|
||||
}
|
||||
}
|
||||
if (y->left != tree->nil) {
|
||||
x = y->left;
|
||||
} else {
|
||||
x = y->right;
|
||||
}
|
||||
x->parent = y->parent;
|
||||
if (y->parent == tree->nil) {
|
||||
tree->root = x;
|
||||
} else if (y == y->parent->left) {
|
||||
y->parent->left = x;
|
||||
} else {
|
||||
y->parent->right = x;
|
||||
}
|
||||
if (y != z) {
|
||||
z->key = y->key;
|
||||
}
|
||||
if (y->color == BLACK) {
|
||||
rb_tree_delete_fixup(tree, x);
|
||||
}
|
||||
free(y);
|
||||
}
|
||||
|
||||
// 打印红黑树
|
||||
void rb_tree_print_node(struct rb_node *node, struct rb_node *nil) {
|
||||
if (node == nil) {
|
||||
return;
|
||||
}
|
||||
rb_tree_print_node(node->left, nil);
|
||||
printf("%d ", node->key);
|
||||
rb_tree_print_node(node->right, nil);
|
||||
}
|
||||
|
||||
void rb_tree_print(struct rb_tree *tree) {
|
||||
rb_tree_print_node(tree->root, tree->nil);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
// 红黑树测试
|
||||
int Test_rbtree(void) {
|
||||
struct rb_tree tree;
|
||||
char input[100];
|
||||
|
||||
// 测试
|
||||
// printf("Enter a command (i for insert, d for delete, s for search): ");
|
||||
// scanf("%99s", input);
|
||||
// while(strcmp(input, "exit") != 0){
|
||||
// printf("\n");
|
||||
// printf("x = %s\n", input);
|
||||
// printf("Enter a command (i for insert, d for delete, s for search): ");
|
||||
// scanf("%99s", input);
|
||||
// }
|
||||
|
||||
|
||||
rb_tree_init(&tree);
|
||||
|
||||
while (1) {
|
||||
printf("Enter a command (i for insert, d for delete, s for search, p for print): ");
|
||||
|
||||
|
||||
PrivTaskDelay(500); //防止时间片长时间占用,使得输入函数没有等待时间
|
||||
//fgets(input, sizeof(input), stdin);
|
||||
scanf("%s", input); // 读取最多99个字符直到换行符为止(不包括换行符)
|
||||
|
||||
printf("input = %s\n", input);
|
||||
|
||||
if (strncmp(input, "i", 1) == 0) {
|
||||
int key;
|
||||
sscanf(input + 1, "%d", &key);
|
||||
rb_tree_insert(&tree, key);
|
||||
printf("Inserted key %d\n", key);
|
||||
} else if (strncmp(input, "d", 1) == 0) {
|
||||
int key;
|
||||
sscanf(input + 1, "%d", &key);
|
||||
rb_tree_delete(&tree, key);
|
||||
printf("Deleted key %d\n", key);
|
||||
} else if (strncmp(input, "s", 1) == 0) {
|
||||
int key;
|
||||
sscanf(input + 1, "%d", &key);
|
||||
struct rb_node* node = rb_tree_search(&tree, key);
|
||||
if (node != NULL) {
|
||||
printf("Key %d found\n", key);
|
||||
} else {
|
||||
printf("Key %d not found\n", key);
|
||||
}
|
||||
} else if (strncmp(input, "p", 1) == 0){
|
||||
rb_tree_print(&tree);
|
||||
} else {
|
||||
printf("Invalid command\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(Test_rbtree, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef TEST_RBTREE_H
|
||||
#define TEST_RBTREE_H
|
||||
|
||||
// 红黑树节点的颜色
|
||||
#define RED 0
|
||||
#define BLACK 1
|
||||
|
||||
// 红黑树节点结构
|
||||
struct rb_node {
|
||||
int key;
|
||||
struct rb_node *left;
|
||||
struct rb_node *right;
|
||||
struct rb_node *parent;
|
||||
int color;
|
||||
};
|
||||
|
||||
// 红黑树结构
|
||||
struct rb_tree {
|
||||
struct rb_node *root;
|
||||
struct rb_node *nil;
|
||||
};
|
||||
|
||||
// 初始化红黑树
|
||||
void rb_tree_init(struct rb_tree *tree);
|
||||
|
||||
// 红黑树中插入新节点
|
||||
void rb_tree_insert(struct rb_tree *tree, int key);
|
||||
|
||||
// 红黑树中删除节点
|
||||
void rb_tree_delete(struct rb_tree *tree, int key);
|
||||
|
||||
// 红黑树中搜索节点
|
||||
struct rb_node* rb_tree_search(struct rb_tree *tree, int key);
|
||||
|
||||
// 打印红黑树节点
|
||||
void rb_tree_print(struct rb_tree *tree);
|
||||
|
||||
// 红黑树功能测试
|
||||
int test_rbtree(void);
|
||||
|
||||
#endif /* TEST_RBTREE_H */
|
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
Loading…
Reference in New Issue