diff --git a/include/tree.h b/include/tree.h index b7d2c9c..28859a6 100644 --- a/include/tree.h +++ b/include/tree.h @@ -13,11 +13,32 @@ #include "common.h" +#include "stack.h" +#include "queue.h" + + typedef enum { RBT_RED = 0x00, RBT_BLACK = 0x01, }rbt_color; +enum _order{ + ORDER_LEFT_PRE = 0x00, + ORDER_LEFT_IN = 0x01, + ORDER_LEFT_POST = 0x02, + ORDER_LEFT_BREADTH = 0x03, + + ORDER_RIGHT_PRE = 0x04, + ORDER_RIGHT_IN = 0x05, + ORDER_RIGHT_POST = 0x06, + ORDER_RIGHT_BREADTH = 0x07, + + ORDER_PRE = ORDER_LEFT_PRE, + ORDER_IN = ORDER_LEFT_IN, + ORDER_POST = ORDER_LEFT_POST, + ORDER_BREADTH = ORDER_LEFT_BREADTH, +}; + struct _tree_node { void *obj; @@ -41,8 +62,13 @@ struct _tree uint32_t _capacity; uint32_t _ratio; + enum _order _order; bool _right_priority; + stack_t stack; + queue_t queue; + struct _tree_node * cur_node; + // kernel bool (*insert)(struct _tree* self, void* obj); bool (*delete)(struct _tree* self, void* obj); @@ -57,10 +83,21 @@ struct _tree bool (*min)(struct _tree* self, void* obj); bool (*max)(struct _tree* self, void* obj); + // base bool (*clear)(struct _tree* self); bool (*empty)(struct _tree* self); uint32_t (*size)(struct _tree* self); + // iter + /** + * @brief + * + */ + void (*set_order)(struct _tree* self, enum _order order); + void* (*begin)(struct _tree* self); + void* (*next)(struct _tree* self); + void* (*end)(struct _tree* self); + /** * @brief obj compare with obj2 * diff --git a/src/tree.c b/src/tree.c index 51a2e84..6544a0c 100644 --- a/src/tree.c +++ b/src/tree.c @@ -611,6 +611,15 @@ void tree_destory(struct _tree* self) assert(self != NULL); self->clear(self); self->_root = NULL; + + if(self->stack != NULL) + { + stack_free(&self->stack); + } + if(self->queue != NULL) + { + queue_free(&self->queue); + } } void tree_order(struct _tree* self, bool right_priority) @@ -1013,40 +1022,7 @@ bool tree_max(struct _tree* self, void* obj) return true; } -bool tree_avl_init(struct _tree *self, uint32_t obj_size) -{ - assert(self != NULL); - self->_obj_size = obj_size; - self->_size = 0; - // self->_capacity = 64; - // self->_ratio = 2; - - self->_right_priority = false; - - self->insert = tree_avl_insert; - self->delete = tree_avl_delete; - self->clear = tree_clear; - self->empty = tree_empty; - self->size = tree_size; - self->destory = tree_destory; - self->preorder = tree_preorder; - self->inorder = tree_inorder; - self->postorder = tree_postorder; - self->breadth = tree_breadth; - self->order = tree_order; - self->find = tree_find; - self->height = tree_height; - self->rebalance = tree_avl_rebalance; - self->find_max = tree_find_max; - self->find_min = tree_find_min; - self->max = tree_max; - self->min = tree_min; - - self->_root = NULL; - - return true; -} rbt_color tree_color(struct _tree_node* node) { @@ -1493,6 +1469,234 @@ bool tree_rb_delete(struct _tree* self, void* obj) return true; } +void tree_set_order(struct _tree* self, enum _order order) +{ + assert(self != NULL); + self->_order = order; +} + +void* tree_begin(struct _tree* self) +{ + assert(self != NULL); + switch (self->_order) + { + case ORDER_LEFT_PRE: + { + struct _tree_node* node = NULL; + + self->cur_node = self->_root; + if(!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); + } + else + { + self->stack->pop(self->stack, &self->cur_node); + self->cur_node = self->cur_node->right; + } + } + return node; + }break; + case ORDER_LEFT_IN: + { + + }break; + case ORDER_LEFT_POST: + { + + }break; + case ORDER_LEFT_BREADTH: + { + + }break; + case ORDER_RIGHT_PRE: + { + + }break; + case ORDER_RIGHT_IN: + { + + }break; + case ORDER_RIGHT_POST: + { + + }break; + case ORDER_RIGHT_BREADTH: + { + + }break; + default: + { + }break; + } +} + +void* tree_next(struct _tree* self) +{ + assert(self != NULL); + switch (self->_order) + { + case ORDER_LEFT_PRE: + { + struct _tree_node* node = NULL; + if(!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); + } + else + { + self->stack->pop(self->stack, &self->cur_node); + self->cur_node = self->cur_node->right; + } + } + return node; + }break; + case ORDER_LEFT_IN: + { + + }break; + case ORDER_LEFT_POST: + { + + }break; + case ORDER_LEFT_BREADTH: + { + + }break; + case ORDER_RIGHT_PRE: + { + + }break; + case ORDER_RIGHT_IN: + { + + }break; + case ORDER_RIGHT_POST: + { + + }break; + case ORDER_RIGHT_BREADTH: + { + + }break; + default: + { + }break; + } +} + +void* tree_end(struct _tree* self) +{ + assert(self != NULL); + switch (self->_order) + { + case ORDER_LEFT_PRE: + { + struct _tree_node* node = NULL; + return node; + }break; + case ORDER_LEFT_IN: + { + + }break; + case ORDER_LEFT_POST: + { + + }break; + case ORDER_LEFT_BREADTH: + { + + }break; + case ORDER_RIGHT_PRE: + { + + }break; + case ORDER_RIGHT_IN: + { + + }break; + case ORDER_RIGHT_POST: + { + + }break; + case ORDER_RIGHT_BREADTH: + { + + }break; + default: + { + }break; + } +} + + + +bool tree_avl_init(struct _tree *self, uint32_t obj_size) +{ + assert(self != NULL); + + self->_obj_size = obj_size; + self->_size = 0; + // self->_capacity = 64; + // self->_ratio = 2; + + self->_right_priority = false; + + self->insert = tree_avl_insert; + self->delete = tree_avl_delete; + self->clear = tree_clear; + self->empty = tree_empty; + self->size = tree_size; + self->destory = tree_destory; + self->preorder = tree_preorder; + self->inorder = tree_inorder; + self->postorder = tree_postorder; + self->breadth = tree_breadth; + self->order = tree_order; + self->find = tree_find; + self->height = tree_height; + self->rebalance = tree_avl_rebalance; + self->find_max = tree_find_max; + self->find_min = tree_find_min; + self->max = tree_max; + self->min = tree_min; + + self->set_order = tree_set_order; + self->begin = tree_begin; + self->next = tree_next; + self->end = tree_end; + + self->_root = NULL; + + self->stack = stack_new(); + if(self->stack == NULL) + { + goto done; + } + stack_init(self->stack, sizeof(struct _tree_node*)); + self->queue = queue_new(); + if(self->queue == NULL) + { + goto done1; + } + queue_init(self->queue, sizeof(struct _tree_node*)); + self->cur_node = NULL; + + return true; +done1: + stack_free(&self->stack); +done: + return false; + + return true; +} + bool tree_rb_init(struct _tree *self, uint32_t obj_size) { assert(self != NULL); @@ -1502,6 +1706,7 @@ bool tree_rb_init(struct _tree *self, uint32_t obj_size) // self->_ratio = 2; self->_right_priority = false; + self->_order = ORDER_PRE; self->insert = tree_rb_insert; self->delete = tree_rb_delete; @@ -1523,8 +1728,32 @@ bool tree_rb_init(struct _tree *self, uint32_t obj_size) self->max = tree_max; self->min = tree_min; + self->set_order = tree_set_order; + self->begin = tree_begin; + self->next = tree_next; + self->end = tree_end; + self->_root = NULL; + + self->stack = stack_new(); + if(self->stack == NULL) + { + goto done; + } + stack_init(self->stack, sizeof(struct _tree_node*)); + self->queue = queue_new(); + if(self->queue == NULL) + { + goto done1; + } + queue_init(self->queue, sizeof(struct _tree_node*)); + self->cur_node = NULL; + return true; +done1: + stack_free(&self->stack); +done: + return false; } tree_t tree_new(void) diff --git a/test/test_tree.c b/test/test_tree.c index e555afc..217a292 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -463,9 +463,58 @@ void test_rbtree_struct(void) } #endif + +static void test_tree_iter(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 buff[32]; + int count = 0; + 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; + + 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"); + } + + int * iter = NULL; + for(iter = tree->begin(tree); iter != tree->end(tree); iter = tree->next(tree)) + { + printf("%d ", *iter); + + buff[count++] = *iter; + } + TEST_ASSERT_EQUAL_INT_ARRAY(data, buff, count); + + TEST_ASSERT_FALSE(tree->empty(tree)); + TEST_ASSERT_TRUE(tree->clear(tree)); + TEST_ASSERT_TRUE(tree->empty(tree)); + TEST_ASSERT_TRUE(tree->clear(tree)); + tree_free(&tree); + TEST_ASSERT_NULL(tree); +} + void test_tree(void) { // RUN_TEST(test_avltree_num); // RUN_TEST(test_rbtree_num); // RUN_TEST(test_rbtree_struct); + + RUN_TEST(test_tree_iter); }