ADD test_rbtree
This commit is contained in:
parent
fe2b0a2293
commit
93d6fa60af
|
@ -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
|
Loading…
Reference in New Issue