mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-05-17 19:41:36 +08:00
Compare commits
5 Commits
eb918955f5
...
51b41f46da
Author | SHA1 | Date | |
---|---|---|---|
51b41f46da | |||
4acdcf3ec7 | |||
d9d5f052b1 | |||
bad8d68180 | |||
4530508a1b |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -26,6 +26,7 @@
|
||||
"graph.h": "c",
|
||||
"unicstl_config.h": "c",
|
||||
"iter.h": "c",
|
||||
"iterator.h": "c"
|
||||
"iterator.h": "c",
|
||||
"assert.h": "c"
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
#ifndef _UNICSTL_CONFIG_H_
|
||||
|
||||
/**
|
||||
* @brief unicstl container
|
||||
* @brief unicstl contains which module
|
||||
*
|
||||
*/
|
||||
#define UNICSTL_LIST
|
||||
@ -27,7 +27,7 @@
|
||||
* @brief debug
|
||||
*
|
||||
*/
|
||||
#define NDEBUG // assert disable
|
||||
// #define NDEBUG // assert disable
|
||||
|
||||
#define UNICSTL_DEBUG
|
||||
|
||||
@ -38,7 +38,6 @@
|
||||
#define UNICSTL_DEBUG_TREE
|
||||
#define UNICSTL_DEBUG_HEAP
|
||||
#define UNICSTL_DEBUG_GRAPH
|
||||
// #define UNICSTL_DEBUG_ITERATOR
|
||||
#endif
|
||||
|
||||
#endif
|
@ -298,7 +298,7 @@ static void deque_print(struct _deque* self)
|
||||
bool deque_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
@ -311,7 +311,7 @@ bool deque_iter_hasnext(struct _iterator* iter)
|
||||
const void* deque_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
@ -825,7 +825,7 @@ static struct _graph_node * graph_find_next_unvisited_target(struct _graph *self
|
||||
bool graph_iter_hasnext(struct _iterator *iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
graph_t self = (graph_t)iter->_container;
|
||||
if (iter->_index < self->size(self))
|
||||
@ -838,7 +838,7 @@ bool graph_iter_hasnext(struct _iterator *iter)
|
||||
const void *graph_iter_next(struct _iterator *iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
graph_t self = (graph_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
|
@ -252,7 +252,7 @@ static void heap_print(struct _heap* self)
|
||||
bool heap_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
heap_t self = (heap_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
@ -265,7 +265,7 @@ bool heap_iter_hasnext(struct _iterator* iter)
|
||||
const void* heap_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
heap_t self = (heap_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
@ -214,8 +214,6 @@ iterator_t list_iter(struct _list* self)
|
||||
static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(obj_size > 0);
|
||||
assert(capacity > 0);
|
||||
if(list == NULL || obj_size == 0 || capacity == 0)
|
||||
{
|
||||
return false;
|
||||
|
@ -309,7 +309,7 @@ static void queue2_print(struct _queue* self)
|
||||
static bool queue_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
@ -322,7 +322,7 @@ static bool queue_iter_hasnext(struct _iterator* iter)
|
||||
static const void* queue_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
@ -355,7 +355,7 @@ static iterator_t queue_iter(struct _queue* self)
|
||||
static const void* queue2_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
queue_t self = (queue_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
@ -385,7 +385,6 @@ static iterator_t queue2_iter(struct _queue* self)
|
||||
static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(obj_size > 0);
|
||||
if(self == NULL || obj_size == 0)
|
||||
{
|
||||
return false;
|
||||
@ -430,8 +429,6 @@ static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||
static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capacity)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(obj_size > 0);
|
||||
assert(capacity > 0);
|
||||
if(self == NULL || obj_size == 0 || capacity == 0)
|
||||
{
|
||||
return false;
|
||||
|
@ -257,7 +257,7 @@ static void stack2_print(struct _stack* self)
|
||||
bool stack_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
stack_t self = (stack_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
@ -274,7 +274,7 @@ bool stack_iter_hasnext(struct _iterator* iter)
|
||||
const void* stack_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
stack_t self = (stack_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
436
src/tree.c
436
src/tree.c
@ -12,10 +12,50 @@
|
||||
#include "queue.h"
|
||||
#include "stack.h"
|
||||
|
||||
// #define TREE_RECURSIVE_ENABLED
|
||||
|
||||
static struct _tree_node* tree_node_new(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
void* obj_new = malloc(self->_obj_size);
|
||||
if (obj_new == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memmove(obj_new, obj, self->_obj_size);
|
||||
|
||||
struct _tree_node* node_new = (struct _tree_node*)malloc(sizeof(struct _tree_node));
|
||||
if (node_new == NULL)
|
||||
{
|
||||
free(obj_new);
|
||||
return NULL;
|
||||
}
|
||||
node_new->obj = obj_new;
|
||||
node_new->parent = NULL;
|
||||
node_new->left = NULL;
|
||||
node_new->right = NULL;
|
||||
node_new->balance = 0;
|
||||
|
||||
return node_new;
|
||||
}
|
||||
|
||||
static void tree_node_free(struct _tree_node** node)
|
||||
{
|
||||
if (node != NULL && (*node) != NULL)
|
||||
{
|
||||
if ((*node)->obj != NULL)
|
||||
{
|
||||
free((*node)->obj);
|
||||
}
|
||||
free(*node);
|
||||
*node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t tree_height_node(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
#if 0
|
||||
#ifdef TREE_RECURSIVE_ENABLED
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
@ -200,7 +240,7 @@ static struct _tree_node* tree_turn_right_then_left(struct _tree* self, struct _
|
||||
*/
|
||||
static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
#if 0
|
||||
#ifdef TREE_RECURSIVE_ENABLED
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
@ -211,7 +251,6 @@ static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
||||
return false;
|
||||
}
|
||||
|
||||
// self->print_obj(root->obj);
|
||||
tree_set_balance(self, root);
|
||||
int balance = root->balance;
|
||||
if (balance == 2)
|
||||
@ -246,6 +285,7 @@ static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
||||
self->_root = root;
|
||||
}
|
||||
return true;
|
||||
|
||||
#else
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
@ -323,107 +363,28 @@ static struct _tree_node* tree_find(struct _tree* self, void* obj)
|
||||
static struct _tree_node* tree_find_min(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
assert(self != NULL);
|
||||
#if 0
|
||||
if (root == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (root->left == NULL)
|
||||
{
|
||||
return root;
|
||||
}
|
||||
return tree_find_min(self, root->left);
|
||||
#else
|
||||
while (root != NULL)
|
||||
{
|
||||
if (root->left != NULL)
|
||||
if (root->left == NULL)
|
||||
{
|
||||
root = root->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
return root;
|
||||
break;
|
||||
}
|
||||
root = root->left;
|
||||
}
|
||||
return root;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct _tree_node* tree_find_max(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
#if 0
|
||||
assert(self != NULL);
|
||||
if (root == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (root->right == NULL)
|
||||
{
|
||||
return root;
|
||||
}
|
||||
return tree_find_max(self, root->right);
|
||||
#else
|
||||
while (root != NULL)
|
||||
{
|
||||
if (root->right != NULL)
|
||||
if (root->right == NULL)
|
||||
{
|
||||
root = root->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
return root;
|
||||
break;
|
||||
}
|
||||
root = root->right;
|
||||
}
|
||||
return root;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct _tree_node* tree_node_new(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
void* obj_new = malloc(self->_obj_size);
|
||||
if (obj_new == NULL)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
memmove(obj_new, obj, self->_obj_size);
|
||||
|
||||
struct _tree_node* node_new = (struct _tree_node*)malloc(sizeof(struct _tree_node));
|
||||
if (node_new == NULL)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
node_new->obj = obj_new;
|
||||
node_new->parent = NULL;
|
||||
node_new->left = NULL;
|
||||
node_new->right = NULL;
|
||||
node_new->balance = 0;
|
||||
|
||||
return node_new;
|
||||
done:
|
||||
if (obj_new != NULL)
|
||||
{
|
||||
free(obj_new);
|
||||
}
|
||||
if (node_new != NULL)
|
||||
{
|
||||
free(node_new);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool tree_node_free(struct _tree_node* node)
|
||||
{
|
||||
if (node != NULL)
|
||||
{
|
||||
if (node->obj != NULL)
|
||||
{
|
||||
free(node->obj);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -440,11 +401,7 @@ struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
|
||||
struct _tree_node* root = self->_root;
|
||||
while (root != NULL)
|
||||
{
|
||||
if (self->compare(obj, root->obj) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (self->compare(obj, root->obj) < 0)
|
||||
if (self->compare(obj, root->obj) < 0)
|
||||
{
|
||||
if (root->left == NULL)
|
||||
{
|
||||
@ -452,7 +409,7 @@ struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
|
||||
}
|
||||
root = root->left;
|
||||
}
|
||||
else
|
||||
else if(self->compare(obj, root->obj) > 0)
|
||||
{
|
||||
if (root->right == NULL)
|
||||
{
|
||||
@ -460,6 +417,11 @@ struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
|
||||
}
|
||||
root = root->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if obj exist
|
||||
break;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
@ -471,40 +433,46 @@ static bool tree_avl_insert(struct _tree* self, void* obj)
|
||||
assert(obj != NULL);
|
||||
assert(self->compare != NULL);
|
||||
|
||||
struct _tree_node* node = tree_node_new(self, obj);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if no root
|
||||
if (self->_root == NULL)
|
||||
{
|
||||
self->_root = node;
|
||||
// if tree is empty
|
||||
struct _tree_node* new_node = tree_node_new(self, obj);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_root = new_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert the node
|
||||
struct _tree_node* root = tree_find_pos(self, obj);
|
||||
if (self->compare(obj, root->obj) == 0)
|
||||
{
|
||||
// if obj is exist in tree, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
struct _tree_node* new_node = tree_node_new(self, obj);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self->compare(obj, root->obj) < 0)
|
||||
{
|
||||
root->left = node;
|
||||
node->parent = root;
|
||||
root->left = new_node;
|
||||
new_node->parent = root;
|
||||
}
|
||||
else if (self->compare(obj, root->obj) > 0)
|
||||
else /*if (self->compare(obj, root->obj) > 0)*/
|
||||
{
|
||||
root->right = node;
|
||||
node->parent = root;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if obj exist, just return false
|
||||
tree_node_free(node);
|
||||
return false;
|
||||
root->right = new_node;
|
||||
new_node->parent = root;
|
||||
}
|
||||
|
||||
self->_rebalance(self, root);
|
||||
}
|
||||
|
||||
self->_size++;
|
||||
return true;
|
||||
}
|
||||
@ -570,7 +538,7 @@ static bool tree_avl_delete_single_child(struct _tree* self, struct _tree_node*
|
||||
|
||||
self->_rebalance(self, node->parent);
|
||||
}
|
||||
tree_node_free(node);
|
||||
tree_node_free(&node);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -619,93 +587,6 @@ static bool tree_avl_delete(struct _tree* self, void* obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_clear(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
if (self->_root == NULL)
|
||||
{
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct _tree_node* node = self->_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);
|
||||
}
|
||||
tree_node_free(node);
|
||||
}
|
||||
queue_free(&queue);
|
||||
self->_root = NULL;
|
||||
self->_size = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_empty(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return !self->size(self);
|
||||
}
|
||||
|
||||
static uint32_t tree_size(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return self->_size;
|
||||
}
|
||||
|
||||
// free
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
|
||||
static bool tree_min(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
struct _tree_node* node = tree_find_min(self, self->_root);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_max(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
struct _tree_node* node = tree_find_max(self, self->_root);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static rbt_color tree_color(struct _tree_node* node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
@ -719,7 +600,6 @@ static bool tree_set_color(struct _tree_node* node, rbt_color color)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static struct _tree_node* tree_rb_turn_left(struct _tree* self, struct _tree_node* root)
|
||||
{
|
||||
assert(self != NULL);
|
||||
@ -800,41 +680,46 @@ static bool tree_rb_insert(struct _tree* self, void* obj)
|
||||
assert(obj != NULL);
|
||||
assert(self->compare != NULL);
|
||||
|
||||
struct _tree_node* node = tree_node_new(self, obj);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if no root
|
||||
struct _tree_node* new_node = NULL;
|
||||
if (self->_root == NULL)
|
||||
{
|
||||
self->_root = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert the node
|
||||
struct _tree_node* root = tree_find_pos(self, obj);
|
||||
if (self->compare(obj, root->obj) < 0)
|
||||
// if tree is empty
|
||||
new_node = tree_node_new(self, obj);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
root->left = node;
|
||||
node->parent = root;
|
||||
}
|
||||
else if (self->compare(obj, root->obj) > 0)
|
||||
{
|
||||
root->right = node;
|
||||
node->parent = root;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if obj exist, just return false
|
||||
tree_node_free(node);
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_root = new_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct _tree_node* root = tree_find_pos(self, obj);
|
||||
if (self->compare(obj, root->obj) == 0)
|
||||
{
|
||||
// if obj is exist in tree, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
new_node = tree_node_new(self, obj);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self->compare(obj, root->obj) < 0)
|
||||
{
|
||||
root->left = new_node;
|
||||
new_node->parent = root;
|
||||
}
|
||||
else /*if (self->compare(obj, root->obj) > 0)*/
|
||||
{
|
||||
root->right = new_node;
|
||||
new_node->parent = root;
|
||||
}
|
||||
}
|
||||
|
||||
self->_rebalance(self, node);
|
||||
self->_rebalance(self, new_node);
|
||||
|
||||
self->_size++;
|
||||
return true;
|
||||
@ -1146,20 +1031,105 @@ static bool tree_rb_delete(struct _tree* self, void* obj)
|
||||
self->_root = NULL;
|
||||
}
|
||||
|
||||
tree_node_free(tmp);
|
||||
tree_node_free(&tmp);
|
||||
self->_size--;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_empty(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return !self->size(self);
|
||||
}
|
||||
|
||||
static uint32_t tree_size(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
return self->_size;
|
||||
}
|
||||
|
||||
static bool tree_clear(struct _tree* self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
if (self->_root == NULL)
|
||||
{
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct _tree_node* node = self->_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);
|
||||
}
|
||||
tree_node_free(&node);
|
||||
}
|
||||
queue_free(&queue);
|
||||
self->_root = NULL;
|
||||
self->_size = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t tree_height(struct _tree* self)
|
||||
{
|
||||
return tree_height_node(self, self->_root);
|
||||
}
|
||||
|
||||
|
||||
static bool tree_min(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
struct _tree_node* node = tree_find_min(self, self->_root);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_max(struct _tree* self, void* obj)
|
||||
{
|
||||
assert(self != NULL);
|
||||
struct _tree_node* node = tree_find_max(self, self->_root);
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tree_iter_hasnext(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
@ -1172,7 +1142,7 @@ static bool tree_iter_hasnext(struct _iterator* iter)
|
||||
static const void* tree_iter_next(struct _iterator* iter)
|
||||
{
|
||||
assert(iter != NULL);
|
||||
assert(iter->parent != NULL);
|
||||
assert(iter->_container != NULL);
|
||||
|
||||
tree_t self = (tree_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user