Add tree iterator (untested) and tree copying
This commit is contained in:
parent
ce1877f52a
commit
bc755098b3
@ -12,7 +12,7 @@ typedef struct RJP_object_member{
|
||||
RJP_value value;
|
||||
}RJP_object_member;
|
||||
|
||||
struct RJP_tree_node;
|
||||
typedef struct RJP_object_iterator RJP_object_iterator;
|
||||
typedef struct RJP_tree_node RJP_tree_node;
|
||||
struct RJP_tree_node{
|
||||
RJP_tree_node* parent;
|
||||
@ -26,6 +26,13 @@ RJP_tree_node* irjp_new_node(RJP_object_member value);
|
||||
RJP_tree_node* irjp_insert_value(RJP_tree_node* root, RJP_object_member value, int* status);
|
||||
RJP_tree_node* irjp_remove_value(RJP_tree_node* root, RJP_object_member value, int* status);
|
||||
RJP_tree_node* irjp_search_value(RJP_tree_node* root, RJP_object_member value);
|
||||
RJP_tree_node* irjp_copy_tree(RJP_tree_node* root);
|
||||
|
||||
int irjp_init_object_iterator(RJP_object_iterator* it, RJP_tree_node* root);
|
||||
void irjp_delete_object_iterator(RJP_object_iterator* it);
|
||||
RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it);
|
||||
RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it);
|
||||
|
||||
void irjp_dbg_print_tree(RJP_tree_node* root);
|
||||
void irjp_dbg_print_tree_bfs(RJP_tree_node* root);
|
||||
|
||||
|
||||
98
src/tree.c
98
src/tree.c
@ -13,13 +13,32 @@
|
||||
#define rjp_free free
|
||||
#define rjp_free_value(x)
|
||||
|
||||
#define RJP_TREE_ITERATOR_STACK_START_SIZE 32
|
||||
|
||||
typedef struct RJP_tree_stack{
|
||||
RJP_tree_node** data;
|
||||
int size;
|
||||
int pos;
|
||||
}RJP_tree_stack;
|
||||
typedef struct RJP_object_iterator{
|
||||
RJP_tree_stack stack;
|
||||
RJP_tree_node* current;
|
||||
}RJP_object_iterator;
|
||||
|
||||
|
||||
static RJP_tree_node* irjp_insert_node(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode);
|
||||
static RJP_tree_node* irjp_insert_impl(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode);
|
||||
static RJP_tree_node* irjp_repair_tree(RJP_tree_node* node);
|
||||
static void irjp_copy_node(RJP_tree_node *restrict dest, RJP_tree_node *restrict src);
|
||||
static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src);
|
||||
static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restrict child);
|
||||
static void irjp_delete_node(RJP_tree_node* node);
|
||||
static void irjp_free_node(RJP_tree_node* node);
|
||||
static RJP_tree_node* irjp_remove_node(RJP_tree_node* target);
|
||||
static int irjp_init_tree_stack(RJP_tree_stack* stack);
|
||||
static void irjp_delete_tree_stack(RJP_tree_stack* stack);
|
||||
static void irjp_resize_tree_stack(RJP_tree_stack* stack);
|
||||
static void irjp_push_tree_stack(RJP_tree_stack* stack, RJP_tree_node* value);
|
||||
static RJP_tree_node* irjp_pop_tree_stack(RJP_tree_stack* stack);
|
||||
static RJP_tree_node* irjp_peek_tree_stack(RJP_tree_stack* stack);
|
||||
|
||||
static inline RJP_tree_node* irjp_grandparent(RJP_tree_node* n){
|
||||
if(!n->parent)
|
||||
@ -81,7 +100,7 @@ static inline int irjp_is_inside_right(RJP_tree_node* n){
|
||||
RJP_tree_node* g = irjp_grandparent(n);
|
||||
return n == p->left && p == g->right;
|
||||
}
|
||||
static void irjp_copy_node(RJP_tree_node *restrict dest, RJP_tree_node *restrict src){
|
||||
static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src){
|
||||
dest->data = src->data;
|
||||
}
|
||||
static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restrict child){
|
||||
@ -94,7 +113,7 @@ static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restr
|
||||
else
|
||||
node->parent->right = child;
|
||||
}
|
||||
static void irjp_delete_node(RJP_tree_node* node){
|
||||
static void irjp_free_node(RJP_tree_node* node){
|
||||
rjp_free(node->data.name.value);
|
||||
rjp_free_value(&node->data.value);
|
||||
rjp_free(node);
|
||||
@ -107,6 +126,73 @@ RJP_tree_node* irjp_new_node(RJP_object_member value){
|
||||
node->parent = node->left = node->right = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* TREE STACK */
|
||||
static int irjp_init_tree_stack(RJP_tree_stack* stack){
|
||||
stack->data = rjp_malloc(sizeof(RJP_tree_node*)*RJP_TREE_ITERATOR_STACK_START_SIZE);
|
||||
stack->size = RJP_TREE_ITERATOR_STACK_START_SIZE;
|
||||
stack->pos = 0;
|
||||
return 0;
|
||||
}
|
||||
static void irjp_delete_tree_stack(RJP_tree_stack* stack){
|
||||
rjp_free(stack->data);
|
||||
}
|
||||
static void irjp_resize_tree_stack(RJP_tree_stack* stack){
|
||||
int newsize = stack->size*2;
|
||||
RJP_tree_node** newdata = rjp_malloc(sizeof(RJP_tree_node*)*newsize);
|
||||
for(int i = 0;i < stack->size;++i){
|
||||
newdata[i] = stack->data[i];
|
||||
}
|
||||
rjp_free(stack->data);
|
||||
stack->data = newdata;
|
||||
stack->size = newsize;
|
||||
}
|
||||
static void irjp_push_tree_stack(RJP_tree_stack* stack, RJP_tree_node* value){
|
||||
stack->data[stack->pos++] = value;
|
||||
if(stack->pos == stack->size)
|
||||
irjp_resize_tree_stack(stack);
|
||||
}
|
||||
static RJP_tree_node* irjp_pop_tree_stack(RJP_tree_stack* stack){
|
||||
return stack->data[--stack->pos];
|
||||
}
|
||||
static RJP_tree_node* irjp_peek_tree_stack(RJP_tree_stack* stack){
|
||||
return stack->data[stack->pos-1];
|
||||
}
|
||||
|
||||
/* TREE ITERATOR */
|
||||
int irjp_init_object_iterator(RJP_object_iterator* it, RJP_tree_node* root){
|
||||
irjp_init_tree_stack(&it->stack);
|
||||
it->current = root;
|
||||
while(it->current){
|
||||
irjp_push_tree_stack(&it->stack, it->current);
|
||||
it->current = it->current->left;
|
||||
}
|
||||
it->current = irjp_peek_tree_stack(&it->stack);
|
||||
return 0;
|
||||
}
|
||||
void irjp_delete_object_iterator(RJP_object_iterator* it){
|
||||
irjp_delete_tree_stack(&it->stack);
|
||||
}
|
||||
RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it){
|
||||
RJP_tree_node* last = irjp_pop_tree_stack(&it->stack);
|
||||
if(last->right){
|
||||
irjp_push_tree_stack(&it->stack, last->right);
|
||||
}
|
||||
return (it->current = irjp_peek_tree_stack(&it->stack));
|
||||
}
|
||||
RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it){
|
||||
return it->current;
|
||||
}
|
||||
|
||||
/* TREE */
|
||||
RJP_tree_node* irjp_copy_tree(RJP_tree_node* root){
|
||||
if(!root)
|
||||
return NULL;
|
||||
RJP_tree_node* newnode = irjp_new_node(root->data);
|
||||
newnode->left = irjp_copy_tree(root->left);
|
||||
newnode->right = irjp_copy_tree(root->right);
|
||||
return newnode;
|
||||
}
|
||||
RJP_tree_node* irjp_insert_value(RJP_tree_node* root, RJP_object_member value, int* status){
|
||||
*status = RJP_TREE_SUCCESS;
|
||||
if(!root){
|
||||
@ -276,7 +362,7 @@ RJP_tree_node* irjp_remove_value(RJP_tree_node* root, RJP_object_member value, i
|
||||
}
|
||||
static RJP_tree_node* irjp_remove_node(RJP_tree_node* target){
|
||||
while(target->right && target->left){
|
||||
irjp_copy_node(target, target->right);
|
||||
irjp_copy_node_data(target, target->right);
|
||||
target = target->right;
|
||||
}
|
||||
RJP_tree_node* retval = target->parent;
|
||||
@ -370,7 +456,7 @@ static RJP_tree_node* irjp_remove_node(RJP_tree_node* target){
|
||||
irjp_replace_node(to_delete, NULL);
|
||||
to_delete->data.name.value = NULL;
|
||||
to_delete->data.value.type = rjp_json_null;
|
||||
irjp_delete_node(to_delete);
|
||||
irjp_free_node(to_delete);
|
||||
|
||||
//return new root
|
||||
if(!retval)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user