diff options
Diffstat (limited to 'tree.c')
| -rw-r--r-- | tree.c | 103 |
1 files changed, 75 insertions, 28 deletions
| @@ -1,9 +1,9 @@ | |||
| 1 | // Binary Search Tree | 1 | // Binary Search Tree |
| 2 | #include <limits.h> | ||
| 3 | #include <stdbool.h> | ||
| 2 | #include <stdio.h> | 4 | #include <stdio.h> |
| 3 | #include <stdlib.h> | 5 | #include <stdlib.h> |
| 4 | #include <stdbool.h> | ||
| 5 | #include <time.h> | 6 | #include <time.h> |
| 6 | #include <limits.h> | ||
| 7 | 7 | ||
| 8 | #include "util.h" | 8 | #include "util.h" |
| 9 | 9 | ||
| @@ -11,9 +11,9 @@ typedef int T; | |||
| 11 | 11 | ||
| 12 | struct tree_node { | 12 | struct tree_node { |
| 13 | struct tree_node *left, *right; | 13 | struct tree_node *left, *right; |
| 14 | T key; | 14 | T key; |
| 15 | int count; /* collision counter */ | 15 | int count; /* collision counter */ |
| 16 | /* ggf. weitere Felder... */ | 16 | /* ggf. weitere Felder... */ |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | static bool tree_isBstUntil(struct tree_node *tree, int min, int max); | 19 | static bool tree_isBstUntil(struct tree_node *tree, int min, int max); |
| @@ -34,7 +34,7 @@ tree_isBstUntil(struct tree_node *tree, int min, int max) | |||
| 34 | return false; | 34 | return false; |
| 35 | 35 | ||
| 36 | return tree_isBstUntil(tree->left, min, tree->key - 1) && | 36 | return tree_isBstUntil(tree->left, min, tree->key - 1) && |
| 37 | tree_isBstUntil(tree->right, tree->key + 1, max); | 37 | tree_isBstUntil(tree->right, tree->key + 1, max); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | struct tree_node * | 40 | struct tree_node * |
| @@ -43,7 +43,7 @@ tree_insert(struct tree_node *tree, T key) | |||
| 43 | if ( tree == NULL ) { | 43 | if ( tree == NULL ) { |
| 44 | tree = malloc(sizeof *tree); | 44 | tree = malloc(sizeof *tree); |
| 45 | if ( tree != NULL ) { | 45 | if ( tree != NULL ) { |
| 46 | tree->key = key; | 46 | tree->key = key; |
| 47 | tree->count = 1; | 47 | tree->count = 1; |
| 48 | tree->left = tree->right = NULL; | 48 | tree->left = tree->right = NULL; |
| 49 | } | 49 | } |
| @@ -54,12 +54,59 @@ tree_insert(struct tree_node *tree, T key) | |||
| 54 | tree->left = tree_insert(tree->left, key); | 54 | tree->left = tree_insert(tree->left, key); |
| 55 | else if ( key > tree->key ) | 55 | else if ( key > tree->key ) |
| 56 | tree->right = tree_insert(tree->right, key); | 56 | tree->right = tree_insert(tree->right, key); |
| 57 | else /* key == tree->key */ | 57 | else /* key == tree->key */ |
| 58 | tree->count++; /* handle collision */ | 58 | tree->count++; /* handle collision */ |
| 59 | 59 | ||
| 60 | return tree; | 60 | return tree; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | struct tree_node * | ||
| 64 | tree_insert_it(struct tree_node *root, T key) | ||
| 65 | { | ||
| 66 | struct tree_node *parent = NULL, | ||
| 67 | *curr = root; | ||
| 68 | |||
| 69 | while ( curr != NULL ) { | ||
| 70 | parent = curr; | ||
| 71 | |||
| 72 | if ( key < curr->key ) { | ||
| 73 | curr = curr->left; | ||
| 74 | } | ||
| 75 | else if ( key > curr->key ) { | ||
| 76 | curr = curr->right; | ||
| 77 | } | ||
| 78 | else { /* key == current->key */ | ||
| 79 | curr->count++; | ||
| 80 | return root; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | struct tree_node *new_node; | ||
| 85 | |||
| 86 | new_node = malloc(sizeof *new_node); | ||
| 87 | if ( new_node != NULL ) { | ||
| 88 | new_node->key = key; | ||
| 89 | new_node->count = 1; | ||
| 90 | new_node->left = NULL; | ||
| 91 | new_node->right = NULL; | ||
| 92 | |||
| 93 | if ( parent == NULL ) { | ||
| 94 | root = new_node; | ||
| 95 | } | ||
| 96 | else if ( key < parent->key ) { | ||
| 97 | parent->left = new_node; | ||
| 98 | } | ||
| 99 | else { | ||
| 100 | parent->right = new_node; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | else { | ||
| 104 | ERROR("out of memory"); | ||
| 105 | } | ||
| 106 | |||
| 107 | return root; | ||
| 108 | } | ||
| 109 | |||
| 63 | static struct tree_node * | 110 | static struct tree_node * |
| 64 | tree_detach_min(struct tree_node **ptree) | 111 | tree_detach_min(struct tree_node **ptree) |
| 65 | { | 112 | { |
| @@ -99,7 +146,7 @@ tree_remove(struct tree_node *tree, T key) | |||
| 99 | else { | 146 | else { |
| 100 | struct tree_node *min = tree_detach_min(&tree->right); | 147 | struct tree_node *min = tree_detach_min(&tree->right); |
| 101 | 148 | ||
| 102 | min->left = tree->left; | 149 | min->left = tree->left; |
| 103 | min->right = tree->right; | 150 | min->right = tree->right; |
| 104 | 151 | ||
| 105 | tree = min; | 152 | tree = min; |
| @@ -161,7 +208,7 @@ tree_height(struct tree_node *tree) | |||
| 161 | size_t hl = tree_height(tree->left); | 208 | size_t hl = tree_height(tree->left); |
| 162 | size_t hr = tree_height(tree->right); | 209 | size_t hr = tree_height(tree->right); |
| 163 | 210 | ||
| 164 | return (( hl > hr ) ? hl : hr) + 1; | 211 | return ((hl > hr) ? hl : hr) + 1; |
| 165 | } | 212 | } |
| 166 | 213 | ||
| 167 | return 0; | 214 | return 0; |
| @@ -210,7 +257,7 @@ tree_apply_postorder(struct tree_node *tree, void (*visit)(T key, void *cl), voi | |||
| 210 | 257 | ||
| 211 | struct stack_item { | 258 | struct stack_item { |
| 212 | struct stack_item *next; | 259 | struct stack_item *next; |
| 213 | struct tree_node *data; | 260 | struct tree_node * data; |
| 214 | }; | 261 | }; |
| 215 | 262 | ||
| 216 | struct stack { | 263 | struct stack { |
| @@ -231,7 +278,7 @@ stack_push(struct stack *stack, struct tree_node *data) | |||
| 231 | if ( (new_item = malloc(sizeof(*new_item))) != NULL ) { | 278 | if ( (new_item = malloc(sizeof(*new_item))) != NULL ) { |
| 232 | new_item->data = data; | 279 | new_item->data = data; |
| 233 | new_item->next = stack->head; | 280 | new_item->next = stack->head; |
| 234 | stack->head = new_item; | 281 | stack->head = new_item; |
| 235 | } | 282 | } |
| 236 | else | 283 | else |
| 237 | ERROR("out of memory"); | 284 | ERROR("out of memory"); |
| @@ -242,7 +289,7 @@ stack_pop(struct stack *stack, struct tree_node **data) | |||
| 242 | { | 289 | { |
| 243 | if ( stack->head != NULL ) { | 290 | if ( stack->head != NULL ) { |
| 244 | struct stack_item *next = stack->head->next; | 291 | struct stack_item *next = stack->head->next; |
| 245 | *data = stack->head->data; | 292 | *data = stack->head->data; |
| 246 | free(stack->head); | 293 | free(stack->head); |
| 247 | stack->head = next; | 294 | stack->head = next; |
| 248 | 295 | ||
| @@ -282,8 +329,10 @@ tree_apply_preorder_it(struct tree_node *tree, void (*visit)(T key, void *cl), v | |||
| 282 | while ( stack_pop(&stack, &tree) ) { | 329 | while ( stack_pop(&stack, &tree) ) { |
| 283 | visit(tree->key, cl); | 330 | visit(tree->key, cl); |
| 284 | 331 | ||
| 285 | if ( tree->right != NULL ) stack_push(&stack, tree->right); | 332 | if ( tree->right != NULL ) |
| 286 | if ( tree->left != NULL ) stack_push(&stack, tree->left ); | 333 | stack_push(&stack, tree->right); |
| 334 | if ( tree->left != NULL ) | ||
| 335 | stack_push(&stack, tree->left); | ||
| 287 | } | 336 | } |
| 288 | 337 | ||
| 289 | stack_free(&stack); | 338 | stack_free(&stack); |
| @@ -358,7 +407,6 @@ tree_iterator_free(struct tree_iterator *it) | |||
| 358 | 407 | ||
| 359 | /* ===== */ | 408 | /* ===== */ |
| 360 | 409 | ||
| 361 | |||
| 362 | void | 410 | void |
| 363 | print(T data, void *cl) | 411 | print(T data, void *cl) |
| 364 | { | 412 | { |
| @@ -372,7 +420,7 @@ int | |||
| 372 | main_(void) | 420 | main_(void) |
| 373 | { | 421 | { |
| 374 | // Teste den Fall von mycodeschool | 422 | // Teste den Fall von mycodeschool |
| 375 | 423 | ||
| 376 | struct tree_node *tree = NULL; | 424 | struct tree_node *tree = NULL; |
| 377 | 425 | ||
| 378 | tree = tree_insert(tree, 12); | 426 | tree = tree_insert(tree, 12); |
| @@ -400,7 +448,7 @@ main_(void) | |||
| 400 | show_tree(tree, 0, 0); | 448 | show_tree(tree, 0, 0); |
| 401 | 449 | ||
| 402 | tree_clear(tree); | 450 | tree_clear(tree); |
| 403 | 451 | ||
| 404 | return EXIT_SUCCESS; | 452 | return EXIT_SUCCESS; |
| 405 | } | 453 | } |
| 406 | 454 | ||
| @@ -433,26 +481,25 @@ main__(void) | |||
| 433 | return EXIT_SUCCESS; | 481 | return EXIT_SUCCESS; |
| 434 | } | 482 | } |
| 435 | 483 | ||
| 436 | |||
| 437 | int | 484 | int |
| 438 | main(void) | 485 | main(void) |
| 439 | { | 486 | { |
| 440 | struct tree_node *tree = NULL; | 487 | struct tree_node *tree = NULL; |
| 441 | 488 | ||
| 442 | tree = tree_insert(tree, 10); | 489 | tree = tree_insert_it(tree, 10); |
| 443 | tree = tree_insert(tree, 5); | 490 | tree = tree_insert_it(tree, 5); |
| 444 | tree = tree_insert(tree, 20); | 491 | tree = tree_insert_it(tree, 20); |
| 445 | tree = tree_insert(tree, 1); | 492 | tree = tree_insert_it(tree, 1); |
| 446 | tree = tree_insert(tree, 7); | 493 | tree = tree_insert_it(tree, 7); |
| 447 | tree = tree_insert(tree, 15); | 494 | tree = tree_insert_it(tree, 15); |
| 448 | tree = tree_insert(tree, 18); | 495 | tree = tree_insert_it(tree, 18); |
| 449 | 496 | ||
| 450 | tree_apply_preorder(tree, print, NULL); | 497 | tree_apply_preorder(tree, print, NULL); |
| 451 | 498 | ||
| 452 | show_tree(tree, 0, 0); | 499 | show_tree(tree, 0, 0); |
| 453 | 500 | ||
| 454 | struct tree_iterator it; | 501 | struct tree_iterator it; |
| 455 | struct tree_node *node = tree_iterator_first(&it, tree); | 502 | struct tree_node * node = tree_iterator_first(&it, tree); |
| 456 | while ( node ) { | 503 | while ( node ) { |
| 457 | fprintf(stdout, "%d\n", node->key); | 504 | fprintf(stdout, "%d\n", node->key); |
| 458 | 505 | ||
