diff --git a/src/binarytree.c b/src/binarytree.c index 623985a..681f3b0 100644 --- a/src/binarytree.c +++ b/src/binarytree.c @@ -5,6 +5,7 @@ struct element { int data; + struct element * parent; struct element * left; struct element * right; }; @@ -13,9 +14,10 @@ struct element * newElement(int data) { struct element * el = malloc(sizeof(struct element)); - el->data = data; - el->left = NULL; - el->right = NULL; + el->data = data; + el->parent = NULL; + el->left = NULL; + el->right = NULL; return el; } @@ -57,14 +59,16 @@ insertElement(struct element ** tree, int data) while (data != (*node)->data) { if (data < (*node)->data) { if (NULL == (*node)->left) { - (*node)->left = newElement(data); + (*node)->left = newElement(data); + (*node)->left->parent = *node; return; } else { *node = (*node)->left; } } else { if (NULL == (*node)->right) { - (*node)->right = newElement(data); + (*node)->right = newElement(data); + (*node)->right->parent = *node; return; } else { *node = (*node)->right; @@ -85,15 +89,12 @@ insertElement(struct element ** tree, int data) * This can be NULL wenn calling. */ struct element * -findInOrderSuccessor(struct element * tree, struct element ** parent) +findInOrderSuccessor(struct element * tree) { struct element * node = tree->right; - *parent = tree; - while (NULL != node->left) { - *parent = node; - node = node->left; + node = node->left; } return node; @@ -126,9 +127,10 @@ deleteElement(struct element ** tree, int data) // case 1: two children if (NULL != node->left && NULL != node->right) { - struct element * successor = findInOrderSuccessor(node, &parent); + struct element * successor = findInOrderSuccessor(node); node->data = successor->data; + parent = successor->parent; node = successor; } @@ -160,6 +162,55 @@ deleteElement(struct element ** tree, int data) } } + +void +traverse(struct element * tree, void (*cb)(int, int)) +{ + struct element * previous = NULL; + struct element * node = tree; + int depth = 1; + + while (tree) { + /* we came from a left node */ + if ((NULL == node->left || previous == node->left) && + previous != node->right) { + + cb(node->data, depth); + previous = node; + + if (NULL != node->right) { + node = node->right; + depth++; + } else { + if (node->parent->right == node) { + break; + } + + node = node->parent; + depth--; + } + } else { + previous = node; + + if (previous == node->left || previous == node->right) { + node = node->parent; + depth--; + } else { + node = node->left; + depth++; + } + } + } +} + +void printElement(int data, int depth) +{ + char format[250]; + + sprintf(format, "%% %dd(%%d)\n", depth * 3); + printf(format, data, depth); +} + /** * ======================================================================= */ @@ -196,6 +247,10 @@ main(int argc, char * argv[]) printf("5: 0x%p\n", findElement(root, 5)); printf("6: 0x%p\n\n", findElement(root, 6)); + puts ("traverse"); + traverse(root, printElement); + puts ("\n"); + puts ("delete 5 (one child on both sides):\n"); deleteElement(&root, 5); printf("R: 0x%p\n", root);