规范代码,补充readme文件

This commit is contained in:
kkk 2023-07-26 21:22:03 +08:00
parent c3bd9f2e77
commit c4e6578b00
7 changed files with 293 additions and 69 deletions

View File

@ -0,0 +1,95 @@
# 热身赛一级赛题2基于cortex-m4-emulator实现红黑树并测试验证
## 1. 简介
基于矽璓模拟器cortex-m4-emulator实现了红黑树基本数据结构和功能主要包括查找、删除、插入、左旋、右旋等功能并编写测试程序在shell终端打印结果
## 2. 数据结构设计说明
红黑树数据结构如下:
``` c
enum Type {RED,BLACK};
struct Node
{
int data;
struct Node* left;
struct Node* right;
struct Node* parent;
enum Type color;
};
```
红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black)。
红黑树的基本操作是添加、删除和旋转。在对红黑树进行添加或删除后,会用到旋转方法。旋转的目的是让树保持红黑树的特性。
## 3. 测试程序说明
测试程序示例如下:
```c
void TestRbtree(void)
{
struct Node* RBT = NULL; //创建红黑树根节点
RBT = RbInsert(RBT,2); //插入节点
RBT = RbInsert(RBT,1);
RBT = RbInsert(RBT,4);
RBT = RbInsert(RBT,5);
RBT = RbInsert(RBT,9);
RBT = RbInsert(RBT,3);
RBT = RbInsert(RBT,6);
RBT = RbInsert(RBT,7);
printf("\nPreOrder - ");
PreOrder(RBT); //先序遍历
printf("\nLevel order - ");
LevelOrder(RBT); //层序遍历
struct Node* x = BstSearch(RBT,5); //查找
RBT = RbDelete(RBT,x); //删除
printf("\nAfter deleting 5");
printf("\nPreOrder - ");
PreOrder(RBT);
front = NULL; rear = NULL; // Delete old Queue
printf("\nLevel order - ");
LevelOrder(RBT);
}
PRIV_SHELL_CMD_FUNCTION(TestRbtree, a red black sample , PRIV_SHELL_CMD_MAIN_ATTR); //注册TestRbtree指令
```
测试程序通过shell指令`TestRbtree`运行,之后输出红黑树插入系列节点后的先序遍历和层序遍历结果,之后删除查找到的节点,并观察结果是否正确。测试覆盖红黑树的插入、删除、查找、先序遍历、层序遍历等功能。
## 4. 运行结果
运行系统`qemu-system-arm -machine netduinoplus2 -nographic -kernel build/XiZi-cortex-m4-emulator.elf`,之后通过`TestRbtree`指令运行测试程序,执行结果如下:
![执行结果](./img/result.png)
结果分析如下所示:
### 1. 插入节点、层序遍历、先序遍历功能测试
1. 通过调用`RbInsert(RBT,val)`方法插入数据,初始数据为(2,1,4,5,9,3,6,7),其对应红黑树为:
![初始生成的红黑树](img/rbtree.png)
2. 首先调用`PreOrder`函数查看先序遍历结果为:
PreOrder - 2 1 5 4 3 7 6 9
与预期一致
3. 再调用`LevelOrder`方法,查看层级遍历结果为:
Level order - 2 1 5 4 7 3 6 9
与预期结果一致
由层序遍历和先序遍历结果,可以看出生成的红黑树和预期一致,插入操作正确。
### 2. 删除节点,查找节点功能测试
1. 首先通过`struct Node* x = BstSearch(RBT,5);`找到5对应的节点
2. 之后使用`RBT = RbDelete(RBT,x);`删除该节点,此时红黑树删除变化为:
![删除元素5](img/delete5.png)
3. 同测试1步骤2和3我们通过`PreOrder`和`LevelOrder`查看此时的树为:
PreOrder - 2 1 6 4 3 7 9
Level order - 2 1 6 4 7 3 9
4. 运行结果与预期一致,红黑树的删除操作正确。

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,3 +1,22 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file rbtree.c
* @author
* @brief
* @version 0.1
* @date 2023-07-26
*/
#include "rbtree.h" #include "rbtree.h"
#include <malloc.h> #include <malloc.h>
#include <stdio.h> #include <stdio.h>
@ -5,14 +24,14 @@
struct Queue* front = NULL; struct Queue* front = NULL;
struct Queue* rear = NULL; struct Queue* rear = NULL;
struct Node* pfront() struct Node* PFront()
{ {
struct Node* data ; struct Node* data ;
data = front->data; data = front->data;
return data; return data;
} }
int isempty() int IsEmpty()
{ {
if(front==NULL) if(front==NULL)
return 1; return 1;
@ -21,9 +40,9 @@ int isempty()
return 0; return 0;
} }
void dequeue() void DeQueue()
{ {
if(isempty()) if(IsEmpty())
return ; return ;
struct Queue* temp = front; struct Queue* temp = front;
@ -32,7 +51,7 @@ void dequeue()
} }
void enqueue(struct Node* data) void EnQueue(struct Node* data)
{ {
struct Queue* temp =(struct Queue*)malloc(sizeof(struct Queue)); struct Queue* temp =(struct Queue*)malloc(sizeof(struct Queue));
temp->data = data; temp->data = data;
@ -48,28 +67,39 @@ void enqueue(struct Node* data)
rear = temp; rear = temp;
} }
void levelorder(struct Node* root) /**
* @brief
*
* @param root
*/
void LevelOrder(struct Node* root)
{ {
if(root==NULL) if(root==NULL)
return; return;
enqueue(root); EnQueue(root);
while(!isempty()) while(!IsEmpty())
{ {
struct Node* current = pfront(); struct Node* current = PFront();
printf("%d ",current->data); printf("%d ",current->data);
if(current->left!=NULL) if(current->left!=NULL)
enqueue(current->left); EnQueue(current->left);
if(current->right!=NULL) if(current->right!=NULL)
enqueue(current->right); EnQueue(current->right);
dequeue(); DeQueue();
} }
} }
/**
* @brief x节点左旋
*
* @param T
* @param x
*/
void LeftRotate(struct Node** T,struct Node** x) void LeftRotate(struct Node** T,struct Node** x)
{ {
struct Node* y = (*x)->right; struct Node* y = (*x)->right;
@ -94,6 +124,13 @@ void LeftRotate(struct Node** T,struct Node** x)
(*x)->parent = y; (*x)->parent = y;
} }
/**
* @brief x节点右旋
*
* @param T
* @param x
*/
void RightRotate(struct Node** T,struct Node** x) void RightRotate(struct Node** T,struct Node** x)
{ {
struct Node* y = (*x)->left; struct Node* y = (*x)->left;
@ -118,7 +155,13 @@ void RightRotate(struct Node** T,struct Node** x)
} }
void RB_insert_fixup(struct Node** T, struct Node** z) /**
* @brief z后调整红黑树
*
* @param T
* @param z
*/
void RbInsertFixup(struct Node** T, struct Node** z)
{ {
struct Node* grandparent = NULL; struct Node* grandparent = NULL;
struct Node* parentpt = NULL; struct Node* parentpt = NULL;
@ -188,7 +231,14 @@ void RB_insert_fixup(struct Node** T, struct Node** z)
} }
struct Node* RB_insert(struct Node* T,int data) /**
* @brief data
*
* @param T
* @param data
* @return struct Node*
*/
struct Node* RbInsert(struct Node* T,int data)
{ {
struct Node* z = (struct Node*)malloc(sizeof(struct Node)); struct Node* z = (struct Node*)malloc(sizeof(struct Node));
z->data = data; z->data = data;
@ -220,22 +270,33 @@ struct Node* RB_insert(struct Node* T,int data)
else else
y->right = z; y->right = z;
RB_insert_fixup(&T,&z); RbInsertFixup(&T,&z);
return T; return T;
} }
void preorder(struct Node* root) /**
* @brief
*
* @param root
*/
void PreOrder(struct Node* root)
{ {
if(root==NULL) if(root==NULL)
return; return;
printf("%d ",root->data); printf("%d ",root->data);
preorder(root->left); PreOrder(root->left);
preorder(root->right); PreOrder(root->right);
} }
struct Node* Tree_minimum(struct Node* node) /**
* @brief node的开始的最小值
*
* @param node
* @return struct Node*
*/
struct Node* TreeMinimum(struct Node* node)
{ {
while(node->left!=NULL) while(node->left!=NULL)
node = node->left; node = node->left;
@ -243,7 +304,13 @@ struct Node* Tree_minimum(struct Node* node)
return node; return node;
} }
void RB_delete_fixup(struct Node** T, struct Node** x) /**
* @brief x后修正红黑树
*
* @param T
* @param x
*/
void RbDeleteFixup(struct Node** T, struct Node** x)
{ {
while((*x)!=*T && (*x)->color == BLACK) while((*x)!=*T && (*x)->color == BLACK)
{ {
@ -323,7 +390,14 @@ void RB_delete_fixup(struct Node** T, struct Node** x)
} }
void RB_transplat(struct Node** T, struct Node** u,struct Node** v) /**
* @brief uv代替u的位置
*
* @param T
* @param u
* @param v
*/
void RbTransplat(struct Node** T, struct Node** u,struct Node** v)
{ {
if((*u)->parent == NULL) if((*u)->parent == NULL)
*T = *v; *T = *v;
@ -337,10 +411,17 @@ void RB_transplat(struct Node** T, struct Node** u,struct Node** v)
(*v)->parent = (*u)->parent; (*v)->parent = (*u)->parent;
} }
struct Node* RB_delete(struct Node *T,struct Node* z) /**
* @brief z
*
* @param T
* @param z
* @return struct Node*
*/
struct Node* RbDelete(struct Node *T,struct Node* z)
{ {
struct Node *y = z; struct Node *y = z;
enum type yoc; enum Type yoc;
yoc = z->color; // y's original color yoc = z->color; // y's original color
struct Node* x; struct Node* x;
@ -348,18 +429,18 @@ struct Node* RB_delete(struct Node *T,struct Node* z)
if(z->left==NULL ) if(z->left==NULL )
{ {
x = z->right; x = z->right;
RB_transplat(&T,&z,&(z->right)); RbTransplat(&T,&z,&(z->right));
} }
else if(z->right==NULL ) else if(z->right==NULL )
{ {
x = z->left; x = z->left;
RB_transplat(&T,&z,&(z->left)); RbTransplat(&T,&z,&(z->left));
} }
else else
{ {
y = Tree_minimum(z->right); y = TreeMinimum(z->right);
yoc = y->color; yoc = y->color;
x = y->right; x = y->right;
@ -368,30 +449,37 @@ struct Node* RB_delete(struct Node *T,struct Node* z)
else else
{ {
RB_transplat(&T,&y,&(y->right)); RbTransplat(&T,&y,&(y->right));
y->right = z->right; y->right = z->right;
y->right->parent = y; y->right->parent = y;
} }
RB_transplat(&T,&z,&y); RbTransplat(&T,&z,&y);
y->left = z->left; y->left = z->left;
y->left->parent = y; y->left->parent = y;
y->color = z->color; y->color = z->color;
} }
if(yoc==BLACK) if(yoc==BLACK)
RB_delete_fixup(&T,&x); RbDeleteFixup(&T,&x);
return T; return T;
} }
struct Node* BST_search(struct Node* root, int x) /**
* @brief x对应的节点
*
* @param root
* @param x
* @return struct Node*
*/
struct Node* BstSearch(struct Node* root, int x)
{ {
if(root==NULL || root->data == x) if(root==NULL || root->data == x)
return root; return root;
if(root->data > x) if(root->data > x)
return BST_search(root->left,x); return BstSearch(root->left,x);
else else
return BST_search(root->right,x); return BstSearch(root->right,x);
} }

View File

@ -1,5 +1,26 @@
#ifndef __LIST_H__ /*
#define __LIST_H__ * Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file rbtree.h
* @author
* @brief
* @version 0.1
* @date 2023-07-26
*/
#ifndef __RBTREE_H__
#define __RBTREE_H__
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
@ -10,7 +31,7 @@ extern "C" {
#endif #endif
enum type {RED,BLACK}; enum Type {RED,BLACK};
struct Node struct Node
{ {
@ -18,7 +39,7 @@ struct Node
struct Node* left; struct Node* left;
struct Node* right; struct Node* right;
struct Node* parent; struct Node* parent;
enum type color; enum Type color;
}; };
struct Queue struct Queue
@ -29,34 +50,35 @@ struct Queue
struct Node *pfront(); struct Node *PFront();
int isempty();
void dequeue(); int IsEmpty();
void enqueue(struct Node *data); void DeQueue();
void levelorder(struct Node *root); void EnQueue(struct Node *data);
void LevelOrder(struct Node *root);
void LeftRotate(struct Node **T, struct Node **x); void LeftRotate(struct Node **T, struct Node **x);
void RightRotate(struct Node **T, struct Node **x); void RightRotate(struct Node **T, struct Node **x);
void RB_insert_fixup(struct Node **T, struct Node **z); void RbInsertFixup(struct Node **T, struct Node **z);
struct Node *RB_insert(struct Node *T, int data); struct Node *RbInsert(struct Node *T, int data);
void preorder(struct Node *root); void PreOrder(struct Node *root);
struct Node *Tree_minimum(struct Node *node); struct Node *TreeMinimum(struct Node *node);
void RB_delete_fixup(struct Node **T, struct Node **x); void RbDeleteFixup(struct Node **T, struct Node **x);
void RB_transplat(struct Node **T, struct Node **u, struct Node **v); void RbTransplat(struct Node **T, struct Node **u, struct Node **v);
struct Node *RB_delete(struct Node *T, struct Node *z); struct Node *RbDelete(struct Node *T, struct Node *z);
struct Node *BST_search(struct Node *root, int x); struct Node *BstSearch(struct Node *root, int x);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,22 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file test_rbtree.c
* @author
* @brief
* @version 0.1
* @date 2023-07-26
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <transform.h> #include <transform.h>
@ -8,40 +27,40 @@
extern struct Queue* front; extern struct Queue* front;
extern struct Queue* rear; extern struct Queue* rear;
void Test_Rbtree(void) void TestRbtree(void)
{ {
struct Node* RBT = NULL; struct Node* RBT = NULL;
RBT = RB_insert(RBT,2); RBT = RbInsert(RBT,2);
RBT = RB_insert(RBT,1); RBT = RbInsert(RBT,1);
RBT = RB_insert(RBT,4); RBT = RbInsert(RBT,4);
RBT = RB_insert(RBT,5); RBT = RbInsert(RBT,5);
RBT = RB_insert(RBT,9); RBT = RbInsert(RBT,9);
RBT = RB_insert(RBT,3); RBT = RbInsert(RBT,3);
RBT = RB_insert(RBT,6); RBT = RbInsert(RBT,6);
RBT = RB_insert(RBT,7); RBT = RbInsert(RBT,7);
printf("\nPreorder - "); printf("\nPreOrder - ");
preorder(RBT); PreOrder(RBT);
printf("\nLevel order - "); printf("\nLevel order - ");
levelorder(RBT); LevelOrder(RBT);
struct Node* x = BST_search(RBT,5); struct Node* x = BstSearch(RBT,5);
RBT = RbDelete(RBT,x);
RBT = RB_delete(RBT,x);
printf("\nAfter deleting 5"); printf("\nAfter deleting 5");
printf("\nPreorder - "); printf("\nPreOrder - ");
preorder(RBT); PreOrder(RBT);
front = NULL; rear = NULL; // Delete old Queue front = NULL; rear = NULL; // Delete old Queue
printf("\nLevel order - "); printf("\nLevel order - ");
levelorder(RBT); LevelOrder(RBT);
return ; // return ;
} }
PRIV_SHELL_CMD_FUNCTION(Test_Rbtree, a red black sample , PRIV_SHELL_CMD_MAIN_ATTR); PRIV_SHELL_CMD_FUNCTION(TestRbtree, a red black sample , PRIV_SHELL_CMD_MAIN_ATTR);