ADD test_rbtree

This commit is contained in:
abc7902564 2023-09-28 22:28:35 +08:00
parent fe2b0a2293
commit 93d6fa60af
1 changed files with 561 additions and 0 deletions

View File

@ -0,0 +1,561 @@
/*
* 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/23
*/
#include<string.h>
#include <transform.h>
#include"test_rbtree.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef ADD_XIZI_FEATURES
// 红黑树节点颜色
#define RED true
#define BLACK false
// 初始化红黑树
void InitializeRBTree(RBTreeType* tree) {
tree->root = NULL; // 设置树根为空
tree->leaf = (RBNodeType*)malloc(sizeof(RBNodeType)); // 分配叶子节点内存
tree->leaf->is_red = BLACK; // 设置叶子节点为黑色
tree->leaf->left_child = NULL;
tree->leaf->right_child = NULL;
tree->leaf->parent = NULL;
tree->leaf->key = -1; // 叶子节点的键值设置为特殊值
}
// 释放红黑树内存
void FreeRBTree(RBTreeType* tree, RBNodeType* node) {
if (node == NULL || node == tree->leaf) {
return;
}
FreeRBTree(tree, node->left_child);
FreeRBTree(tree, node->right_child);
free(node);
}
// 辅助函数
static RBNodeType* RBTreeMinimum(RBNodeType* node) {
while (node->left_child != NULL) {
node = node->left_child;
}
return node;
}
static void RBTreeTransplant(RBTreeType* tree, RBNodeType* old_node, RBNodeType* new_node) {
if (old_node->parent == tree->leaf) {
tree->root = new_node;
} else if (old_node == old_node->parent->left_child) {
old_node->parent->left_child = new_node;
} else {
old_node->parent->right_child = new_node;
}
if (new_node != NULL) {
new_node->parent = old_node->parent;
}
}
// 左旋转操作
static void RBTreeLeftRotate(RBTreeType* tree, RBNodeType* current_node) {
RBNodeType* right_child = current_node->right_child;
current_node->right_child = right_child->left_child;
if (right_child->left_child != tree->leaf) {
right_child->left_child->parent = current_node;
}
right_child->parent = current_node->parent;
if (current_node->parent == tree->leaf) {
tree->root = right_child;
} else if (current_node == current_node->parent->left_child) {
current_node->parent->left_child = right_child;
} else {
current_node->parent->right_child = right_child;
}
right_child->left_child = current_node;
current_node->parent = right_child;
}
// 右旋转操作
static void RBTreeRightRotate(RBTreeType* tree, RBNodeType* current_node) {
RBNodeType* left_child = current_node->left_child;
current_node->left_child = left_child->right_child;
if (left_child->right_child != tree->leaf) {
left_child->right_child->parent = current_node;
}
left_child->parent = current_node->parent;
if (current_node->parent == tree->leaf) {
tree->root = left_child;
} else if (current_node == current_node->parent->right_child) {
current_node->parent->right_child = left_child;
} else {
current_node->parent->left_child = left_child;
}
left_child->right_child = current_node;
current_node->parent = left_child;
}
// 插入修复函数
static void InsertFixup(RBTreeType* tree, RBNodeType* current_node) {
while (current_node->parent->is_red) {
if (current_node->parent == current_node->parent->parent->left_child) {
RBNodeType* uncle = current_node->parent->parent->right_child;
if (uncle->is_red) {
current_node->parent->is_red = BLACK;
uncle->is_red = BLACK;
current_node->parent->parent->is_red = RED;
current_node = current_node->parent->parent;
} else {
if (current_node == current_node->parent->right_child) {
current_node = current_node->parent;
RBTreeLeftRotate(tree, current_node);
}
current_node->parent->is_red = BLACK;
current_node->parent->parent->is_red = RED;
RBTreeRightRotate(tree, current_node->parent->parent);
}
} else {
// 对称的情况
RBNodeType* uncle = current_node->parent->parent->left_child;
if (uncle->is_red) {
current_node->parent->is_red = BLACK;
uncle->is_red = BLACK;
current_node->parent->parent->is_red = RED;
current_node = current_node->parent->parent;
} else {
if (current_node == current_node->parent->left_child) {
current_node = current_node->parent;
RBTreeRightRotate(tree, current_node);
}
current_node->parent->is_red = BLACK;
current_node->parent->parent->is_red = RED;
RBTreeLeftRotate(tree, current_node->parent->parent);
}
}
}
tree->root->is_red = BLACK;
}
// 插入操作
void RBTreeInsert(RBTreeType* tree, RBNodeType* new_node) {
RBNodeType* current_node = tree->root;
RBNodeType* parent_node = tree->leaf;
// 找到插入位置
while (current_node != tree->leaf) {
//printf("dao xun huan fou\n");
parent_node = current_node;
if (new_node->key < current_node->key) {
current_node = current_node->left_child;
} else {
current_node = current_node->right_child;
}
}
//printf("chu xun huan fou\n");
new_node->parent = parent_node;
if (parent_node == tree->leaf) {
tree->root = new_node;
} else if (new_node->key < parent_node->key) {
parent_node->left_child = new_node;
} else {
parent_node->right_child = new_node;
}
new_node->left_child = tree->leaf;
new_node->right_child = tree->leaf;
new_node->is_red = RED;
//printf("dao xiu fu fou\n");
InsertFixup(tree, new_node);
}
/*
// 删除修复函数
static void DeleteFixup(RBTreeType* tree, RBNodeType* current_node) {
while (current_node != tree->root && current_node->is_red == BLACK) {
if (current_node == current_node->parent->left_child) {
RBNodeType* sibling = current_node->parent->right_child;
if (sibling->is_red) {
sibling->is_red = BLACK;
current_node->parent->is_red = RED;
RBTreeLeftRotate(tree, current_node->parent);
sibling = current_node->parent->right_child;
}
if (sibling->left_child->is_red == BLACK && sibling->right_child->is_red == BLACK) {
sibling->is_red = RED;
current_node = current_node->parent;
} else {
if (sibling->right_child->is_red == BLACK) {
sibling->left_child->is_red = BLACK;
sibling->is_red = RED;
RBTreeRightRotate(tree, sibling);
sibling = current_node->parent->right_child;
}
sibling->is_red = current_node->parent->is_red;
current_node->parent->is_red = BLACK;
sibling->right_child->is_red = BLACK;
RBTreeLeftRotate(tree, current_node->parent);
current_node = tree->root;
}
} else {
// 对称的情况
RBNodeType* sibling = current_node->parent->left_child;
if (sibling->is_red) {
sibling->is_red = BLACK;
current_node->parent->is_red = RED;
RBTreeRightRotate(tree, current_node->parent);
sibling = current_node->parent->left_child;
}
if (sibling->right_child->is_red == BLACK && sibling->left_child->is_red == BLACK) {
sibling->is_red = RED;
current_node = current_node->parent;
} else {
if (sibling->left_child->is_red == BLACK) {
sibling->right_child->is_red = BLACK;
sibling->is_red = RED;
RBTreeLeftRotate(tree, sibling);
sibling = current_node->parent->left_child;
}
sibling->is_red = current_node->parent->is_red;
current_node->parent->is_red = BLACK;
sibling->left_child->is_red = BLACK;
RBTreeRightRotate(tree, current_node->parent);
current_node = tree->root;
}
}
}
current_node->is_red = BLACK;
}
// 删除节点
void RBTreeDelete(RBTreeType* tree, RBNodeType* target_node) {
RBNodeType* current_node = target_node;
RBNodeType* temp_node;
bool original_color = current_node->is_red;
if (target_node->left_child == tree->leaf) {
temp_node = target_node->right_child;
RBTreeTransplant(tree, target_node, target_node->right_child);
} else if (target_node->right_child == tree->leaf) {
temp_node = target_node->left_child;
RBTreeTransplant(tree, target_node, target_node->left_child);
} else {
current_node = RBTreeMinimum(target_node->right_child);
original_color = current_node->is_red;
temp_node = current_node->right_child;
if (current_node->parent == target_node) {
temp_node->parent = current_node;
} else {
RBTreeTransplant(tree, current_node, current_node->right_child);
current_node->right_child = target_node->right_child;
current_node->right_child->parent = current_node;
}
RBTreeTransplant(tree, target_node, current_node);
current_node->left_child = target_node->left_child;
current_node->left_child->parent = current_node;
current_node->is_red = target_node->is_red;
}
if (original_color == BLACK) {
DeleteFixup(tree, temp_node);
}
free(target_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);
}
/*
// 查找后继节点
RBNodeType* FindSuccessor(RBTreeType* tree, RBNodeType* current_node) {
if (current_node->right_child != tree->leaf) {
return RBTreeMinimum(current_node->right_child);
}
RBNodeType* parent_node = current_node->parent;
while (parent_node != tree->leaf && current_node == parent_node->right_child) {
current_node = parent_node;
parent_node = parent_node->parent;
}
return parent_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;
}
// 中序遍历红黑树
static void RBTreeInorderTraversal(RBTreeType* tree, RBNodeType* node) {
if (node != tree->leaf) {
RBTreeInorderTraversal(tree, node->left_child);
printf("%d(%s) ", node->key, node->is_red ? "RED" : "BLACK");
RBTreeInorderTraversal(tree, node->right_child);
}
}
// 对外提供的遍历接口
void RBTreeTraversal(RBTreeType* tree) {
RBTreeInorderTraversal(tree, tree->root);
printf("\n");
}
// 在红黑树中查找指定键值的节点
RBNodeType* RBTreeSearch(RBTreeType* tree, int key) {
RBNodeType* current_node = tree->root;
while (current_node != tree->leaf) {
if (key == current_node->key) {
return current_node;
} else if (key < current_node->key) {
current_node = current_node->left_child;
} else {
current_node = current_node->right_child;
}
}
return NULL;
}
/*
// 测试函数
void TestRBTree(void) {
RBTreeType tree;
InitializeRBTree(&tree); // 初始化红黑树
int keys[] = {50, 30, 70, 20, 40, 60, 80, 10, 25, 35, 45, 55, 65, 75, 90, 5, 15, 28, 38, 48};
for (int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
RBNodeType* new_node = (RBNodeType*)malloc(sizeof(RBNodeType));
if (new_node == NULL) {
// 处理内存分配失败的情况
fprintf(stderr, "Error: Memory allocation failed.\n");
}
new_node->left_child = NULL;
new_node->right_child = NULL;
new_node->parent = NULL;
new_node->is_red = true;
new_node->key = keys[i];
printf("charuqian\n ");
RBTreeInsert(&tree, new_node);
}
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n ");
printf("Inorder Traversal: ");
RBTreeTraversal(&tree);
printf("Enter key to search and delete (Ctrl+C to exit):\n");
int key;
while (1) {
printf("Enter key: ");
if (scanf("%d", &key) != 1) {
printf("Invalid input. Please enter a valid integer.\n");
continue;
}
RBNodeType* found_node = RBTreeSearch(&tree, key);
if (found_node != NULL) {
printf("Key %d found. Parent: %d, Left: %d, Right: %d\n", key,
found_node->parent != NULL ? found_node->parent->key : -1,
found_node->left_child != NULL ? found_node->left_child->key : -1,
found_node->right_child != NULL ? found_node->right_child->key : -1);
RBTreeDelete(&tree, found_node);
printf("Key %d deleted\n", key);
printf("Inorder Traversal: ");
RBTreeTraversal(&tree);
} else {
printf("Key %d not found\n", key);
}
}
// 释放红黑树内存
FreeRBTree(&tree, tree.root);
free(tree.leaf);
}
*/
void TestRBTree(void)
{
int default_key[] = {50, 30, 70, 20, 40, 60, 80, 10, 25, 35, 45, 55, 65, 75, 90, 5, 15, 28, 38, 48};
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: ");
RBTreeTraversal(tree);
int key;
while (1) {
printf("Enter key: ");
if (scanf("%d", &key) != 1) {
printf("Invalid input. Please enter a valid integer.\n");
continue;
}
if (key==-1||tree==NULL)
{
break;
}
RBNodeType* found_node = RBTreeSearch(tree, key);
if (found_node != NULL) {
printf("Key %d found. Parent: %d, Left: %d, Right: %d\n", key,
found_node->parent != NULL ? found_node->parent->key : -1,
found_node->left_child != NULL ? found_node->left_child->key : -1,
found_node->right_child != NULL ? found_node->right_child->key : -1);
RBTreeDelete(tree, found_node);
printf("Key %d deleted\n", key);
printf("Inorder Traversal: ");
RBTreeTraversal(tree);
} else {
printf("Key %d not found\n", key);
}
}
// 释放红黑树内存
FreeRBTree(tree, tree->root);
free(tree->leaf);
}
PRIV_SHELL_CMD_FUNCTION(TestRBTree, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#endif