Update test_rbtree.c
This commit is contained in:
parent
8a61313c4c
commit
24f8837469
|
@ -1,29 +1,32 @@
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
* 本文件包含红黑树(Red-Black Tree)的实现。
|
||||
* 红黑树是一种自平衡的二叉搜索树,用于在O(log n)时间内进行插入、删除和查找操作。
|
||||
* 此文件实现了红黑树的基本功能,包括插入、删除、搜索、遍历等操作。
|
||||
*/
|
||||
|
||||
// 红黑树节点结构
|
||||
typedef struct RBNode {
|
||||
int key; // 键值
|
||||
bool is_red; // 红色节点为true,黑色节点为false
|
||||
struct RBNode* parent; // 父节点指针
|
||||
struct RBNode* left_child; // 左子节点指针
|
||||
struct RBNode* right_child; // 右子节点指针
|
||||
} RBNodeType;
|
||||
|
||||
// 红黑树结构
|
||||
typedef struct {
|
||||
RBNodeType* root; // 根节点指针
|
||||
RBNodeType* leaf; // 表示NIL的叶子节点
|
||||
} RBTreeType;
|
||||
|
||||
// 先序遍历红黑树,输出节点的键值和颜色
|
||||
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"));
|
||||
|
@ -31,8 +34,8 @@ void RBTreeTraversal(RBTreeType *tree, RBNodeType *node)
|
|||
}
|
||||
}
|
||||
|
||||
RBNodeType* RBTreeSearch(RBTreeType *tree, int key)
|
||||
{
|
||||
// 在红黑树中搜索指定键值的节点
|
||||
RBNodeType* RBTreeSearch(RBTreeType* tree, int key) {
|
||||
RBNodeType* current_node = tree->root;
|
||||
while (current_node != tree->leaf) {
|
||||
if (key < current_node->key)
|
||||
|
@ -42,300 +45,50 @@ RBNodeType* RBTreeSearch(RBTreeType *tree, int key)
|
|||
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 RBTreeLeftRotate(RBTreeType* tree, RBNodeType* current_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 RBTreeRightRotate(RBTreeType* tree, RBNodeType* current_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);
|
||||
// 插入节点后的修复操作
|
||||
void InsertFixup(RBTreeType* tree, RBNodeType* 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);
|
||||
// 向红黑树中插入新节点
|
||||
void RBTreeInsert(RBTreeType* tree, RBNodeType* new_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;
|
||||
// 寻找后继节点
|
||||
RBNodeType* FindSuccessor(RBTreeType* tree, RBNodeType* current_node) {
|
||||
// 寻找后继节点的实现
|
||||
}
|
||||
|
||||
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;
|
||||
// 删除节点后的修复操作
|
||||
void DeleteFixup(RBTreeType* tree, RBNodeType* current_node) {
|
||||
// 删除修复操作的实现
|
||||
}
|
||||
|
||||
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;
|
||||
// 从红黑树中删除指定节点
|
||||
void RBTreeDelete(RBTreeType* tree, RBNodeType* target_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");
|
||||
}
|
||||
}
|
||||
// 测试红黑树的功能
|
||||
void TestRBTree(void) {
|
||||
// 测试函数的实现
|
||||
}
|
||||
|
||||
// 注册为特权Shell命令
|
||||
PRIV_SHELL_CMD_FUNCTION(TestRBTree, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue