From 8ffde2b60854ca4ba907ed748b69162842094ab7 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Thu, 24 Apr 2025 18:40:22 +0800 Subject: [PATCH] =?UTF-8?q?tree=E7=9A=84=E6=96=B0=E8=BF=AD=E4=BB=A3?= =?UTF-8?q?=E5=99=A8=E5=B7=B2=E7=BB=8F=E5=AE=9E=E7=8E=B0=EF=BC=8C=E4=BD=86?= =?UTF-8?q?=E6=98=AF=E5=8D=A1=E6=AD=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/tree.h | 2 +- src/tree.c | 183 +++++++++++++++++++++++++++++++++++++++++++++-- test/test_tree.c | 36 ++++++++++ 3 files changed, 215 insertions(+), 6 deletions(-) diff --git a/include/tree.h b/include/tree.h index 7a329ca..7c2b063 100644 --- a/include/tree.h +++ b/include/tree.h @@ -93,7 +93,7 @@ struct _tree uint32_t (*size)(struct _tree* self); // iter - iterator_t (*iter)(struct _tree* self); + iterator_t (*iter)(struct _tree* self, enum _order); /** * @brief diff --git a/src/tree.c b/src/tree.c index 08147b6..84ee8a8 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1889,14 +1889,21 @@ static void* tree_end(struct _tree* self) } -iterator_t tree_iter(struct _tree* self) +iterator_t tree_iter(struct _tree* self, enum _order order) { assert(self != NULL); iterator_t iter = &self->_iter; iter->_parent = self; iter->_cur = 0; + iter->_cur_node = self->_root; + + self->cur_node = self->_root; + self->stack->clear(self->stack); + self->queue->clear(self->queue); + + self->_order = order; return iter; } @@ -1922,12 +1929,170 @@ const void* tree_iter_next(struct _iterator* iter) void *obj = NULL; // base on linklist - struct _tree_node * node = (struct _tree_node *)iter->_cur_node; - if(node != NULL) + // struct _tree_node * node = (struct _tree_node *)iter->_cur_node; + // if(node != NULL) + // { + // obj = node->obj; + // // iter->_cur_node = node->next; + // } + + switch (self->_order) { - obj = node->obj; - // iter->_cur_node = node->next; + case ORDER_LEFT_PRE: + case ORDER_RIGHT_PRE: + { + struct _tree_node* node = NULL; + if (self->_order == ORDER_LEFT_PRE) + { + while (!self->stack->empty(self->stack) || self->cur_node != NULL) + { + if (self->cur_node != NULL) + { + node = self->cur_node; + + self->stack->push(self->stack, &self->cur_node); + self->cur_node = self->cur_node->left; + + break; + } + else + { + self->stack->pop(self->stack, &self->cur_node); + self->cur_node = self->cur_node->right; + } + } + } + else + { + while (!self->stack->empty(self->stack) || self->cur_node != NULL) + { + if (self->cur_node != NULL) + { + node = self->cur_node; + + self->stack->push(self->stack, &self->cur_node); + self->cur_node = self->cur_node->right; + + break; + } + else + { + self->stack->pop(self->stack, &self->cur_node); + self->cur_node = self->cur_node->left; + } + } + } + + if (node == NULL) + { + return NULL; + } + return node->obj; + }break; + case ORDER_LEFT_IN: + case ORDER_RIGHT_IN: + { + struct _tree_node* node = NULL; + if (self->_order == ORDER_LEFT_IN) + { + while (!self->stack->empty(self->stack) || self->cur_node != NULL) + { + if (self->cur_node != NULL) + { + self->stack->push(self->stack, &self->cur_node); + self->cur_node = self->cur_node->left; + } + else + { + self->stack->pop(self->stack, &self->cur_node); + + node = self->cur_node; + self->cur_node = self->cur_node->right; + break; + } + } + } + else + { + while (!self->stack->empty(self->stack) || self->cur_node != NULL) + { + if (self->cur_node != NULL) + { + self->stack->push(self->stack, &self->cur_node); + self->cur_node = self->cur_node->right; + } + else + { + self->stack->pop(self->stack, &self->cur_node); + + node = self->cur_node; + self->cur_node = self->cur_node->left; + break; + } + } + } + if (node == NULL) + { + return NULL; + } + return node->obj; + }break; + case ORDER_LEFT_POST: + case ORDER_RIGHT_POST: + { + if (!self->stack->empty(self->stack)) + { + self->stack->pop(self->stack, &self->cur_node); + } + else + { + self->cur_node = NULL; + } + return self->cur_node == NULL ? NULL : self->cur_node->obj; + }break; + case ORDER_LEFT_BREADTH: + case ORDER_RIGHT_BREADTH: + { + struct _tree_node* node = self->cur_node; + queue_t queue = self->queue; + if (!queue->empty(queue) && node != NULL) + { + queue->pop(queue, &node); + if (self->_order == ORDER_LEFT_BREADTH) + { + if (node->left != NULL) + { + queue->push(queue, &node->left); + } + if (node->right != NULL) + { + queue->push(queue, &node->right); + } + } + else + { + if (node->right != NULL) + { + queue->push(queue, &node->right); + } + if (node->left != NULL) + { + queue->push(queue, &node->left); + } + } + self->cur_node = node; + } + else + { + self->cur_node = NULL; + } + return self->cur_node == NULL ? NULL : self->cur_node->obj; + }break; + default: + { + }break; } + self->_iter._cur += 1; return obj; } @@ -1983,6 +2148,10 @@ static bool tree_avl_init(struct _tree* self, uint32_t obj_size) } self->cur_node = NULL; + self->_iter.hasnext = tree_iter_hasnext; + self->_iter.next = tree_iter_next; + self->iter = tree_iter; + return true; done1: stack_free(&self->stack); @@ -2042,6 +2211,10 @@ static bool tree_rb_init(struct _tree* self, uint32_t obj_size) } self->cur_node = NULL; + self->_iter.hasnext = tree_iter_hasnext; + self->_iter.next = tree_iter_next; + self->iter = tree_iter; + return true; done1: stack_free(&self->stack); diff --git a/test/test_tree.c b/test/test_tree.c index 18ff8a5..6a67e6f 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -904,6 +904,40 @@ static void test_rbtree_delete(void) } +static void test_avltree_iter_2(void) +{ + uint32_t i = 0; + int data[15] = { 5, 2, 3, 1, 7, 8, 6, 4, 9, 10, 12, 11, 15, 14, 13, }; + int buff[32]; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + // int * iter = NULL; + int count = 0; + + tree_t tree = tree_avl_new(sizeof(int)); + TEST_ASSERT_NOT_NULL(tree); + tree->print_obj = print_num; + tree->compare = compare_num; + + for (i = 0; i < len; i++) + { + temp = data[i]; + TEST_ASSERT_TRUE(tree->insert(tree, &temp)); + } + + iterator_t iter = tree->iter(tree, ORDER_LEFT_PRE); + while(iter->hasnext(iter)) + { + temp = *(int *)iter->next(iter); + tree->print_obj(&temp); + } + + TEST_ASSERT_TRUE(tree->clear(tree)); + tree_free(&tree); + TEST_ASSERT_NULL(tree); +} + void test_tree(void) { UnitySetTestFile(__FILE__); @@ -919,4 +953,6 @@ void test_tree(void) // RUN_TEST(test_avltree_num); // RUN_TEST(test_rbtree_num); // RUN_TEST(test_rbtree_struct); + + RUN_TEST(test_avltree_iter_2); }