rbtree
changeset 3:53afe96233f2
changed the tail-recursive find and find_min to loops
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Sun, 09 Oct 2011 08:30:54 +0300 |
parents | 7205a7d8d3d6 |
children | c4f36d709ee9 |
files | src/rbtree.c test/test.c |
diffstat | 2 files changed, 32 insertions(+), 23 deletions(-) [+] |
line diff
1.1 --- a/src/rbtree.c Sun Oct 09 07:55:51 2011 +0300 1.2 +++ b/src/rbtree.c Sun Oct 09 08:30:54 2011 +0300 1.3 @@ -26,7 +26,7 @@ 1.4 static void del_tree(struct rbnode *node, void (*delfunc)(struct rbnode*, void*), void *cls); 1.5 static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data); 1.6 static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key); 1.7 -static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key); 1.8 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key);*/ 1.9 static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls); 1.10 1.11 struct rbtree *rb_create(rb_cmp_func_t cmp_func) 1.12 @@ -127,12 +127,21 @@ 1.13 1.14 void *rb_find(struct rbtree *rb, void *key) 1.15 { 1.16 - return find(rb, rb->root, key); 1.17 + struct rbnode *node = rb->root; 1.18 + 1.19 + while(node) { 1.20 + int cmp = rb->cmp(key, node->key); 1.21 + if(cmp == 0) { 1.22 + return node; 1.23 + } 1.24 + node = cmp < 0 ? node->left : node->right; 1.25 + } 1.26 + return 0; 1.27 } 1.28 1.29 void *rb_findi(struct rbtree *rb, int key) 1.30 { 1.31 - return find(rb, rb->root, INT2PTR(key)); 1.32 + return rb_find(rb, INT2PTR(key)); 1.33 } 1.34 1.35 1.36 @@ -322,7 +331,7 @@ 1.37 return fix_up(tree); 1.38 } 1.39 1.40 -static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key) 1.41 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key) 1.42 { 1.43 int cmp; 1.44 1.45 @@ -333,7 +342,7 @@ 1.46 return node; 1.47 } 1.48 return find(rb, cmp < 0 ? node->left : node->right, key); 1.49 -} 1.50 +}*/ 1.51 1.52 static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls) 1.53 { 1.54 @@ -381,10 +390,15 @@ 1.55 1.56 static struct rbnode *find_min(struct rbnode *tree) 1.57 { 1.58 - if(!tree || !tree->left) { 1.59 - return tree; 1.60 + struct rbnode *node; 1.61 + 1.62 + if(!tree) 1.63 + return 0; 1.64 + 1.65 + while(node->left) { 1.66 + node = node->left; 1.67 } 1.68 - return find_min(tree->left); 1.69 + return node; 1.70 } 1.71 1.72 static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree)
2.1 --- a/test/test.c Sun Oct 09 07:55:51 2011 +0300 2.2 +++ b/test/test.c Sun Oct 09 08:30:54 2011 +0300 2.3 @@ -102,7 +102,7 @@ 2.4 glLoadIdentity(); 2.5 2.6 if(input_buffer[0]) { 2.7 - char *prompt = "select node to delete: "; 2.8 + char *prompt = "select node: "; 2.9 char *buf = alloca(strlen(prompt) + strlen(input_buffer)); 2.10 2.11 glPushMatrix(); 2.12 @@ -304,23 +304,12 @@ 2.13 { 2.14 static int wposx = -1, wposy; 2.15 static char *inp_next; 2.16 + static char op; 2.17 2.18 switch(key) { 2.19 case 27: 2.20 exit(0); 2.21 2.22 - case 'f': 2.23 - case 'F': 2.24 - if(wposx >= 0) { 2.25 - glutPositionWindow(wposx, wposy); 2.26 - wposx = -1; 2.27 - } else { 2.28 - wposx = glutGet(GLUT_WINDOW_X); 2.29 - wposy = glutGet(GLUT_WINDOW_Y); 2.30 - glutFullScreen(); 2.31 - } 2.32 - break; 2.33 - 2.34 case 'a': 2.35 rb_inserti(tree, num_nodes++, 0); 2.36 glutPostRedisplay(); 2.37 @@ -339,6 +328,8 @@ 2.38 break; 2.39 2.40 case 'd': 2.41 + case 'f': 2.42 + op = key; 2.43 inp_next = input_buffer; 2.44 *inp_next++ = ' '; 2.45 *inp_next = 0; 2.46 @@ -383,8 +374,12 @@ 2.47 } else if(!rb_findi(tree, x)) { 2.48 fprintf(stderr, "%d not found in the tree\n", x); 2.49 } else { 2.50 - printf("deleting: %d\n", x); 2.51 - rb_deletei(tree, x); 2.52 + if(op == 'd') { 2.53 + printf("deleting: %d\n", x); 2.54 + rb_deletei(tree, x); 2.55 + } else { 2.56 + printf("%d found!\n", x); 2.57 + } 2.58 } 2.59 input_buffer[0] = 0; 2.60 glutPostRedisplay();