mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-05-18 03:51:35 +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",
|
"graph.h": "c",
|
||||||
"unicstl_config.h": "c",
|
"unicstl_config.h": "c",
|
||||||
"iter.h": "c",
|
"iter.h": "c",
|
||||||
"iterator.h": "c"
|
"iterator.h": "c",
|
||||||
|
"assert.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef _UNICSTL_CONFIG_H_
|
#ifndef _UNICSTL_CONFIG_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief unicstl container
|
* @brief unicstl contains which module
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define UNICSTL_LIST
|
#define UNICSTL_LIST
|
||||||
@ -27,7 +27,7 @@
|
|||||||
* @brief debug
|
* @brief debug
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define NDEBUG // assert disable
|
// #define NDEBUG // assert disable
|
||||||
|
|
||||||
#define UNICSTL_DEBUG
|
#define UNICSTL_DEBUG
|
||||||
|
|
||||||
@ -38,7 +38,6 @@
|
|||||||
#define UNICSTL_DEBUG_TREE
|
#define UNICSTL_DEBUG_TREE
|
||||||
#define UNICSTL_DEBUG_HEAP
|
#define UNICSTL_DEBUG_HEAP
|
||||||
#define UNICSTL_DEBUG_GRAPH
|
#define UNICSTL_DEBUG_GRAPH
|
||||||
// #define UNICSTL_DEBUG_ITERATOR
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -298,7 +298,7 @@ static void deque_print(struct _deque* self)
|
|||||||
bool deque_iter_hasnext(struct _iterator* iter)
|
bool deque_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
deque_t self = (deque_t)iter->_container;
|
deque_t self = (deque_t)iter->_container;
|
||||||
if(iter->_index < self->size(self))
|
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)
|
const void* deque_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
deque_t self = (deque_t)iter->_container;
|
deque_t self = (deque_t)iter->_container;
|
||||||
void *obj = NULL;
|
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)
|
bool graph_iter_hasnext(struct _iterator *iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
graph_t self = (graph_t)iter->_container;
|
graph_t self = (graph_t)iter->_container;
|
||||||
if (iter->_index < self->size(self))
|
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)
|
const void *graph_iter_next(struct _iterator *iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
graph_t self = (graph_t)iter->_container;
|
graph_t self = (graph_t)iter->_container;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ static void heap_print(struct _heap* self)
|
|||||||
bool heap_iter_hasnext(struct _iterator* iter)
|
bool heap_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
heap_t self = (heap_t)iter->_container;
|
heap_t self = (heap_t)iter->_container;
|
||||||
if(iter->_index < self->size(self))
|
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)
|
const void* heap_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
heap_t self = (heap_t)iter->_container;
|
heap_t self = (heap_t)iter->_container;
|
||||||
void *obj = NULL;
|
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)
|
static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity)
|
||||||
{
|
{
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
assert(obj_size > 0);
|
|
||||||
assert(capacity > 0);
|
|
||||||
if(list == NULL || obj_size == 0 || capacity == 0)
|
if(list == NULL || obj_size == 0 || capacity == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -309,7 +309,7 @@ static void queue2_print(struct _queue* self)
|
|||||||
static bool queue_iter_hasnext(struct _iterator* iter)
|
static bool queue_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_container;
|
||||||
if(iter->_index < self->size(self))
|
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)
|
static const void* queue_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_container;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
@ -355,7 +355,7 @@ static iterator_t queue_iter(struct _queue* self)
|
|||||||
static const void* queue2_iter_next(struct _iterator* iter)
|
static const void* queue2_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
queue_t self = (queue_t)iter->_container;
|
queue_t self = (queue_t)iter->_container;
|
||||||
void *obj = NULL;
|
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)
|
static bool queue_init(struct _queue * self, uint32_t obj_size)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
assert(obj_size > 0);
|
|
||||||
if(self == NULL || obj_size == 0)
|
if(self == NULL || obj_size == 0)
|
||||||
{
|
{
|
||||||
return false;
|
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)
|
static bool queue_init2(struct _queue * self, uint32_t obj_size, uint32_t capacity)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
assert(obj_size > 0);
|
|
||||||
assert(capacity > 0);
|
|
||||||
if(self == NULL || obj_size == 0 || capacity == 0)
|
if(self == NULL || obj_size == 0 || capacity == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -257,7 +257,7 @@ static void stack2_print(struct _stack* self)
|
|||||||
bool stack_iter_hasnext(struct _iterator* iter)
|
bool stack_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
stack_t self = (stack_t)iter->_container;
|
stack_t self = (stack_t)iter->_container;
|
||||||
if(iter->_index < self->size(self))
|
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)
|
const void* stack_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
stack_t self = (stack_t)iter->_container;
|
stack_t self = (stack_t)iter->_container;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
436
src/tree.c
436
src/tree.c
@ -12,10 +12,50 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "stack.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)
|
static uint32_t tree_height_node(struct _tree* self, struct _tree_node* root)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef TREE_RECURSIVE_ENABLED
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
if (root == 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)
|
static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifdef TREE_RECURSIVE_ENABLED
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
if (root == NULL)
|
if (root == NULL)
|
||||||
{
|
{
|
||||||
@ -211,7 +251,6 @@ static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// self->print_obj(root->obj);
|
|
||||||
tree_set_balance(self, root);
|
tree_set_balance(self, root);
|
||||||
int balance = root->balance;
|
int balance = root->balance;
|
||||||
if (balance == 2)
|
if (balance == 2)
|
||||||
@ -246,6 +285,7 @@ static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
|
|||||||
self->_root = root;
|
self->_root = root;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
if (root == 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)
|
static struct _tree_node* tree_find_min(struct _tree* self, struct _tree_node* root)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
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)
|
while (root != NULL)
|
||||||
{
|
{
|
||||||
if (root->left != NULL)
|
if (root->left == NULL)
|
||||||
{
|
{
|
||||||
root = root->left;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
root = root->left;
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct _tree_node* tree_find_max(struct _tree* self, struct _tree_node* root)
|
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)
|
while (root != NULL)
|
||||||
{
|
{
|
||||||
if (root->right != NULL)
|
if (root->right == NULL)
|
||||||
{
|
{
|
||||||
root = root->right;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
root = root->right;
|
||||||
}
|
}
|
||||||
return root;
|
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;
|
struct _tree_node* root = self->_root;
|
||||||
while (root != NULL)
|
while (root != NULL)
|
||||||
{
|
{
|
||||||
if (self->compare(obj, root->obj) == 0)
|
if (self->compare(obj, root->obj) < 0)
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (self->compare(obj, root->obj) < 0)
|
|
||||||
{
|
{
|
||||||
if (root->left == NULL)
|
if (root->left == NULL)
|
||||||
{
|
{
|
||||||
@ -452,7 +409,7 @@ struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
|
|||||||
}
|
}
|
||||||
root = root->left;
|
root = root->left;
|
||||||
}
|
}
|
||||||
else
|
else if(self->compare(obj, root->obj) > 0)
|
||||||
{
|
{
|
||||||
if (root->right == NULL)
|
if (root->right == NULL)
|
||||||
{
|
{
|
||||||
@ -460,6 +417,11 @@ struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
|
|||||||
}
|
}
|
||||||
root = root->right;
|
root = root->right;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if obj exist
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@ -471,40 +433,46 @@ static bool tree_avl_insert(struct _tree* self, void* obj)
|
|||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
assert(self->compare != 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)
|
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
|
else
|
||||||
{
|
{
|
||||||
// insert the node
|
|
||||||
struct _tree_node* root = tree_find_pos(self, obj);
|
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)
|
if (self->compare(obj, root->obj) < 0)
|
||||||
{
|
{
|
||||||
root->left = node;
|
root->left = new_node;
|
||||||
node->parent = root;
|
new_node->parent = root;
|
||||||
}
|
}
|
||||||
else if (self->compare(obj, root->obj) > 0)
|
else /*if (self->compare(obj, root->obj) > 0)*/
|
||||||
{
|
{
|
||||||
root->right = node;
|
root->right = new_node;
|
||||||
node->parent = root;
|
new_node->parent = root;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if obj exist, just return false
|
|
||||||
tree_node_free(node);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->_rebalance(self, root);
|
self->_rebalance(self, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->_size++;
|
self->_size++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -570,7 +538,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);
|
tree_node_free(&node);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,93 +587,6 @@ static bool tree_avl_delete(struct _tree* self, void* obj)
|
|||||||
return true;
|
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)
|
static rbt_color tree_color(struct _tree_node* node)
|
||||||
{
|
{
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
@ -719,7 +600,6 @@ static bool tree_set_color(struct _tree_node* node, rbt_color color)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct _tree_node* tree_rb_turn_left(struct _tree* self, struct _tree_node* root)
|
static struct _tree_node* tree_rb_turn_left(struct _tree* self, struct _tree_node* root)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -800,41 +680,46 @@ static bool tree_rb_insert(struct _tree* self, void* obj)
|
|||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
assert(self->compare != NULL);
|
assert(self->compare != NULL);
|
||||||
|
|
||||||
struct _tree_node* node = tree_node_new(self, obj);
|
struct _tree_node* new_node = NULL;
|
||||||
if (node == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no root
|
|
||||||
if (self->_root == NULL)
|
if (self->_root == NULL)
|
||||||
{
|
{
|
||||||
self->_root = node;
|
// if tree is empty
|
||||||
}
|
new_node = tree_node_new(self, obj);
|
||||||
else
|
if (new_node == NULL)
|
||||||
{
|
|
||||||
// insert the node
|
|
||||||
struct _tree_node* root = tree_find_pos(self, obj);
|
|
||||||
if (self->compare(obj, root->obj) < 0)
|
|
||||||
{
|
{
|
||||||
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;
|
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++;
|
self->_size++;
|
||||||
return true;
|
return true;
|
||||||
@ -1146,20 +1031,105 @@ static bool tree_rb_delete(struct _tree* self, void* obj)
|
|||||||
self->_root = NULL;
|
self->_root = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_node_free(tmp);
|
tree_node_free(&tmp);
|
||||||
self->_size--;
|
self->_size--;
|
||||||
return true;
|
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)
|
static uint32_t tree_height(struct _tree* self)
|
||||||
{
|
{
|
||||||
return tree_height_node(self, self->_root);
|
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)
|
static bool tree_iter_hasnext(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
tree_t self = (tree_t)iter->_container;
|
tree_t self = (tree_t)iter->_container;
|
||||||
if(iter->_index < self->size(self))
|
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)
|
static const void* tree_iter_next(struct _iterator* iter)
|
||||||
{
|
{
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
assert(iter->parent != NULL);
|
assert(iter->_container != NULL);
|
||||||
|
|
||||||
tree_t self = (tree_t)iter->_container;
|
tree_t self = (tree_t)iter->_container;
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user