规范代码,补充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 <malloc.h>
#include <stdio.h>
@ -5,14 +24,14 @@
struct Queue* front = NULL;
struct Queue* rear = NULL;
struct Node* pfront()
struct Node* PFront()
{
struct Node* data ;
data = front->data;
return data;
}
int isempty()
int IsEmpty()
{
if(front==NULL)
return 1;
@ -21,9 +40,9 @@ int isempty()
return 0;
}
void dequeue()
void DeQueue()
{
if(isempty())
if(IsEmpty())
return ;
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));
temp->data = data;
@ -48,28 +67,39 @@ void enqueue(struct Node* data)
rear = temp;
}
void levelorder(struct Node* root)
/**
* @brief
*
* @param root
*/
void LevelOrder(struct Node* root)
{
if(root==NULL)
return;
enqueue(root);
EnQueue(root);
while(!isempty())
while(!IsEmpty())
{
struct Node* current = pfront();
struct Node* current = PFront();
printf("%d ",current->data);
if(current->left!=NULL)
enqueue(current->left);
EnQueue(current->left);
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)
{
struct Node* y = (*x)->right;
@ -94,6 +124,13 @@ void LeftRotate(struct Node** T,struct Node** x)
(*x)->parent = y;
}
/**
* @brief x节点右旋
*
* @param T
* @param x
*/
void RightRotate(struct Node** T,struct Node** x)
{
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* 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));
z->data = data;
@ -220,22 +270,33 @@ struct Node* RB_insert(struct Node* T,int data)
else
y->right = z;
RB_insert_fixup(&T,&z);
RbInsertFixup(&T,&z);
return T;
}
void preorder(struct Node* root)
/**
* @brief
*
* @param root
*/
void PreOrder(struct Node* root)
{
if(root==NULL)
return;
printf("%d ",root->data);
preorder(root->left);
preorder(root->right);
PreOrder(root->left);
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)
node = node->left;
@ -243,7 +304,13 @@ struct Node* Tree_minimum(struct Node* 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)
{
@ -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)
*T = *v;
@ -337,10 +411,17 @@ void RB_transplat(struct Node** T, struct Node** u,struct Node** v)
(*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;
enum type yoc;
enum Type yoc;
yoc = z->color; // y's original color
struct Node* x;
@ -348,18 +429,18 @@ struct Node* RB_delete(struct Node *T,struct Node* z)
if(z->left==NULL )
{
x = z->right;
RB_transplat(&T,&z,&(z->right));
RbTransplat(&T,&z,&(z->right));
}
else if(z->right==NULL )
{
x = z->left;
RB_transplat(&T,&z,&(z->left));
RbTransplat(&T,&z,&(z->left));
}
else
{
y = Tree_minimum(z->right);
y = TreeMinimum(z->right);
yoc = y->color;
x = y->right;
@ -368,30 +449,37 @@ struct Node* RB_delete(struct Node *T,struct Node* z)
else
{
RB_transplat(&T,&y,&(y->right));
RbTransplat(&T,&y,&(y->right));
y->right = z->right;
y->right->parent = y;
}
RB_transplat(&T,&z,&y);
RbTransplat(&T,&z,&y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if(yoc==BLACK)
RB_delete_fixup(&T,&x);
RbDeleteFixup(&T,&x);
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)
return root;
if(root->data > x)
return BST_search(root->left,x);
return BstSearch(root->left,x);
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 <stdarg.h>
@ -10,7 +31,7 @@ extern "C" {
#endif
enum type {RED,BLACK};
enum Type {RED,BLACK};
struct Node
{
@ -18,7 +39,7 @@ struct Node
struct Node* left;
struct Node* right;
struct Node* parent;
enum type color;
enum Type color;
};
struct Queue
@ -29,34 +50,35 @@ struct Queue
struct Node *pfront();
int isempty();
struct Node *PFront();
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 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
}

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 <stdlib.h>
#include <transform.h>
@ -8,40 +27,40 @@
extern struct Queue* front;
extern struct Queue* rear;
void Test_Rbtree(void)
void TestRbtree(void)
{
struct Node* RBT = NULL;
RBT = RB_insert(RBT,2);
RBT = RB_insert(RBT,1);
RBT = RB_insert(RBT,4);
RBT = RB_insert(RBT,5);
RBT = RB_insert(RBT,9);
RBT = RB_insert(RBT,3);
RBT = RB_insert(RBT,6);
RBT = RB_insert(RBT,7);
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("\nPreOrder - ");
PreOrder(RBT);
printf("\nLevel order - ");
levelorder(RBT);
LevelOrder(RBT);
struct Node* x = BST_search(RBT,5);
RBT = RB_delete(RBT,x);
struct Node* x = BstSearch(RBT,5);
RBT = RbDelete(RBT,x);
printf("\nAfter deleting 5");
printf("\nPreorder - ");
preorder(RBT);
printf("\nPreOrder - ");
PreOrder(RBT);
front = NULL; rear = NULL; // Delete old Queue
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);