mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-05-17 19:41:36 +08:00
Compare commits
10 Commits
932b078778
...
eb918955f5
Author | SHA1 | Date | |
---|---|---|---|
eb918955f5 | |||
4aa966bb93 | |||
c70b007386 | |||
4691b848ef | |||
1982a90a3e | |||
d278ef008f | |||
7b672b6e77 | |||
6054e712e6 | |||
7a7af3152a | |||
59e5c9be71 |
@ -16,10 +16,10 @@
|
||||
struct _iterator
|
||||
{
|
||||
// ---------- private ----------
|
||||
void* _parent;
|
||||
void* _cur_node;
|
||||
uint32_t _cur;
|
||||
void* _container; // pointer to stack/queue/tree ...
|
||||
|
||||
void* _node; // current node
|
||||
uint32_t _index; // current index
|
||||
uint32_t _order;
|
||||
|
||||
// ---------- public ----------
|
||||
|
@ -22,29 +22,17 @@ typedef enum {
|
||||
RBT_BLACK,
|
||||
}rbt_color;
|
||||
|
||||
/**
|
||||
* @brief dfs amd bfs traversal order
|
||||
*
|
||||
* pre-order traversal
|
||||
* in-order traversal
|
||||
* post-order traversal
|
||||
* breadth-first search traversal [BFS]
|
||||
*
|
||||
* right-first pre-order traversal
|
||||
* right-first in-order traversal
|
||||
* right-first post-order traversal
|
||||
* breadth-first search traversal [BFS]
|
||||
*/
|
||||
enum _order{
|
||||
ORDER_PRE,
|
||||
ORDER_IN,
|
||||
ORDER_POST,
|
||||
ORDER_BREADTH,
|
||||
// dfs and bfs traversal order
|
||||
enum _tree_order{
|
||||
ORDER_PRE, // pre-order
|
||||
ORDER_IN, // in-order
|
||||
ORDER_POST, // post-order
|
||||
ORDER_BREADTH, // breadth-first search [BFS]
|
||||
|
||||
ORDER_PRE_R,
|
||||
ORDER_IN_R,
|
||||
ORDER_POST_R,
|
||||
ORDER_BREADTH_R,
|
||||
ORDER_PRE_R, // right-first pre-order
|
||||
ORDER_IN_R, // right-first in-order
|
||||
ORDER_POST_R, // right-first post-order
|
||||
ORDER_BREADTH_R,// right-first breadth-first search [BFS]
|
||||
};
|
||||
|
||||
struct _tree_node
|
||||
@ -71,22 +59,19 @@ struct _tree
|
||||
uint32_t _capacity;
|
||||
uint32_t _ratio;
|
||||
|
||||
enum _order _order;
|
||||
bool _right_priority;
|
||||
|
||||
stack_t stack;
|
||||
queue_t queue;
|
||||
|
||||
struct _iterator _iter;
|
||||
|
||||
bool (*_rebalance)(struct _tree* self, struct _tree_node* root);
|
||||
void (*_destory)(struct _tree* self);
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
bool (*insert)(struct _tree* self, void* obj);
|
||||
bool (*delete)(struct _tree* self, void* obj);
|
||||
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
|
||||
int32_t (*height)(struct _tree* self, struct _tree_node* root);
|
||||
uint32_t (*height)(struct _tree* self);
|
||||
|
||||
// base
|
||||
bool (*clear)(struct _tree* self);
|
||||
@ -94,7 +79,7 @@ struct _tree
|
||||
uint32_t (*size)(struct _tree* self);
|
||||
|
||||
// iter
|
||||
iterator_t (*iter)(struct _tree* self, enum _order);
|
||||
iterator_t (*iter)(struct _tree* self, enum _tree_order);
|
||||
|
||||
// others
|
||||
bool (*min)(struct _tree* self, void* obj);
|
||||
|
58
src/deque.c
58
src/deque.c
@ -295,32 +295,13 @@ static void deque_print(struct _deque* self)
|
||||
}
|
||||
}
|
||||
|
||||
iterator_t deque_iter(struct _deque* self, enum _deque_order order)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_parent = self;
|
||||
iter->_cur = 0;
|
||||
iter->_order = order;
|
||||
if(iter->_order == DEQUE_FORWARD)
|
||||
{
|
||||
iter->_cur_node = self->_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_cur_node = self->_tail;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool deque_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_parent;
|
||||
if(iter->_cur < self->size(self))
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -332,10 +313,10 @@ const void* deque_iter_next(struct _iterator* iter)
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_parent;
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
struct _deque_node * cur_node = (struct _deque_node *)iter->_cur_node;
|
||||
struct _deque_node * cur_node = (struct _deque_node *)iter->_node;
|
||||
if(cur_node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
@ -344,17 +325,39 @@ const void* deque_iter_next(struct _iterator* iter)
|
||||
obj = cur_node->obj;
|
||||
if(iter->_order == DEQUE_FORWARD)
|
||||
{
|
||||
iter->_cur_node = cur_node->next;
|
||||
iter->_node = cur_node->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_cur_node = cur_node->prev;
|
||||
iter->_node = cur_node->prev;
|
||||
}
|
||||
|
||||
self->_iter._cur += 1;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
iterator_t deque_iter(struct _deque* self, enum _deque_order order)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_order = order;
|
||||
if(iter->_order == DEQUE_FORWARD)
|
||||
{
|
||||
iter->_node = self->_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_node = self->_tail;
|
||||
}
|
||||
|
||||
iter->hasnext = deque_iter_hasnext;
|
||||
iter->next = deque_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool deque_init(struct _deque* self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -371,9 +374,6 @@ static bool deque_init(struct _deque* self, uint32_t obj_size)
|
||||
self->_head = NULL;
|
||||
self->_tail = NULL;
|
||||
|
||||
self->_iter.hasnext = deque_iter_hasnext;
|
||||
self->_iter.next = deque_iter_next;
|
||||
|
||||
self->_destory = deque_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
|
116
src/graph.c
116
src/graph.c
@ -822,59 +822,13 @@ static struct _graph_node * graph_find_next_unvisited_target(struct _graph *self
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iterator_t graph_iter(struct _graph *self, enum _graph_search search_type, void *start)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_parent = self;
|
||||
iter->_cur = 0;
|
||||
iter->_cur_node = self->_head->next;
|
||||
|
||||
struct _graph_node *start_node = find_node(self, start);
|
||||
if (start_node == NULL)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
iter->_cur_node = start_node;
|
||||
|
||||
struct _graph_node *node = self->_head->next;
|
||||
while (node != NULL)
|
||||
{
|
||||
node->visited = false;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
self->_search = search_type;
|
||||
switch (self->_search)
|
||||
{
|
||||
case GRAPH_BFS:
|
||||
{
|
||||
self->queue->push(self->queue, &iter->_cur_node);
|
||||
}
|
||||
break;
|
||||
case GRAPH_DFS:
|
||||
{
|
||||
// pass
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool graph_iter_hasnext(struct _iterator *iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
graph_t self = (graph_t)iter->_parent;
|
||||
if (iter->_cur < self->size(self))
|
||||
graph_t self = (graph_t)iter->_container;
|
||||
if (iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -885,16 +839,15 @@ const void *graph_iter_next(struct _iterator *iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
graph_t self = (graph_t)iter->_parent;
|
||||
graph_t self = (graph_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
iter->_cur += 1;
|
||||
iter->_index += 1;
|
||||
switch (self->_search)
|
||||
{
|
||||
case GRAPH_BFS:
|
||||
{
|
||||
struct _graph_node *cur_node = iter->_cur_node;
|
||||
struct _graph_node *cur_node = iter->_node;
|
||||
struct _graph_edge *cur_edge = cur_node->edgehead;
|
||||
struct _graph_node *target = NULL;
|
||||
struct _graph_node *node = cur_node;
|
||||
@ -933,14 +886,13 @@ const void *graph_iter_next(struct _iterator *iter)
|
||||
cur_node = node;
|
||||
}
|
||||
|
||||
iter->_cur_node = cur_node;
|
||||
iter->_node = cur_node;
|
||||
obj = cur_node->obj;
|
||||
}
|
||||
break;
|
||||
case GRAPH_DFS:
|
||||
{
|
||||
// self->stack->push(self->stack, iter->_cur_node);
|
||||
struct _graph_node *cur_node = self->_iter._cur_node;
|
||||
struct _graph_node *cur_node = iter->_node;
|
||||
struct _graph_node *node = NULL;
|
||||
|
||||
stack_t stack = self->stack;
|
||||
@ -976,7 +928,7 @@ const void *graph_iter_next(struct _iterator *iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
iter->_cur_node = cur_node;
|
||||
iter->_node = cur_node;
|
||||
obj = node->obj;
|
||||
}
|
||||
break;
|
||||
@ -989,6 +941,55 @@ const void *graph_iter_next(struct _iterator *iter)
|
||||
return obj;
|
||||
}
|
||||
|
||||
iterator_t graph_iter(struct _graph *self, enum _graph_search search_type, void *start)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
// iter->_node = self->_head->next;
|
||||
|
||||
struct _graph_node *start_node = find_node(self, start);
|
||||
if (start_node == NULL)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
iter->_node = start_node;
|
||||
|
||||
iter->hasnext = graph_iter_hasnext;
|
||||
iter->next = graph_iter_next;
|
||||
|
||||
struct _graph_node *node = self->_head->next;
|
||||
while (node != NULL)
|
||||
{
|
||||
node->visited = false;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
self->_search = search_type;
|
||||
switch (self->_search)
|
||||
{
|
||||
case GRAPH_BFS:
|
||||
{
|
||||
self->queue->push(self->queue, &iter->_node);
|
||||
}
|
||||
break;
|
||||
case GRAPH_DFS:
|
||||
{
|
||||
// pass
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool graph_init(struct _graph *self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -1030,9 +1031,6 @@ static bool graph_init(struct _graph *self, uint32_t obj_size)
|
||||
self->_type = GRAPH_UNDIRECTED;
|
||||
// self->_type = GRAPH_DIRECTED;
|
||||
|
||||
self->_iter.hasnext = graph_iter_hasnext;
|
||||
self->_iter.next = graph_iter_next;
|
||||
|
||||
self->_destory = graph_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
|
39
src/heap.c
39
src/heap.c
@ -249,25 +249,13 @@ static void heap_print(struct _heap* self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
iterator_t heap_iter(struct _heap* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_parent = self;
|
||||
iter->_cur = 0;
|
||||
iter->_cur_node = self->obj;
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool heap_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
heap_t self = (heap_t)iter->_parent;
|
||||
if(iter->_cur < self->size(self))
|
||||
heap_t self = (heap_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -279,16 +267,30 @@ const void* heap_iter_next(struct _iterator* iter)
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
heap_t self = (heap_t)iter->_parent;
|
||||
heap_t self = (heap_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
uint32_t index = self->_iter._cur;
|
||||
uint32_t index = iter->_index;
|
||||
obj = self->obj + self->_obj_size * index;
|
||||
|
||||
self->_iter._cur += 1;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
iterator_t heap_iter(struct _heap* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_node = self->obj;
|
||||
|
||||
iter->hasnext = heap_iter_hasnext;
|
||||
iter->next = heap_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -305,9 +307,6 @@ static bool heap_init2(struct _heap* self, uint32_t obj_size, uint32_t capacity)
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_iter.hasnext = heap_iter_hasnext;
|
||||
self->_iter.next = heap_iter_next;
|
||||
|
||||
self->_destory = heap_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
|
32
src/list.c
32
src/list.c
@ -179,30 +179,36 @@ static void list_print(struct _list* self)
|
||||
}
|
||||
}
|
||||
|
||||
static const void* list_iter_next(struct _iterator* iter)
|
||||
{
|
||||
list_t self = (list_t)iter->_parent;
|
||||
void *obj = self->obj + self->_iter._cur * self->_obj_size;
|
||||
self->_iter._cur += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bool list_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
list_t self = (list_t)iter->_parent;
|
||||
list_t self = (list_t)iter->_container;
|
||||
|
||||
if(self->_iter._cur < self->size(self))
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const void* list_iter_next(struct _iterator* iter)
|
||||
{
|
||||
list_t self = (list_t)iter->_container;
|
||||
void *obj = self->obj + iter->_index * self->_obj_size;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
iterator_t list_iter(struct _list* self)
|
||||
{
|
||||
self->_iter._parent = self;
|
||||
self->_iter._cur = 0;
|
||||
return &self->_iter;
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
|
||||
iter->hasnext = list_iter_hasnext;
|
||||
iter->next = list_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
|
63
src/queue.c
63
src/queue.c
@ -306,24 +306,13 @@ static void queue2_print(struct _queue* self)
|
||||
}
|
||||
}
|
||||
|
||||
static iterator_t queue_iter(struct _queue* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_parent = self;
|
||||
iter->_cur = 0;
|
||||
iter->_cur_node = self->_front;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool queue_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_parent;
|
||||
if(iter->_cur < self->size(self))
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -335,36 +324,64 @@ static const void* queue_iter_next(struct _iterator* iter)
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_parent;
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
// base on linklist
|
||||
struct _queue_node * node = (struct _queue_node *)iter->_cur_node;
|
||||
struct _queue_node * node = (struct _queue_node *)iter->_node;
|
||||
if(node != NULL)
|
||||
{
|
||||
obj = node->obj;
|
||||
iter->_cur_node = node->next;
|
||||
iter->_node = node->next;
|
||||
}
|
||||
self->_iter._cur += 1;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static iterator_t queue_iter(struct _queue* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_node = self->_front;
|
||||
|
||||
iter->hasnext = queue_iter_hasnext;
|
||||
iter->next = queue_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static const void* queue2_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_parent;
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
// base on array
|
||||
uint32_t index = self->_iter._cur;
|
||||
uint32_t index = iter->_index;
|
||||
obj = self->_front->obj + self->_obj_size * index;
|
||||
|
||||
self->_iter._cur += 1;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static iterator_t queue2_iter(struct _queue* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_node = self->_front;
|
||||
|
||||
iter->hasnext = queue_iter_hasnext;
|
||||
iter->next = queue2_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -387,10 +404,6 @@ static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||
// base
|
||||
self->_destory = queue_destory;
|
||||
|
||||
// iter
|
||||
self->_iter.hasnext = queue_iter_hasnext;
|
||||
self->_iter.next = queue_iter_next;
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
self->push = queue_push;
|
||||
@ -471,7 +484,7 @@ static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capaci
|
||||
self->clear = queue2_clear;
|
||||
|
||||
// iter
|
||||
self->iter = queue_iter;
|
||||
self->iter = queue2_iter;
|
||||
|
||||
// -------------------- debug --------------------
|
||||
self->print = queue2_print;
|
||||
|
90
src/stack.c
90
src/stack.c
@ -254,63 +254,64 @@ static void stack2_print(struct _stack* self)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iterator next
|
||||
* from top to bottom
|
||||
*
|
||||
* @param iter
|
||||
* @return const void*
|
||||
* the value of return is const, so you can't modify it.
|
||||
*/
|
||||
const void* stack_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
stack_t self = (stack_t)iter->_parent;
|
||||
void *obj = NULL;
|
||||
|
||||
if(self->_head->obj == NULL)
|
||||
{
|
||||
// base on linklist
|
||||
struct _stack_node* node = (struct _stack_node *)self->_iter._cur_node;
|
||||
if(node != NULL)
|
||||
{
|
||||
obj = node->obj;
|
||||
self->_iter._cur_node = node->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// base on array
|
||||
uint32_t index = self->size(self) - 1 - self->_iter._cur;
|
||||
obj = self->_head->obj + self->_obj_size * index;
|
||||
}
|
||||
|
||||
self->_iter._cur += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool stack_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
stack_t self = (stack_t)iter->_parent;
|
||||
if(self->_iter._cur < self->size(self))
|
||||
stack_t self = (stack_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iter next
|
||||
* from top to bottom
|
||||
*/
|
||||
const void* stack_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
stack_t self = (stack_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
if(self->_head->obj == NULL)
|
||||
{
|
||||
// base on linklist
|
||||
struct _stack_node* node = (struct _stack_node *)iter->_node;
|
||||
if(node != NULL)
|
||||
{
|
||||
obj = node->obj;
|
||||
iter->_node = node->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// base on array
|
||||
uint32_t index = self->size(self) - 1 - iter->_index;
|
||||
obj = self->_head->obj + self->_obj_size * index;
|
||||
}
|
||||
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
iterator_t stack_iter(struct _stack* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
self->_iter._parent = self;
|
||||
self->_iter._cur = 0;
|
||||
self->_iter._cur_node = self->_head->next;
|
||||
return &self->_iter;
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_node = self->_head->next;
|
||||
|
||||
iter->hasnext = stack_iter_hasnext;
|
||||
iter->next = stack_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool stack_init(struct _stack* self, uint32_t obj_size)
|
||||
@ -336,9 +337,6 @@ static bool stack_init(struct _stack* self, uint32_t obj_size)
|
||||
self->_head->obj = NULL;
|
||||
self->_head->next = NULL;
|
||||
|
||||
self->_iter.next = stack_iter_next;
|
||||
self->_iter.hasnext = stack_iter_hasnext;
|
||||
|
||||
self->_destory = stack_destory;
|
||||
|
||||
// ---------- public ----------
|
||||
|
515
src/tree.c
515
src/tree.c
@ -12,6 +12,60 @@
|
||||
#include "queue.h"
|
||||
#include "stack.h"
|
||||
|
||||
|
||||
static uint32_t tree_height_node(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
#if 0
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t left_height = tree_height_node(self, root->left);
|
||||
uint32_t right_height = tree_height_node(self, root->right);
|
||||
return (left_height > right_height) ? (left_height + 1) : (right_height + 1);
|
||||
#else
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t height = 0;
|
||||
uint32_t count_cur_level = 0;
|
||||
uint32_t count_next_level = 0;
|
||||
|
||||
struct _tree_node* node = root;
|
||||
queue_t queue = queue_new(sizeof(struct _tree_node*));
|
||||
|
||||
queue->push(queue, &node);
|
||||
while (!queue->empty(queue))
|
||||
{
|
||||
queue->pop(queue, &node);
|
||||
if (node->left != NULL)
|
||||
{
|
||||
queue->push(queue, &node->left);
|
||||
}
|
||||
if (node->right != NULL)
|
||||
{
|
||||
queue->push(queue, &node->right);
|
||||
}
|
||||
|
||||
if (count_cur_level == count_next_level)
|
||||
{
|
||||
count_next_level = queue->size(queue);
|
||||
height++;
|
||||
count_cur_level = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count_cur_level++;
|
||||
}
|
||||
}
|
||||
queue_free(&queue);
|
||||
return height;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tree_set_balance(struct _tree* self, struct _tree_node* node)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -19,7 +73,7 @@ static void tree_set_balance(struct _tree* self, struct _tree_node* node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
node->balance = self->height(self, node->right) - self->height(self, node->left);
|
||||
node->balance = (int32_t)(tree_height_node(self, node->right) - tree_height_node(self, node->left));
|
||||
}
|
||||
|
||||
static struct _tree_node* tree_turn_left(struct _tree* self, struct _tree_node* root)
|
||||
@ -128,59 +182,6 @@ static struct _tree_node* tree_turn_right_then_left(struct _tree* self, struct _
|
||||
return node;
|
||||
}
|
||||
|
||||
static int32_t tree_height(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
#if 0
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t left_height = tree_height(self, root->left);
|
||||
int32_t right_height = tree_height(self, root->right);
|
||||
return (left_height > right_height) ? (left_height + 1) : (right_height + 1);
|
||||
#else
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t height = 0;
|
||||
int32_t count_cur_level = 0;
|
||||
int32_t count_next_level = 0;
|
||||
|
||||
struct _tree_node* node = root;
|
||||
queue_t queue = queue_new(sizeof(struct _tree_node*));
|
||||
|
||||
queue->push(queue, &node);
|
||||
while (!queue->empty(queue))
|
||||
{
|
||||
queue->pop(queue, &node);
|
||||
if (node->left != NULL)
|
||||
{
|
||||
queue->push(queue, &node->left);
|
||||
}
|
||||
if (node->right != NULL)
|
||||
{
|
||||
queue->push(queue, &node->right);
|
||||
}
|
||||
|
||||
if (count_cur_level == count_next_level)
|
||||
{
|
||||
count_next_level = queue->size(queue);
|
||||
height++;
|
||||
count_cur_level = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count_cur_level++;
|
||||
}
|
||||
}
|
||||
queue_free(&queue);
|
||||
return height;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
@ -502,7 +503,7 @@ static bool tree_avl_insert(struct _tree* self, void* obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
self->rebalance(self, root);
|
||||
self->_rebalance(self, root);
|
||||
}
|
||||
self->_size++;
|
||||
return true;
|
||||
@ -567,7 +568,7 @@ static bool tree_avl_delete_single_child(struct _tree* self, struct _tree_node*
|
||||
}
|
||||
}
|
||||
|
||||
self->rebalance(self, node->parent);
|
||||
self->_rebalance(self, node->parent);
|
||||
}
|
||||
tree_node_free(node);
|
||||
return true;
|
||||
@ -833,7 +834,7 @@ static bool tree_rb_insert(struct _tree* self, void* obj)
|
||||
|
||||
}
|
||||
|
||||
self->rebalance(self, node);
|
||||
self->_rebalance(self, node);
|
||||
|
||||
self->_size++;
|
||||
return true;
|
||||
@ -1150,20 +1151,191 @@ static bool tree_rb_delete(struct _tree* self, void* obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
static iterator_t tree_iter(struct _tree* self, enum _order order)
|
||||
static uint32_t tree_height(struct _tree* self)
|
||||
{
|
||||
return tree_height_node(self, self->_root);
|
||||
}
|
||||
|
||||
static bool tree_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const void* tree_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
struct _tree_node* cur_node = iter->_node;
|
||||
struct _tree_node* target_node = NULL;
|
||||
switch (iter->_order)
|
||||
{
|
||||
case ORDER_PRE:
|
||||
case ORDER_PRE_R:
|
||||
{
|
||||
struct _tree_node* node = NULL;
|
||||
if (iter->_order == ORDER_PRE)
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
target_node = cur_node;
|
||||
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
target_node = cur_node;
|
||||
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case ORDER_IN:
|
||||
case ORDER_IN_R:
|
||||
{
|
||||
if (iter->_order == ORDER_IN)
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
target_node = cur_node;
|
||||
|
||||
cur_node = cur_node->right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
target_node = cur_node;
|
||||
|
||||
cur_node = cur_node->left;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case ORDER_POST:
|
||||
case ORDER_POST_R:
|
||||
{
|
||||
if (!self->stack->empty(self->stack))
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
target_node = cur_node;
|
||||
}
|
||||
}break;
|
||||
case ORDER_BREADTH:
|
||||
case ORDER_BREADTH_R:
|
||||
{
|
||||
queue_t queue = self->queue;
|
||||
if (!queue->empty(queue) && cur_node != NULL)
|
||||
{
|
||||
queue->pop(queue, &cur_node);
|
||||
target_node = cur_node;
|
||||
|
||||
if (iter->_order == ORDER_BREADTH)
|
||||
{
|
||||
if (cur_node->left != NULL)
|
||||
{
|
||||
queue->push(queue, &cur_node->left);
|
||||
}
|
||||
if (cur_node->right != NULL)
|
||||
{
|
||||
queue->push(queue, &cur_node->right);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur_node->right != NULL)
|
||||
{
|
||||
queue->push(queue, &cur_node->right);
|
||||
}
|
||||
if (cur_node->left != NULL)
|
||||
{
|
||||
queue->push(queue, &cur_node->left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
}break;
|
||||
}
|
||||
|
||||
iter->_node = cur_node;
|
||||
obj = target_node->obj;
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
static iterator_t tree_iter(struct _tree* self, enum _tree_order order)
|
||||
{
|
||||
assert(self != NULL);
|
||||
iterator_t iter = &self->_iter;
|
||||
|
||||
iter->_parent = self;
|
||||
iter->_cur = 0;
|
||||
iter->_cur_node = self->_root;
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_node = self->_root;
|
||||
iter->_order = order;
|
||||
iter->hasnext = tree_iter_hasnext;
|
||||
iter->next = tree_iter_next;
|
||||
|
||||
self->_order = order;
|
||||
self->stack->clear(self->stack);
|
||||
self->queue->clear(self->queue);
|
||||
|
||||
switch (self->_order)
|
||||
switch (iter->_order)
|
||||
{
|
||||
case ORDER_PRE:
|
||||
case ORDER_PRE_R:
|
||||
@ -1182,7 +1354,7 @@ static iterator_t tree_iter(struct _tree* self, enum _order order)
|
||||
self->stack->clear(self->stack);
|
||||
|
||||
stack_t stack = stack_new(sizeof(struct _tree_node*));
|
||||
if (self->_order == ORDER_POST)
|
||||
if (iter->_order == ORDER_POST)
|
||||
{
|
||||
while (!stack->empty(stack) || node != NULL)
|
||||
{
|
||||
@ -1234,205 +1406,6 @@ static iterator_t tree_iter(struct _tree* self, enum _order order)
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool tree_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_parent;
|
||||
if(iter->_cur < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const void* tree_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_parent;
|
||||
void *obj = NULL;
|
||||
|
||||
self->_iter._cur += 1;
|
||||
|
||||
struct _tree_node* cur_node = self->_iter._cur_node;
|
||||
switch (self->_order)
|
||||
{
|
||||
case ORDER_PRE:
|
||||
case ORDER_PRE_R:
|
||||
{
|
||||
struct _tree_node* node = NULL;
|
||||
if (self->_order == ORDER_PRE)
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
node = cur_node;
|
||||
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
node = cur_node;
|
||||
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->_iter._cur_node = cur_node;
|
||||
obj = node->obj;
|
||||
}break;
|
||||
case ORDER_IN:
|
||||
case ORDER_IN_R:
|
||||
{
|
||||
struct _tree_node* node = NULL;
|
||||
if (self->_order == ORDER_IN)
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
|
||||
node = cur_node;
|
||||
cur_node = cur_node->right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!self->stack->empty(self->stack) || cur_node != NULL)
|
||||
{
|
||||
if (cur_node != NULL)
|
||||
{
|
||||
self->stack->push(self->stack, &cur_node);
|
||||
cur_node = cur_node->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
|
||||
node = cur_node;
|
||||
cur_node = cur_node->left;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->_iter._cur_node = cur_node;
|
||||
obj = node->obj;
|
||||
}break;
|
||||
case ORDER_POST:
|
||||
case ORDER_POST_R:
|
||||
{
|
||||
if (!self->stack->empty(self->stack))
|
||||
{
|
||||
self->stack->pop(self->stack, &cur_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_node = NULL;
|
||||
}
|
||||
|
||||
if(cur_node != NULL)
|
||||
{
|
||||
self->_iter._cur_node = cur_node;
|
||||
obj = cur_node->obj;
|
||||
}
|
||||
}break;
|
||||
case ORDER_BREADTH:
|
||||
case ORDER_BREADTH_R:
|
||||
{
|
||||
struct _tree_node* node = cur_node;
|
||||
queue_t queue = self->queue;
|
||||
if (!queue->empty(queue) && node != NULL)
|
||||
{
|
||||
queue->pop(queue, &node);
|
||||
if (self->_order == ORDER_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);
|
||||
}
|
||||
}
|
||||
cur_node = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_node = NULL;
|
||||
}
|
||||
|
||||
if(cur_node != NULL)
|
||||
{
|
||||
self->_iter._cur_node = cur_node;
|
||||
obj = cur_node->obj;
|
||||
}
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
}break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
static bool tree_avl_init(struct _tree* self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -1443,9 +1416,6 @@ static bool tree_avl_init(struct _tree* self, uint32_t obj_size)
|
||||
// self->_capacity = 64;
|
||||
// self->_ratio = 2;
|
||||
|
||||
self->_right_priority = false;
|
||||
self->_order = ORDER_PRE;
|
||||
|
||||
self->_root = NULL;
|
||||
|
||||
self->stack = stack_new(sizeof(struct _tree_node*));
|
||||
@ -1460,16 +1430,13 @@ static bool tree_avl_init(struct _tree* self, uint32_t obj_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_iter.hasnext = tree_iter_hasnext;
|
||||
self->_iter.next = tree_iter_next;
|
||||
|
||||
self->_rebalance = tree_avl_rebalance;
|
||||
self->_destory = tree_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
self->insert = tree_avl_insert;
|
||||
self->delete = tree_avl_delete;
|
||||
self->rebalance = tree_avl_rebalance;
|
||||
self->height = tree_height;
|
||||
|
||||
// base
|
||||
@ -1499,9 +1466,6 @@ static bool tree_rb_init(struct _tree* self, uint32_t obj_size)
|
||||
|
||||
self->_root = NULL;
|
||||
|
||||
self->_right_priority = false;
|
||||
self->_order = ORDER_PRE;
|
||||
|
||||
self->stack = stack_new(sizeof(struct _tree_node*));
|
||||
if (self->stack == NULL)
|
||||
{
|
||||
@ -1514,16 +1478,13 @@ static bool tree_rb_init(struct _tree* self, uint32_t obj_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_iter.hasnext = tree_iter_hasnext;
|
||||
self->_iter.next = tree_iter_next;
|
||||
|
||||
self->_rebalance = tree_rb_rebalance;
|
||||
self->_destory = tree_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
self->insert = tree_rb_insert;
|
||||
self->delete = tree_rb_delete;
|
||||
self->rebalance = tree_rb_rebalance;
|
||||
self->height = tree_height;
|
||||
|
||||
// base
|
||||
|
@ -67,7 +67,7 @@ static const int expected_int_array_orderpre_delete[15][15] = {
|
||||
{ 13, },
|
||||
};
|
||||
|
||||
static const enum _order order[8] = {
|
||||
static const enum _tree_order order[8] = {
|
||||
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
|
||||
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
|
||||
};
|
||||
@ -335,10 +335,6 @@ static void test_rbtree_delete(void)
|
||||
int temp = 0;
|
||||
int count = 0;
|
||||
iterator_t iter = NULL;
|
||||
enum _order order[8] = {
|
||||
ORDER_PRE, ORDER_IN, ORDER_POST, ORDER_BREADTH,
|
||||
ORDER_PRE_R, ORDER_IN_R, ORDER_POST_R, ORDER_BREADTH_R
|
||||
};
|
||||
|
||||
tree_t tree = tree_rb_new(sizeof(int));
|
||||
TEST_ASSERT_NOT_NULL(tree);
|
||||
|
Loading…
Reference in New Issue
Block a user