白痴也有春天 提交 热身赛test_rbtree

This commit is contained in:
Idiot-Cabbage 2023-09-18 19:43:12 +08:00
parent a1df906d16
commit 054e1ecdf9
10 changed files with 494 additions and 451 deletions

View File

@ -1,69 +1,79 @@
# 基于cortex-m4-emulator实现红黑树并测试验证
## 1. 简介
红黑树是一种自平衡的二叉查找树,具有良好的插入、删除和查找性能本次提交结果为红黑树数据结构的简单实现。test_rbtree.h中定义了红黑树的数据结构和声明插入、删除、查找相关操作函数;test_rbtree.c中为操作函数的定义并提供了测试函数TestRBTree用于验证红黑树的正确性。
红黑树是一棵二叉查找树它在每个结点上增加了一个存储位表示结点的颜色可以是红色RED或黑色BLACK。通过对任何一条从根到叶子的路径上各个结点着色方式的限制红黑树确保没有一条路径会比其它路径长出俩倍因而是近似平衡的。红黑树具有良好的插入、删除和查找性能本次提交结果为红黑树数据结构的简单实现。test_rbtree.h中定义了红黑树的数据结构和声明插入、删除、查找相关操作函数;test_rbtree.c中为操作函数的定义并提供了测试函数RBTreeTest用于验证红黑树的正确性。
## 2. 数据结构设计说明
**RBNodeType 结构体**
用来存储一个红黑树结点的相关信息
- key节点的键值
- left_child指向左子节点的指针
- right_child指向右子节点的指针
- parent指向父节点的指针
- is_red表示节点的颜色true表示红色false表示黑色
**RBTreeType 结构体**
用来存储一个红黑树的相关信息
- root指向红黑树的根节点的指针
- leaf红黑树的叶节点由于叶节点并不需要存储数据故每棵树只分配一个叶节点
用来存储一个红黑树结点的相关信息
- key结点的键值
- left_child指向左子结点的指针
- right_child指向右子结点的指针
- parent指向父结点的指针
- color表示结点颜色类型为 ColorTypeRED表示红色BLACK表示黑色
**RBTreeRootType 结构体**
用来存储红黑树根结点的相关信息
- root指向红黑树的根结点的指针
- nil指向红黑树的叶结点由于叶结点并不需要存储数据故每棵树只分配一个叶结点
**RBTreeTraversal 函数**
该函数用于遍历红黑树并打印节点的键值。采用中序遍历的方式,递归地遍历左子树、当前节点和右子树。
**RBTreeInit函数**
该函数实现红黑树的初始化。创建一个根结点和一个哨兵结点,然后将根结点指向哨兵结点。返回创建的红黑树的根结点。
**RBTreeHandleReorient函数**
该函数实现红黑树的重新定向。主要用于插入和删除操作后的调整。它会根据红黑树的性质进行左旋、右旋和颜色调整。
**RBTreeTransplant函数**
该函数实现红黑树的子树替换。用于替换红黑树中的结点。它将结点 node 替换为结点 child。
**RBTreeLeftRotate 函数**
该函数实现红黑树的左旋转操作。接受一个当前节点指针作为参数,并按照左旋转的规则调整节点和子树的位置。
该函数实现红黑树的左旋转操作。接受一个当前结点指针作为参数,并按照左旋转的规则调整结点和子树的位置。
**RBTreeRightRotate 函数**
该函数实现红黑树的右旋转操作。接受一个当前节点指针作为参数,并按照右旋转的规则调整节点和子树的位置。
该函数实现红黑树的右旋转操作。接受一个当前结点指针作为参数,并按照右旋转的规则调整结点和子树的位置。
**InsertFixup 函数**
该函数用于插入节点后修复红黑树的平衡性。接受一个当前节点指针作为参数,并根据红黑树的性质进行旋转和着色操作,以恢复平衡。
**RBTreeFindMin函数**
该函数用于查找红黑树中最小值。
**RBTreeFindMax函数**
该函数用于查找红黑树中最大值。
**RBTreeInsert 函数**
该函数用于向红黑树中插入一个新节点。接受一个新节点指针作为参数,并根据新节点的键值插入到适当的位置,然后调用 InsertFixup 进行修复。
**DeleteFixup 函数**
该函数用于删除节点后修复红黑树的平衡性。接受一个当前节点指针作为参数,并根据红黑树的性质进行旋转和着色操作,以恢复平衡。
该函数用于向红黑树中插入一个新结点。如果插入成功,返回新的红黑树的根结点。
**RBTreeDelete 函数**
该函数用于从红黑树中删除指定节点。接受一个目标节点指针作为参数,并根据不同的情况进行节点的替换和删除操作,然后调用 DeleteFixup 进行修复
该函数用于从红黑树中删除指定结点。如果删除成功,返回新的红黑树的根结点。
**FindSuccessor 函数**
该函数用于查找给定节点的后继节点。接受一个当前节点指针作为参数,并在红黑树中找到当前节点的后继节点
**RBTreePrePrint函数**
该函数用于遍历红黑树并打印结点的键值。采用先序遍历的方式,打印每个结点的键值和颜色
**RBTreeSearch 函数**
该函数用于在红黑树中查找指定键值的节点。接受一个键值作为参数,并在红黑树中进行查找,返回找到的节点指针。
**RBTreeInPrin函数**
该函数用于遍历红黑树并打印结点的键值。采用中序遍历的方式,打印每个结点的键值和颜色。
**RBTreePrint函数**
该函数用于遍历红黑树。打印红黑树的前序和中序遍历结果。
**RBTreeTest函数**
该函数用于测试红黑树的功能和正确性。测试红黑树的功能,包括初始化、插入、删除和打印操作。
## 3. 测试程序说明
TestRBTree用于验证红黑树的功能和正确性,下面是该程序的使用步骤和说明:
- 函数中定义一个默认关键字数组其中包含了20个整数关键字运行时自动遍历数组构建红黑树构建完成后中序遍历输出结果可以根据输出结果验证红黑树的节点顺序以及颜色是否符合预期。
- 对关键字数组中的每个关键字,在红黑树中进行搜索,并输出找到节点的父节点、左子节点和右子节点的关键字,随后删除该节点。
- 在每次删除操作后,程序会询问是否显示当前的红黑树。如果输入 "Y" 或 "y",将再次进行中序遍历,并输出当前红黑树中的结点,可以根据输出结果查看结点是否符合预期。当树空时结束程序。
RBTreeTest用于验证红黑树的功能和正确性,下面是该程序的使用步骤和说明:
- 函数中定义一个默认关键字数组其中包含了9个整数关键字运行时自动遍历数组构建红黑树构建完成后输出前序遍历和中序遍历结果可以根据输出结果验证红黑树的结点顺序以及颜色是否符合预期。
- 删除5个结点删除后再次输出当前红黑树中结点前序遍历和中序遍历结果。
## 4. 运行结果(##需结合运行测试截图按步骤说明##
根据默认关键字数组构建红黑树
![Alt text](image.png)
![Alt text](image1.png)
根据键值查找结点,输出相关信息并删除,可以输入'Y'或'y'展示删除后的红黑树
此时红黑树中结点前序遍历和中序遍历
![Alt text](image-1.png)
![Alt text](image2.png)
到达空树,退出程序
删除5个结点当前红黑树中结点前序遍历和中序遍历
![Alt text](image3.png)
![Alt text](image-2.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,341 +1,372 @@
/*
* Copyright (c) 2023 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
* @brief: a application of red-black tree function
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/6/23
*/
#include<string.h>
#include <transform.h>
#include"test_rbtree.h"
#ifdef ADD_XIZI_FEATURES
void RBTreeTraversal(RBTreeType *tree, RBNodeType *node)
{
if (node != tree->leaf) {
RBTreeTraversal(tree, node->left_child);
printf("key:%d, color:%s\n", node->key, (node->is_red ? "Red" : "Black"));
RBTreeTraversal(tree, node->right_child);
}
}
RBNodeType* RBTreeSearch(RBTreeType *tree, int key)
{
RBNodeType* current_node = tree->root;
while (current_node != tree->leaf){
if (key < current_node->key)
current_node = current_node->left_child;
else if (key > current_node->key)
current_node = current_node->right_child;
else
return current_node;
}
return tree->leaf;
}
void RBTreeLeftRotate(RBTreeType *tree, RBNodeType *current_node)
{
RBNodeType* child_node = current_node->right_child;
current_node->right_child = child_node->left_child;
if (child_node->left_child != tree->leaf)
child_node->left_child->parent = current_node;
child_node->parent = current_node->parent;
if (current_node->parent == tree->leaf)
tree->root = child_node;
else if (current_node == current_node->parent->left_child)
current_node->parent->left_child = child_node;
else
current_node->parent->right_child = child_node;
child_node->left_child = current_node;
current_node->parent = child_node;
}
void RBTreeRightRotate(RBTreeType *tree, RBNodeType* current_node)
{
RBNodeType* child_node = current_node->left_child;
current_node->left_child = child_node->right_child;
if (child_node->right_child != tree->leaf)
child_node->right_child->parent = current_node;
child_node->parent = current_node->parent;
if (current_node->parent == tree->leaf)
tree->root = child_node;
else if (current_node == current_node->parent->right_child)
current_node->parent->right_child = child_node;
else
current_node->parent->left_child = child_node;
child_node->right_child = current_node;
current_node->parent = child_node;
}
void InsertFixup(RBTreeType *tree, RBNodeType* current_node)
{
while (current_node->parent->is_red){
/* The parent of current_node is the left subtree of the grandfather */
if (current_node->parent == current_node->parent->parent->left_child){
RBNodeType * uncle_node = current_node->parent->parent->right_child;
if (uncle_node->is_red){ /* case1:red uncle and red parent, change color */
uncle_node->is_red = false;
current_node->parent->is_red = false;
current_node->parent->parent->is_red = true;
current_node = current_node->parent->parent;
}else{ /* case2:black uncle and red parent, need rotation */
if (current_node->parent->right_child == current_node){
current_node = current_node->parent;
RBTreeLeftRotate(tree, current_node);
}
current_node->parent->is_red = false;
current_node->parent->parent->is_red = true;
RBTreeRightRotate(tree, current_node->parent->parent);
}
/* The parent of current_node is the right subtree of the grandfather, same with left subtree */
}else{
RBNodeType * uncle_node = current_node->parent->parent->left_child;
if (uncle_node->is_red){
uncle_node->is_red = false;
current_node->parent->is_red = false;
current_node->parent->parent->is_red = true;
current_node = current_node->parent->parent;
}else{
if (current_node->parent->left_child == current_node){
current_node = current_node->parent;
RBTreeRightRotate(tree, current_node);
}
current_node->parent->is_red = false;
current_node->parent->parent->is_red = true;
RBTreeLeftRotate(tree, current_node->parent->parent);
}
}
}
tree->root->is_red = false;
}
void RBTreeInsert(RBTreeType *tree, RBNodeType* new_node)
{
RBNodeType* previous_node = tree->root;
RBNodeType* current_node = tree->root;
while (current_node != tree->leaf){
previous_node = current_node;
if (new_node->key > current_node->key)
current_node = current_node->right_child;
else if (new_node->key < current_node->key)
current_node = current_node->left_child;
else
return;
}
if (previous_node == tree->leaf){
tree->root = new_node;
tree->root->parent = tree->leaf;
}else{
new_node->parent = previous_node;
if (previous_node->key > new_node->key)
previous_node->left_child = new_node;
else
previous_node->right_child = new_node;
}
InsertFixup(tree, new_node);
}
RBNodeType* FindSuccessor(RBTreeType *tree, RBNodeType* current_node)
{
RBNodeType* parent_node = current_node->parent;
if (current_node->right_child != tree->leaf){
current_node = current_node->right_child;
while (current_node->left_child != tree->leaf)
current_node = current_node->left_child;
return current_node;
}
while ((parent_node != tree->leaf) && (current_node == parent_node->right_child)){
current_node = parent_node;
parent_node = parent_node->parent;
}
return parent_node;
}
void DeleteFixup(RBTreeType *tree, RBNodeType* current_node)
{
while ((current_node != tree->root) && (current_node->is_red == false)){
if (current_node == current_node->parent->left_child){
RBNodeType* brother_node = current_node->parent->right_child;
if (brother_node->is_red){
brother_node->is_red = false;
current_node->parent->is_red = true;
RBTreeLeftRotate(tree, current_node->parent);
brother_node = current_node->parent->right_child;
}
if ((brother_node->left_child->is_red == false) && (brother_node->right_child->is_red == false)){
brother_node->is_red = true;
current_node = current_node->parent;
}else{
if (brother_node->right_child->is_red == false){
brother_node->left_child->is_red = false;
brother_node->is_red = true;
RBTreeRightRotate(tree, brother_node);
brother_node = current_node->parent->right_child;
}
brother_node->is_red = current_node->parent->is_red;
current_node->parent->is_red = false;
brother_node->right_child->is_red = false;
RBTreeLeftRotate(tree, current_node->parent);
current_node = tree->root;
}
}else{
RBNodeType* brother_node = current_node->parent->left_child;
if (brother_node->is_red){
brother_node->is_red = false;
current_node->parent->is_red = true;
RBTreeRightRotate(tree, current_node->parent);
brother_node = current_node->parent->left_child;
}
if ((brother_node->left_child->is_red == false) && (brother_node->right_child->is_red == false)){
brother_node->is_red = true;
current_node = current_node->parent;
}else{
if (brother_node->left_child->is_red == false){
brother_node->right_child->is_red = false;
brother_node->is_red = true;
RBTreeLeftRotate(tree, brother_node);
brother_node = current_node->parent->left_child;
}
brother_node->is_red = current_node->parent->is_red;
current_node->parent->is_red = false;
brother_node->left_child->is_red = false;
RBTreeRightRotate(tree, current_node->parent);
current_node = tree->root;
}
}
}
current_node->is_red = false;
}
void RBTreeDelete(RBTreeType *tree, RBNodeType* target_node)
{
RBNodeType* delete_node = tree->leaf;
RBNodeType* replace_node = tree->leaf;
if ((target_node->left_child == tree->leaf) || (target_node->right_child == tree->leaf))
delete_node = target_node;
else
delete_node = FindSuccessor(tree, target_node);
if (delete_node->left_child != tree->leaf) /* successor still has subtree */
replace_node = delete_node->left_child;
else if (delete_node->right_child != tree->leaf)
replace_node = delete_node->right_child;
replace_node->parent = delete_node->parent;
if (delete_node->parent == tree->leaf) /* delete a root node */
tree->root = replace_node;
else if (delete_node == delete_node->parent->left_child)
delete_node->parent->left_child = replace_node;
else
delete_node->parent->right_child = replace_node;
if (delete_node != target_node)
target_node->key = delete_node->key;
if (delete_node->is_red == false)
DeleteFixup(tree, replace_node);
free(delete_node);
}
void TestRBTree(void)
{
int default_key[] = { 16, 25, 23, 5, 2, 6, 17, 37, 38, 98, 20, 19, 47, 49, 12, 21, 9, 18, 14, 15 };
int array_size = sizeof(default_key) / sizeof(default_key[0]);
printf("Test Red Black Tree\n");
printf("default_key array: ");
for (int i = 0; i < array_size; i++)
printf("%d ", default_key[i]);
printf("\n%d elements\n", array_size);
RBTreeType *tree = (RBTreeType *)malloc(sizeof(RBTreeType));
if (tree == NULL) {
printf("malloc failed\n");
return;
}
tree->leaf = (RBNodeType*)malloc(sizeof(RBNodeType));
tree->leaf->left_child = NULL;
tree->leaf->right_child = NULL;
tree->leaf->parent = NULL;
tree->leaf->is_red = false;
tree->leaf->key = -1;
tree->root = tree->leaf;
RBNodeType *node = tree->leaf;
for (int i = 0; i < array_size; i++) {
node = (RBNodeType*)malloc(sizeof(RBNodeType));
node->left_child = tree->leaf;
node->right_child = tree->leaf;
node->parent = NULL;
node->is_red = true;
node->key = default_key[i];
printf("insert key[%d]=%d\n",i,default_key[i]);
RBTreeInsert(tree, node);
}
printf("------------------Inorder Traversal------------------\n");
RBTreeTraversal(tree, tree->root);
for (int i = 0; i < array_size; i++) {
printf("search key = %d\n", default_key[i]);
node = RBTreeSearch(tree, default_key[i]);
printf("search succeeded, parent node: %d, left-child: %d, right-child: %d\n", node->parent->key, node->left_child->key, node->right_child->key);
printf("delete key = %d\n", node->key);
RBTreeDelete(tree, node);
printf("Show current tree?Y/N \n");
char ch;
scanf("%c", &ch);
if (ch == 'Y' || ch == 'y') {
printf("------------------Inorder Traversal Tree After Deletion------------------\n");
if (tree->root != tree->leaf)
RBTreeTraversal(tree, tree->root);
else
printf("the tree is empty.\n");
}
}
}
PRIV_SHELL_CMD_FUNCTION(TestRBTree, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#endif
/*
* Copyright (c) 2023 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
* @brief: a application of red-black tree function
* @version: 1.0
* @author:
* @date: 2023/9/18
*/
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "test_rbtree.h"
#include <transform.h>
#ifdef ADD_XIZI_FEATURES
RBTreeRootType *RBTreeInit(void)
{
RBTreeRootType *TreeRoot;
TreeRoot = (RBTreeRootType *)malloc(sizeof(RBTreeRootType));
assert(TreeRoot != NULL);
TreeRoot->nil = (RBTreeType *)malloc(sizeof(RBTreeType));
assert(TreeRoot->nil != NULL);
TreeRoot->nil->color = BLACK;
TreeRoot->nil->left = NULL;
TreeRoot->nil->right = NULL;
TreeRoot->nil->parent = NULL;
TreeRoot->root = TreeRoot->nil;
return TreeRoot;
}
static void RBTreeHandleReorient(RBTreeRootType *TreeRoot, RBTreeType *node, int key)
{
node->color = RED;
node->left->color = BLACK;
node->right->color = BLACK;
if (node->parent->color == RED){
node->parent->parent->color = RED;
if (node->parent->key < node->parent->parent->key){
if (key > node->parent->key){
node->color = BLACK;
RBTreeLeftRotate(TreeRoot, node->parent);
RBTreeRightRotate(TreeRoot, node->parent);
}else{
node->parent->color = BLACK;
RBTreeRightRotate(TreeRoot, node->parent->parent);
}
}else{
if (key < node->parent->key){
node->color = BLACK;
RBTreeRightRotate(TreeRoot, node->parent);
RBTreeLeftRotate(TreeRoot, node->parent);
}else{
node->parent->color = BLACK;
RBTreeLeftRotate(TreeRoot, node->parent->parent);
}
}
}
TreeRoot->root->color = BLACK;
}
void RBTreeTransplant(RBTreeRootType *TreeRoot, RBTreeType *node, RBTreeType *child)
{
if (node->parent == TreeRoot->nil)
TreeRoot->root = child;
else if (node == node->parent->left)
node->parent->left = child;
else
node->parent->right = child;
child->parent = node->parent;
}
static void RBTreeLeftRotate(RBTreeRootType *TreeRoot, RBTreeType *node)
{
RBTreeType *nodeNew = node->right;
node->right = nodeNew->left;
if (nodeNew->left != TreeRoot->nil)
nodeNew->left->parent = node;
nodeNew->parent = node->parent;
if (node->parent == TreeRoot->nil)
TreeRoot->root = nodeNew;
else if (node == node->parent->left)
node->parent->left = nodeNew;
else
node->parent->right = nodeNew;
nodeNew->left = node;
node->parent = nodeNew;
}
static void RBTreeRightRotate(RBTreeRootType *TreeRoot, RBTreeType *node)
{
RBTreeType *nodeNew = node->left;
node->left = nodeNew->right;
if (nodeNew->right != TreeRoot->nil)
nodeNew->right->parent = node;
nodeNew->parent = node->parent;
if (node->parent == TreeRoot->nil)
TreeRoot->root = nodeNew;
else if (node == node->parent->left)
node->parent->left = nodeNew;
else
node->parent->right = nodeNew;
nodeNew->right = node;
node->parent = nodeNew;
}
static RBTreeType *RBTreeFindMin(RBTreeRootType *TreeRoot, RBTreeType *node)
{
if (node == TreeRoot->nil)
return TreeRoot->nil;
while (node->left != TreeRoot->nil)
node = node->left;
return node;
}
static RBTreeType *RBTreeFindMax(RBTreeRootType *TreeRoot, RBTreeType *node)
{
if (node == TreeRoot->nil)
return TreeRoot->nil;
while (node->right != TreeRoot->nil)
node = node->right;
return node;
}
RBTreeRootType *RBTreeInsert(RBTreeRootType *TreeRoot, int key)
{
RBTreeType *node, *parent;
node = TreeRoot->root;
parent = node;
while (node != TreeRoot->nil){
if (node != TreeRoot->nil){
if (node->left->color == RED && node->right->color == RED){
RBTreeHandleReorient(TreeRoot, node, key);
}
}
parent = node;
if (key < node->key)
node = node->left;
else if (key > node->key)
node = node->right;
else
return TreeRoot;
}
node = (RBTreeType *)malloc(sizeof(RBTreeType));
assert(node != NULL);
node->key = key;
node->color = RED;
node->left = TreeRoot->nil;
node->right = TreeRoot->nil;
node->parent = parent;
if (TreeRoot->root == TreeRoot->nil)
TreeRoot->root = node;
else if (key < parent->key)
parent->left = node;
else
parent->right = node;
RBTreeHandleReorient(TreeRoot, node, key);
return TreeRoot;
}
RBTreeRootType *RBTreeDelete(RBTreeRootType *TreeRoot, int key)
{
assert(TreeRoot != NULL);
if (NULL == TreeRoot->root)
return TreeRoot;
RBTreeType *ToDelete = TreeRoot->root;
RBTreeType *node;
while (ToDelete != TreeRoot->nil && ToDelete->key != key){
if (ToDelete->key > key)
ToDelete = ToDelete->left;
else if (ToDelete->key < key)
ToDelete = ToDelete->right;
}
if (ToDelete == TreeRoot->nil)
return TreeRoot;
if (ToDelete->left != TreeRoot->nil && ToDelete->right != TreeRoot->nil){
RBTreeType *alternative = RBTreeFindMin(TreeRoot, ToDelete->right);
key = alternative->key;
ToDelete->key = alternative->key;
ToDelete = alternative;
}
if (ToDelete->left == TreeRoot->nil){
node = ToDelete->right;
RBTreeTransplant(TreeRoot, ToDelete, ToDelete->right);
}else if (ToDelete->right == TreeRoot->nil){
node = ToDelete->left;
RBTreeTransplant(TreeRoot, ToDelete, ToDelete->left);
}
if (ToDelete->color == BLACK){
while (node != TreeRoot->root && node->color == BLACK){
if (node == node->parent->left){
RBTreeType *brother = node->parent->right;
if (brother->color == RED){
brother->color = BLACK;
brother->parent->color = RED;
RBTreeLeftRotate(TreeRoot, node->parent);
brother = node->parent->right;
}
if (brother->left->color == BLACK && brother->right->color == BLACK){
if (brother->parent->color == RED){
node->parent->color = BLACK;
brother->color = RED;
break;
}else{
brother->color = RED;
node = node->parent;
continue;
}
}
if (brother->right->color == BLACK){
brother->left->color = BLACK;
brother->color = RED;
RBTreeRightRotate(TreeRoot, brother);
brother = node->parent->right;
}
brother->color = node->parent->color;
node->parent->color = BLACK;
brother->right->color = BLACK;
RBTreeLeftRotate(TreeRoot, node->parent);
node = TreeRoot->root;
}else{
RBTreeType *brother = node->parent->left;
if (brother->color == RED){
brother->color = BLACK;
node->parent->color = RED;
RBTreeRightRotate(TreeRoot, node->parent);
brother = node->parent->left;
}
if (brother->left->color == BLACK && brother->right->color == BLACK){
if (brother->parent->color == RED){
node->parent->color = BLACK;
brother->color = RED;
break;
}else{
node->parent->color = BLACK;
brother->color = RED;
node = node->parent;
continue;
}
}
if (brother->left->color == BLACK){
brother->color = RED;
brother->right->color = BLACK;
brother = node->parent->left;
}
brother->color = node->parent->color;
node->parent->color = BLACK;
brother->left->color = BLACK;
RBTreeRightRotate(TreeRoot, node->parent);
node = TreeRoot->root;
}
}
node->color = BLACK;
}
free(ToDelete);
return TreeRoot;
}
void RBTreePrePrint(const RBTreeRootType *TreeRoot, RBTreeType *node)
{
if (TreeRoot->nil == node)
return;
if (node->color == RED)
printf("%3d(R) ", node->key);
else
printf("%3d(B) ", node->key);
RBTreePrePrint(TreeRoot, node->left);
RBTreePrePrint(TreeRoot, node->right);
}
void RBTreeInPrint(const RBTreeRootType *TreeRoot, RBTreeType *node)
{
if (TreeRoot->nil == node)
return;
RBTreeInPrint(TreeRoot, node->left);
if (node->color == RED)
printf("%3d(R) ", node->key);
else
printf("%3d(B) ", node->key);
RBTreeInPrint(TreeRoot, node->right);
}
void RBTreePrint(const RBTreeRootType *TreeRoot)
{
assert(TreeRoot != NULL);
printf("前序遍历: ");
RBTreePrePrint(TreeRoot, TreeRoot->root);
printf("\n");
printf("中序遍历: ");
RBTreeInPrint(TreeRoot, TreeRoot->root);
printf("\n");
}
void RBTreeTest(void)
{
RBTreeRootType *TreeRoot = RBTreeInit();
int i;
int array[10] = { 11, 7, 1, 2, 8, 14, 15, 5, 4 };
printf("Test Red Black Tree\n");
printf("default_key array: ");
for (i = 0; i < 9; i++){
printf("%d ", array[i]);
RBTreeInsert(TreeRoot, array[i]);
}
printf("\n");
// TreeRoot = RBTreeInsert(TreeRoot, 4);
RBTreePrint(TreeRoot);
RBTreeDelete(TreeRoot, 8);
RBTreeDelete(TreeRoot, 14);
RBTreeDelete(TreeRoot, 7);
RBTreeDelete(TreeRoot, 11);
RBTreeDelete(TreeRoot, 8);
RBTreePrint(TreeRoot);
}
PRIV_SHELL_CMD_FUNCTION(RBTreeTest, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#endif

View File

@ -1,60 +1,62 @@
/*
* Copyright (c) 2023 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.h
* @brief: a head file of red-black tree structure
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/6/23
*/
#ifndef REDBLACKTREE_H_
#define REDBLACKTREE_H_
#include <stdbool.h>
#include <stdio.h>
typedef struct RedBlackNode
{
int key;
struct RedBlackNode *left_child;
struct RedBlackNode *right_child;
struct RedBlackNode *parent;
bool is_red;
} RBNodeType;
typedef struct RedBlackTree
{
RBNodeType *root;
RBNodeType *leaf;
} RBTreeType;
void TestRBTree(void);
void RBTreeTraversal(RBTreeType *tree, RBNodeType *node);
void RBTreeLeftRotate(RBTreeType *tree, RBNodeType *current_node);
void RBTreeRightRotate(RBTreeType *tree, RBNodeType* current_node);
void InsertFixup(RBTreeType *tree, RBNodeType* current_node);
void RBTreeInsert(RBTreeType *tree, RBNodeType* new_node);
void DeleteFixup(RBTreeType *tree, RBNodeType* current_node);
void RBTreeDelete(RBTreeType *tree, RBNodeType* target_node);
RBNodeType* FindSuccessor(RBTreeType *tree, RBNodeType* current_node);
RBNodeType* RBTreeSearch(RBTreeType *tree, int key);
/*
* Copyright (c) 2023 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.h
* @brief: a head file of red-black tree structure
* @version: 1.0
* @author:
* @date: 2023/9/11
*/
#ifndef TEST_RBTREE_H
#define TEST_RBTREE_H
// 红黑树
typedef enum ColorType {RED, BLACK} ColorType;
typedef struct RBTreeType
{
int key;
struct RBTreeType *left;
struct RBTreeType *right;
struct RBTreeType *parent;
ColorType color;
}RBTreeType;
typedef struct RBTreeRootType
{
struct RBTreeType *root;
struct RBTreeType *nil;
}RBTreeRootType;
RBTreeRootType *RBTreeInit(void);
static void RBTreeHandleReorient(RBTreeRootType *TreeRoot, RBTreeType *node, int key);
void RBTreeTransplant(RBTreeRootType *TreeRoot, RBTreeType *node, RBTreeType *child);
static void RBTreeLeftRotate(RBTreeRootType *TreeRoot, RBTreeType *node);
static void RBTreeRightRotate(RBTreeRootType *TreeRoot, RBTreeType *node);
static RBTreeType *RBTreeFindMin(RBTreeRootType *TreeRoot, RBTreeType *node);
static RBTreeType *RBTreeFindMax(RBTreeRootType *TreeRoot, RBTreeType *node);
RBTreeRootType *RBTreeInsert(RBTreeRootType *TreeRoot, int key);
RBTreeRootType *RBTreeDelete(RBTreeRootType *TreeRoot, int key);
void RBTreePrePrint(const RBTreeRootType *TreeRoot, RBTreeType *node);
void RBTreeInPrint(const RBTreeRootType *TreeRoot, RBTreeType *node);
void RBTreePrint(const RBTreeRootType *TreeRoot);
void RBTreeTest(void);
#endif

View File

@ -1,14 +1,14 @@
/*
* 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.
*/
* 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.
*/
#include <stdio.h>
#include <string.h>
@ -19,13 +19,13 @@ extern int FrameworkInit();
extern void ApplicationOtaTaskInit(void);
int main(void)
{
printf("Hello, world! \n");
// printf("Hello, world! \n");
// printf("Hello, DHU!\nI'm Tang Liyuan. My student number is 201310424.\n");
printf("Hello, GitLink! \nWe're \"白痴也有春天\". \n");
FrameworkInit();
#ifdef APPLICATION_OTA
ApplicationOtaTaskInit();
#endif
return 0;
return 0;
}
// int cppmain(void);