Merge pull request #176 from RichardWeiYang/master

BST and Heap
This commit is contained in:
wangzheng0822 2018-12-03 14:46:40 +08:00 committed by GitHub
commit bc9abec31f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 357 additions and 0 deletions

View File

@ -0,0 +1,197 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
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;
}

160
c-cpp/28_heap/heap.c Normal file
View File

@ -0,0 +1,160 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
/* 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;
}