From c4ea040660bce3cfd0a26a7e4a685b8b61e2556f Mon Sep 17 00:00:00 2001 From: jf-home Date: Mon, 2 Sep 2024 00:54:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=88=E6=B7=BB=E5=8A=A0=E4=B8=8A=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E6=98=AF=E5=85=B7=E4=BD=93=E7=9A=84=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=96=B9=E6=A1=88=EF=BC=8C=E6=83=B3=E7=AD=89=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E8=BF=AD=E4=BB=A3=E5=99=A8=E7=9B=B8=E5=85=B3=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=90=8E=E5=86=8D=E5=86=99=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test.c | 1 + test/test_tree.c | 470 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 470 insertions(+), 1 deletion(-) diff --git a/test/test.c b/test/test.c index fb2c3b1..e046aaf 100644 --- a/test/test.c +++ b/test/test.c @@ -83,6 +83,7 @@ int main(int argc, char const *argv[]) TEST_ADD(test_list); TEST_ADD(test_deque); TEST_ADD(test_heap); + TEST_ADD(test_tree); return UNITY_END(); } diff --git a/test/test_tree.c b/test/test_tree.c index 2a37cad..e555afc 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -1,3 +1,471 @@ - +/** + * @file test_tree.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-09-02 + * + * @copyright Copyright (c) 2024 + * + */ #include "test.h" +// if vs2022 has error: 'max': macro redefinition +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#if 0 +/** + * @brief + * int data[] = { 5,2,3,1,7,8,6 }; + * 5 + * | | + * 2 7 + * | | | | + * 1 3 6 8 + */ +void test_avltree_num(void) +{ + uint32_t i = 0; + // int data[] = { 2,1,3,4}; + // int data[] = { 1,2,3,4,5,6}; + // int data[] = { 5,2,3,1,7,8,6 }; + int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + tree_t tree = tree_new(); + tree_avl_init(tree, sizeof(int)); + tree->print_obj = print_num; + tree->compare = compare_num; + + printf("\n\n----- demo_avltree_num -----\n"); + + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + + printf("insert = "); + tree->print_obj(&temp); + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + } + + printf("----- max -----\n"); + tree->max(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- min -----\n"); + tree->min(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- tree -----\n"); + tree->clear(tree); + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + } + + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + + printf("----- right priority -----\n"); + tree->order(tree, true); + + printf("----- preorder(right) -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder(right) -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder(right) -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth(right) -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + + + printf("----- left priority -----\n"); + tree->order(tree, false); + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + for (i = 0; i < len; i++) + { + temp = data[i]; + // delete + tree->delete(tree, &temp); + + printf("delete = "); + tree->print_obj(&temp); + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + } + + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } + + tree_free(&tree); +} + +static bool tree_rb_check_color(struct _tree *self, struct _tree_node* root, int black_num, int black_num_expected) +{ + if(root == NULL) + { + if(black_num != black_num_expected) + { + printf("black_num != black_num_expected\n"); + return false; + } + return true; + } + + if(root->color == RBT_BLACK) + { + black_num++; + } + + if(root->color == RBT_RED && root->parent && root->parent->color == RBT_RED) + { + printf("The red node is adjacent to the red node\n"); + return false; + } + return tree_rb_check_color(self, root->left, black_num, black_num_expected) && + tree_rb_check_color(self, root->right, black_num, black_num_expected); +} + +static bool tree_rb_check(struct _tree* self) +{ + assert(self != NULL); + if(self->_root == NULL) + { + return true; + } + + if(self->_root->color != RBT_BLACK) + { + printf("self->_root->color != RBT_BLACK\n"); + return false; + } + + int black_num_expected = 0; + struct _tree_node* root = self->_root; + while(root) + { + if(root->color == RBT_BLACK) + { + black_num_expected++; + } + root = root->left; + } + return tree_rb_check_color(self, self->_root, 0, black_num_expected); +} + +/** + * @brief + */ +void test_rbtree_num(void) +{ + uint32_t i = 0; + // int data[] = { 2,1,3,4}; + // int data[] = { 1,2,3,4,5,6}; + // int data[] = { 5,2,3,1,7,8,6 }; + int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + tree_t tree = tree_new(); + tree_rb_init(tree, sizeof(int)); + tree->print_obj = print_num; + tree->compare = compare_num; + + printf("\n\n----- demo_rbtree_num -----\n"); + + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + + printf("insert = "); + tree->print_obj(&temp); + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + + if(true != tree_rb_check(tree)) + { + printf("----- rb_check_error -----\n"); + return; + } + } + + printf("----- max -----\n"); + tree->max(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- min -----\n"); + tree->min(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- tree -----\n"); + tree->clear(tree); + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + } + + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + + printf("----- right priority -----\n"); + tree->order(tree, true); + + printf("----- preorder(right) -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder(right) -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder(right) -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth(right) -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + +#if 1 + printf("----- left priority -----\n"); + tree->order(tree, false); + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + for (i = 0; i < len; i++) + { + temp = data[i]; + printf("delete = "); + tree->print_obj(&temp); + + // delete + tree->delete(tree, &temp); + + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + + if(true != tree_rb_check(tree)) + { + printf("----- rb_check_error -----\n"); + return; + } + } + + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } +#endif + tree_free(&tree); +} + +/** + * @brief + */ +void test_rbtree_struct(void) +{ + uint32_t i = 0; + struct _student data[] = { + {"zhao", 1001},{"qian", 1002}, {"sun", 1003}, {"li", 1004}, + "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + }; + struct _student temp = {0}; + uint32_t len = sizeof(data) / sizeof(data[0]); + + tree_t tree = tree_new(); + tree_rb_init(tree, sizeof(struct _student)); + tree->print_obj = print_struct; + tree->compare = compare_struct; + + printf("\n\n----- demo_rbtree_struct -----\n"); + + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + + printf("insert = "); + tree->print_obj(&temp); + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + + if(true != tree_rb_check(tree)) + { + printf("----- rb_check_error -----\n"); + return; + } + } + + printf("----- max -----\n"); + tree->max(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- min -----\n"); + tree->min(tree, &temp); + tree->print_obj(&temp); + printf("\n"); + + printf("----- tree -----\n"); + tree->clear(tree); + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } + printf("----- insert -----\n"); + for (i = 0; i < len; i++) + { + temp = data[i]; + tree->insert(tree, &temp); + } + + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + + printf("----- right priority -----\n"); + tree->order(tree, true); + + printf("----- preorder(right) -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + printf("----- inorder(right) -----\n"); + tree->inorder(tree, tree->_root); + printf("\n"); + + printf("----- postorder(right) -----\n"); + tree->postorder(tree, tree->_root); + printf("\n"); + + printf("----- breadth(right) -----\n"); + tree->breadth(tree, tree->_root); + printf("\n"); + +#if 1 + printf("----- left priority -----\n"); + tree->order(tree, false); + printf("----- preorder -----\n"); + tree->preorder(tree, tree->_root); + printf("\n"); + + for (i = 0; i < len; i++) + { + temp = data[i]; + printf("delete = "); + tree->print_obj(&temp); + + // delete + tree->delete(tree, &temp); + + printf("size = %2d : ", tree->size(tree)); + tree->preorder(tree, tree->_root); + printf("\n"); + + if(true != tree_rb_check(tree)) + { + printf("----- rb_check_error -----\n"); + return; + } + } + + if(tree->empty(tree)) + { + printf("----- empty -----\n"); + } +#endif + tree_free(&tree); +} +#endif + +void test_tree(void) +{ + // RUN_TEST(test_avltree_num); + // RUN_TEST(test_rbtree_num); + // RUN_TEST(test_rbtree_struct); +}