1 changed files with 237 additions and 0 deletions
-
237src/binarytree.c
@ -0,0 +1,237 @@ |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
|
|||
struct element |
|||
{ |
|||
int data; |
|||
|
|||
struct element * left; |
|||
struct element * right; |
|||
}; |
|||
|
|||
struct element * |
|||
newElement(int data) |
|||
{ |
|||
struct element * el = malloc(sizeof(struct element)); |
|||
el->data = data; |
|||
el->left = NULL; |
|||
el->right = NULL; |
|||
|
|||
return el; |
|||
} |
|||
|
|||
/** |
|||
* find element in tree |
|||
*/ |
|||
struct element * |
|||
findElement(struct element * tree, int data) |
|||
{ |
|||
while (NULL != tree) { |
|||
if (tree->data == data) { |
|||
break; |
|||
} |
|||
|
|||
if (data < tree->data) { |
|||
tree = tree->left; |
|||
} else { |
|||
tree = tree->right; |
|||
} |
|||
} |
|||
|
|||
return tree; |
|||
} |
|||
|
|||
/** |
|||
* insert element in tree |
|||
*/ |
|||
void |
|||
insertElement(struct element ** tree, int data) |
|||
{ |
|||
struct element ** node = tree; |
|||
|
|||
if (NULL == *node) { |
|||
*node = newElement(data); |
|||
return; |
|||
} |
|||
|
|||
while (data != (*node)->data) { |
|||
if (data < (*node)->data) { |
|||
if (NULL == (*node)->left) { |
|||
(*node)->left = newElement(data); |
|||
return; |
|||
} else { |
|||
*node = (*node)->left; |
|||
} |
|||
} else { |
|||
if (NULL == (*node)->right) { |
|||
(*node)->right = newElement(data); |
|||
return; |
|||
} else { |
|||
*node = (*node)->right; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* delete element from tree |
|||
* here multiple functions are involved.... |
|||
* ======================================================================= |
|||
*/ |
|||
/** |
|||
* find minimum of the right subtree aka leftmost leaf of right subtree |
|||
* aka left in-order successor. |
|||
* We return the parent of the element in the out argument parent. |
|||
* This can be NULL wenn calling. |
|||
*/ |
|||
struct element * |
|||
findInOrderSuccessor(struct element * tree, struct element ** parent) |
|||
{ |
|||
struct element * node = tree->right; |
|||
|
|||
*parent = tree; |
|||
|
|||
while (NULL != node->left) { |
|||
*parent = node; |
|||
node = node->left; |
|||
} |
|||
|
|||
return node; |
|||
} |
|||
|
|||
void |
|||
deleteElement(struct element ** tree, int data) |
|||
{ |
|||
struct element * parent = NULL; |
|||
struct element * node = *tree; |
|||
|
|||
// find the relevant node and it's parent |
|||
while (NULL != node && node->data != data) { |
|||
parent = node; |
|||
|
|||
if (data < node->data) { |
|||
node = node->left; |
|||
} else { |
|||
node = node->right; |
|||
} |
|||
} |
|||
|
|||
// element not found |
|||
if (NULL == node) { |
|||
return; |
|||
} |
|||
|
|||
// distinuish 3 cases, where the resolving of each case leads to the |
|||
// precondition of the other. |
|||
|
|||
// case 1: two children |
|||
if (NULL != node->left && NULL != node->right) { |
|||
struct element * successor = findInOrderSuccessor(node, &parent); |
|||
|
|||
node->data = successor->data; |
|||
node = successor; |
|||
} |
|||
|
|||
// case 2: one child wither left or right |
|||
if (NULL != node->left) { |
|||
node->data = node->left->data; |
|||
parent = node; |
|||
node = parent->left; |
|||
} |
|||
|
|||
if (NULL != node->right) { |
|||
node->data = node->right->data; |
|||
parent = node; |
|||
node = parent->right; |
|||
} |
|||
|
|||
// case 3: we are a leaf |
|||
if (NULL != parent) { |
|||
if (node == parent->left) { |
|||
parent->left = NULL; |
|||
} else { |
|||
parent->right = NULL; |
|||
} |
|||
} |
|||
|
|||
free(node); |
|||
if (node == *tree) { |
|||
*tree = NULL; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ======================================================================= |
|||
*/ |
|||
int |
|||
main(int argc, char * argv[]) |
|||
{ |
|||
struct element * root = NULL; |
|||
|
|||
puts ("insert 5:\n"); |
|||
insertElement(&root, 5); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("insert 4:\n"); |
|||
insertElement(&root, 4); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("insert 5:\n"); |
|||
insertElement(&root, 5); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("insert 6:\n"); |
|||
insertElement(&root, 6); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("delete 5 (one child on both sides):\n"); |
|||
deleteElement(&root, 5); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("delete 6 (one child on the left):\n"); |
|||
deleteElement(&root, 6); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("insert 6:\n"); |
|||
insertElement(&root, 6); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("delete 6 (a leaf):\n"); |
|||
deleteElement(&root, 6); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
puts ("delete 4 (a leaf and root):\n"); |
|||
deleteElement(&root, 4); |
|||
printf("R: 0x%p\n", root); |
|||
printf("4: 0x%p\n", findElement(root, 4)); |
|||
printf("5: 0x%p\n", findElement(root, 5)); |
|||
printf("6: 0x%p\n\n", findElement(root, 6)); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
// vim: set et ts=4 sw=4: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue