From 91fb78752208b66284413a15261751e330af7e36 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Sun, 2 Dec 2018 07:46:07 +0800 Subject: [PATCH] BST in c --- c-cpp/24_binarysearchtree/bst.c | 197 ++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 c-cpp/24_binarysearchtree/bst.c diff --git a/c-cpp/24_binarysearchtree/bst.c b/c-cpp/24_binarysearchtree/bst.c new file mode 100644 index 0000000..7fdfd87 --- /dev/null +++ b/c-cpp/24_binarysearchtree/bst.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include + +enum child_dir { + left_child, + right_child, + root, +}; + +struct node { + unsigned long data; + struct node *left; + struct node *right; +}; + +struct root { + struct node *r; +}; + +void dump(struct node *node, int level, enum child_dir dir) +{ + if (!node) + return; + + dump(node->right, level + 1, right_child); + + if (dir == left_child) + printf("%*s\n", level*3, "|"); + + printf("%*s - %05lu\n", level*3, " ", node->data); + + if (dir == right_child) + printf("%*s\n", level*3, "|"); + + dump(node->left, level + 1, left_child); +} + +struct node* find(struct root *root, unsigned long data) +{ + struct node* n = root->r; + + while (n) { + if (n->data == data) + return n; + if (data < n->data) + n = n->left; + else + n = n->right; + } + + return NULL; +} + +struct node* new_node(unsigned long data) +{ + struct node *n; + + n = malloc(sizeof(struct node)); + + n->data = data; + n->left = n->right = NULL; + return n; +} + +void insert(struct root *root, struct node *new) +{ + struct node *parent; + + if (!root->r) { + root->r = new; + return; + } + + parent = root->r; + + while (true) { + /* Don't support duplicate data */ + if (new->data == parent->data) + break; + + if (new->data < parent->data) { + if (!parent->left) { + parent->left = new; + break; + } + parent = parent->left; + } else { + if (!parent->right) { + parent->right = new; + break; + } + parent = parent->right; + } + } +} + +struct node* delete(struct root *root, unsigned long data) +{ + struct node *n = root->r, **p = &root->r; + struct node *child; + + while (n && n->data != data) { + if (data < n->data) { + p = &n->left; + n = n->left; + } else { + p = &n->right; + n = n->right; + } + } + + if (!n) + return NULL; + + if (n->left && n->right) { + struct node *rn = n->right, **rp = &n->right; + + while (rn->left) { + rp = &rn->left; + rn = rn->left; + } + + n->data = rn->data; + n = rn; + p = rp; + } + + child = n->left ? n->left : n->right; + *p = child; + + return NULL; +} + +void insert_test() +{ + struct root tree; + struct node* n; + + tree.r = NULL; + + insert(&tree, new_node(9)); + + insert(&tree, new_node(5)); + insert(&tree, new_node(2)); + insert(&tree, new_node(8)); + + insert(&tree, new_node(18)); + insert(&tree, new_node(13)); + insert(&tree, new_node(21)); + insert(&tree, new_node(20)); + + dump(tree.r, 0, root); + + n = find(&tree, 18); + if (n && n->data == 18) + printf("Get 18\n"); + +} + +void delete_test() +{ + struct root tree; + struct node* n; + + tree.r = NULL; + + insert(&tree, new_node(9)); + + insert(&tree, new_node(5)); + insert(&tree, new_node(2)); + insert(&tree, new_node(8)); + + insert(&tree, new_node(18)); + insert(&tree, new_node(13)); + insert(&tree, new_node(21)); + insert(&tree, new_node(20)); + + dump(tree.r, 0, root); + + delete(&tree, 20); + printf("Delete 20\n"); + dump(tree.r, 0, root); + + delete(&tree, 9); + printf("Delete 9\n"); + dump(tree.r, 0, root); +} + +int main() +{ + //insert_test(); + delete_test(); + return 0; +}