void _rb_traverse(QSP_ARG_DECL qrb_node *np, void (*func)(QSP_ARG_DECL qrb_node *, qrb_tree *), qrb_tree* tree_p ) { if( np == NULL ) return; rb_traverse( np->left, func, tree_p ); (*func)(QSP_ARG np, tree_p); rb_traverse( np->right, func, tree_p ); }
static void _make_rb_tree_list(QSP_ARG_DECL qrb_tree *tree_p) { assert( RB_TREE_ITEM_LIST(tree_p) == NULL ); SET_RB_TREE_ITEM_LIST(tree_p,new_list()); rb_traverse(tree_p->root,_add_rb_node_to_list,tree_p); MARK_RB_TREE_CURRENT(tree_p); }
/* Simple stress test procedure for the red-black tree routines. Does the following: * Generate a random number seed. By default this is generated from the current time. You can also pass an integer seed value on the command line if you want to test the same case. The seed value is displayed. * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 into it, in random order. Verifies and displays the tree structure after each insertion. * Removes each integer from the tree, in a different random order. Verifies and displays the tree structure after each deletion. * Destroys the tree. This is pretty good test code if you write some of your own red-black tree routines. If you do so you will probably want to modify the code below so that it increments the random seed and goes on to new test cases automatically. */ int main(int argc, char **argv) { int array[TREE_SIZE]; struct rb_tree *tree; int i; randomize(argc, argv); for (i = 0; i < TREE_SIZE; i++) array[i] = i; shuffle(array, TREE_SIZE); tree = rb_create(); for (i = 0; i < TREE_SIZE; i++) { int result = rb_insert(tree, array[i]); if (result != 1) { printf("Error %d inserting element %d, %d, into tree.\n", result, i, array[i]); exit(EXIT_FAILURE); } printf("Inserted %d: ", array[i]); /*print_structure(tree->root, 0);*/ rb_walk(tree); putchar('\n'); verify_tree(tree, array); } shuffle(array, TREE_SIZE); for (i = 0; i < TREE_SIZE; i++) { if (rb_delete(tree, array[i]) == 0) { printf("Error removing element %d, %d, from tree.\n", i, array[i]); exit(EXIT_FAILURE); } printf("Removed %d: ", array[i]); /*print_structure(tree->root, 0);*/ rb_traverse(tree); putchar('\n'); verify_tree(tree, array + i + 1); } rb_destroy(tree); printf("Success!\n"); return EXIT_SUCCESS; }
/* Potential optimization, have a static variable for a freelist of rbtree nodes */ int trie_check_word(trie_dict *t, string word, FILE *out, int n_edits){ char *tmp = string_to_cstra(word); // DEBUG_PRINTF("Checking %s\n", tmp); if(trie_dict_lookup(t, word.mem, word.len)){ fprintf(out, "correct: %s\n", tmp); } else { rb_tree *suggs = make_empty_rbtree((int(*)(void*,void*))string_ptr_cmp); fprintf(out, "incorrect: %s\n", tmp); check_edits(t, word, n_edits, suggs); fprintf(out, "suggestions:\n"); rb_traverse(suggs, out, output_suggest_visit); fprintf(out, "\t----\n"); destroy_rbtree_custom(suggs, free); } return 0; }
const void * rbdelete(const void *key, struct rbtree *rbinfo) { struct rbnode *x; const void *y; if (rbinfo==NULL) return(NULL); x=rb_traverse(key, rbinfo); if (x==RBNULL) { return(NULL); } else { y=x->key; rb_delete(&rbinfo->rb_root, x); return(y); } }