static void bstree_copy_sort( bstree bst, unsigned int node, bstree_node *array, unsigned int *index){ static int bstree_shrink( bstree bst); static int bstree_node_find( const bstree bst, const unsigned int *node, KEYTYPE key, VALUETYPE *value){ if( key == bst->array[*node].key ){ *value = bst->array[*node].value; return BSTREE_SUCCESS; } if( COMP(key, bst->array[*node].key) < 0 ){ if( bst->array[*node].left != NODE_NULL ){ return bstree_node_find( bst, &(bst->array[node].left), key, value); } }else{ if( bst->array[node].right != NODE_NULL ){ return bstree_node_find( bst, &(bst->array[node].right), key, value); } } return BSTREE_FAILURE; } static int bstree_node_insert( bstree bst, unsigned int *node, KEYTYPE key, VALUETYPE value){ int status; if( *node == NODE_NULL){ if( bst->max_pos == bst->array_size ){ if( bstree_grow( bst) == BSTREE_MEM_ERROR ){ return BSTREE_MEM_ERROR; } } *node = bstree->max_pos; bst->array[*node].left = NODE_NULL; bst->array[*node].right = NODE_NULL; bst->array[*node].key = key; bst->array[*node].value = value; bst->array[*node].level = 1; (bst->max_pos)++; (bst->size)++; return BSTREE_SUCCESS; } if( key == bst->array[*node].key ){ bst->array[*node].value += value; return BSTREE_SUCCESS; } if( COMP( key, bst->array[*node].key) < 0 ){ status = bstree_node_insert( bst, &(bst->array[node].left), key, value); }else{ status = bstree_node_insert( bst, &(bst->array[node].right), key, value); } skew( bst, node); split( bst, node); return status; }
int bstree_init( bstree_t *tree_in, long step_in, int (*compf_in)(void*,void*) ) { tree_in->start = NULL; tree_in->root = -1; tree_in->step = step_in; tree_in->size = 0; tree_in->alloc = 0; tree_in->compf = compf_in; tree_in->min = -1; tree_in->max = -1; if( bstree_grow( tree_in, BTREE_SIZE_INC ) < 0 ) /* All non-success return codes will be < 0 */ return -1; /* allocate the and initialize the NIL node */ bsnode_init( tree_in->start - 1, tree_in->step ); tree_in->start[-1].color = BLACK; return 0; }
int bstree_insert( bstree_t *tree_in, void *data_in, long key_in, long *idx_out ) { /* Grow with bstree_grow() if necessary */ if( tree_in->alloc < tree_in->size + 1 ) if( bstree_grow( tree_in, BTREE_SIZE_INC ) < 0 ) return -1; /* It's a sick sad world... I hate my f*****g life */ char usecomp; long cur = tree_in->root; long temp = -1; if( tree_in->compf == NULL ) { usecomp = 0; while( cur != -1 ) { temp = cur; if( key_in < tree_in->start[cur].key ) cur = tree_in->start[cur].left; else cur = tree_in->start[cur].right; } } else { usecomp = 1; while( cur != -1 ) { temp = cur; if( tree_in->compf( data_in, tree_in->start[cur].data ) < 0 ) cur = tree_in->start[cur].left; else cur = tree_in->start[cur].right; } } /* Set the data */ bstree_avail( tree_in, &cur ); /* Find a free spot and bsnode_reset() it */ if( idx_out != NULL ) *idx_out = cur; bsnode_reset( tree_in->start + cur ); /* makes sure left and right are NULL and key has no value until set */ tree_in->start[cur].parent = temp; tree_in->start[cur].key = key_in; /* regardless of order relation, copy the key */ if( data_in != NULL ) bcopy( data_in, tree_in->start[cur].data, tree_in->step ); else if( usecomp == 1 ) /* use compare function, compf */ return -1; /* fail if data_in is NULL and usecomp indicates that order relation relies on data only, not key */ tree_in->start[cur].avail = 1; /* now set cur's location relative to rest of tree */ if( temp != -1 ) { if( usecomp == 0 ) { if( key_in < tree_in->start[temp].key ) tree_in->start[temp].left = cur; else tree_in->start[temp].right = cur; } else { if( tree_in->compf( data_in, tree_in->start[temp].data ) < 0 ) tree_in->start[temp].left = cur; else tree_in->start[temp].right = cur; } } else tree_in->root = cur; /* if added successfully increment size */ ++tree_in->size; /* now set min and max */ if( tree_in->size > 1 ) { if( tree_in->compf == NULL ) { if( tree_in->start[cur].key < tree_in->start[tree_in->min].key ) tree_in->min = cur; else if( tree_in->start[cur].key > tree_in->start[tree_in->max].key ) tree_in->max = cur; } else { if( tree_in->compf( tree_in->start[cur].data, tree_in->start[tree_in->min].data ) < 0 ) tree_in->min = cur; else if( tree_in->compf( tree_in->start[cur].data, tree_in->start[tree_in->max].data ) > 0 ) tree_in->max = cur; } } else { /* initialize when no comparison can be made */ tree_in->min = cur; tree_in->max = cur; } return 0; }