规范代码,补充readme文件
This commit is contained in:
parent
c3bd9f2e77
commit
c4e6578b00
|
@ -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`指令运行测试程序,执行结果如下:
|
||||
|
||||

|
||||
|
||||
结果分析如下所示:
|
||||
### 1. 插入节点、层序遍历、先序遍历功能测试
|
||||
1. 通过调用`RbInsert(RBT,val)`方法插入数据,初始数据为(2,1,4,5,9,3,6,7),其对应红黑树为:
|
||||

|
||||
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);`删除该节点,此时红黑树删除变化为:
|
||||

|
||||
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 |
|
@ -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 删除节点u,并用v代替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);
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue