diff --git a/APP_Framework/Applications/app_test/test_rbtree/README.md b/APP_Framework/Applications/app_test/test_rbtree/README.md new file mode 100644 index 000000000..5745de969 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/README.md @@ -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的值; +![结点](./insert.jpg) + +### step 2 (打印红黑树-中序): +1. shell中输入指令p,中序打印红黑树结点; +![结点](./print1.jpg) + +### step 3 (删除结点) +1. shell中输入指令d5,key=5的结点被删除; +![结点](./delete.jpg) + +### step 4 (搜索结点) +1. shell中输入指令s8,结果“Key 8 found”显示查询到key=8的结点; +![结点](./search.jpg) + +### step 5 (结果验证) +1. shell中输入指令p按中序打印红黑树结点,验证前几步,结果如图所示: +![结点](./verification.jpg) + diff --git a/APP_Framework/Applications/app_test/test_rbtree/delete.jpg b/APP_Framework/Applications/app_test/test_rbtree/delete.jpg new file mode 100644 index 000000000..7c809019a Binary files /dev/null and b/APP_Framework/Applications/app_test/test_rbtree/delete.jpg differ diff --git a/APP_Framework/Applications/app_test/test_rbtree/insert.jpg b/APP_Framework/Applications/app_test/test_rbtree/insert.jpg new file mode 100644 index 000000000..1802b421f Binary files /dev/null and b/APP_Framework/Applications/app_test/test_rbtree/insert.jpg differ diff --git a/APP_Framework/Applications/app_test/test_rbtree/print1.jpg b/APP_Framework/Applications/app_test/test_rbtree/print1.jpg new file mode 100644 index 000000000..4f7ae9a94 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_rbtree/print1.jpg differ diff --git a/APP_Framework/Applications/app_test/test_rbtree/search.jpg b/APP_Framework/Applications/app_test/test_rbtree/search.jpg new file mode 100644 index 000000000..ecc243e69 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_rbtree/search.jpg differ diff --git a/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c new file mode 100644 index 000000000..081cdb647 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include "test_rbtree.h" +#include + + + +// 创建红黑树节点 +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); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.h b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.h new file mode 100644 index 000000000..a0c970710 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.h @@ -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 */ diff --git a/APP_Framework/Applications/app_test/test_rbtree/verification.jpg b/APP_Framework/Applications/app_test/test_rbtree/verification.jpg new file mode 100644 index 000000000..a76347a19 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_rbtree/verification.jpg differ