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; +} diff --git a/c-cpp/28_heap/heap.c b/c-cpp/28_heap/heap.c new file mode 100644 index 0000000..6bd872d --- /dev/null +++ b/c-cpp/28_heap/heap.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include + +/* Implement heap */ + +#define MAX_HEAP_SIZE (1 << 8) + +struct element { + int data; +}; + +struct heap { + union { + unsigned long elements; + struct element *elem[MAX_HEAP_SIZE]; + }; +}; + +void init_heap(struct heap *heap) +{ + int i; + + for(i = 0; i < MAX_HEAP_SIZE; i++) { + heap->elem[i] = NULL; + } +} + +void dump_heap(struct heap *heap, int index) +{ + struct element *elem; + int level; + + if (index > heap->elements) + return; + + elem = heap->elem[index]; + level = fls(index); + + dump_heap(heap, index * 2 + 1); + + if (!(index % 2) && index != 1) + printf("%*s\n", level*3, "|"); + + printf("%*s - %05d\n", level*3, " ", elem->data); + + if (index % 2 && index != 1) + printf("%*s\n", level*3, "|"); + + dump_heap(heap, index * 2); +} + +void dump(struct heap *heap, int elements) +{ + int i; + + for (i = 1; i <= elements; i++) + printf("[%02d]: %4d\n", i, heap->elem[i]->data); + +} + +struct element* create_element(int data) +{ + struct element *elem; + + elem = malloc(sizeof(struct element)); + + if (elem) + elem->data = data; + + return elem; +} + +void fake_a_heap(struct heap *heap) +{ + /* data is in ordered */ + int i, data[10] = {7, 4, 9, 2, 6, 8, 10, 1, 3, 5}; + + init_heap(heap); + + /* root start at 1 */ + for (i = 0; i < 10; i++) + heap->elem[i+1] = create_element(data[i]); + + heap->elements = 10; +} + +void swap(struct heap *heap, int i, int j) +{ + struct element *tmp; + + tmp = heap->elem[j]; + heap->elem[j] = heap->elem[i]; + heap->elem[i] = tmp; +} + +void heapify(struct heap *heap, int parent) +{ + struct element **elem = heap->elem; + int elements = heap->elements; + int left, right, max; + + while (true) { + left = parent * 2; + right = left + 1; + + max = parent; + if (left <= elements && elem[max]->data < elem[left]->data) + max = left; + if (right <= elements && elem[max]->data < elem[right]->data) + max = right; + + if (max == parent) + break; + + swap(heap, max, parent); + parent = max; + } +} + +void build_heap(struct heap *heap) +{ + int i; + + for (i = heap->elements / 2; i >= 1; i--) + heapify(heap, i); +} + +int heap_sort(struct heap *heap) +{ + int elements = heap->elements; + + while (heap->elements) { + swap(heap, 1, heap->elements); + heap->elements--; + heapify(heap, 1); + } + + return elements; +} + +int main() +{ + struct heap heap; + int elements; + + fake_a_heap(&heap); + dump_heap(&heap, 1); + + printf("After Heapify:\n"); + build_heap(&heap); + dump_heap(&heap, 1); + + printf("After Heap sort:\n"); + elements = heap_sort(&heap); + dump(&heap, elements); + return 0; +}