Skip to content

Instantly share code, notes, and snippets.

@razpeitia
Created May 19, 2013 22:30
Show Gist options
  • Save razpeitia/5609319 to your computer and use it in GitHub Desktop.
Save razpeitia/5609319 to your computer and use it in GitHub Desktop.
Queue and Binary Tree. Implementation.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
struct node *next;
void *data;
} NODE;
typedef struct queue {
NODE *back;
NODE *front;
int size;
void* (*allocate_node_data)();
void (*free_node_data)(void *data);
void (*print_node_data)(void *data);
} QUEUE;
QUEUE* create_queue(void*(*allocate_node_data)(),
void(*free_node_datra)(void *),
void(*print_node_data)(void *)) {
QUEUE *q = (QUEUE*) malloc(sizeof(QUEUE));
if(q == NULL)
return q;
q->back = NULL;
q->front = NULL;
q->size = 0;
q->allocate_node_data = allocate_node_data;
q->free_node_data = free_node_datra;
q->print_node_data = print_node_data;
return q;
}
int empty(QUEUE *q) {
if(q == NULL || q->front == NULL)
return 1;
return 0;
}
void enqueue(QUEUE *q, void *data) {
if(q == NULL)
return;
NODE *pnew = (NODE*) malloc(sizeof(NODE));
if(pnew == NULL)
return;
pnew->data = data;
pnew->next = NULL;
if(q->back == NULL)
q->front = pnew;
else
q->back->next = pnew;
q->back = pnew;
q->size++;
}
void dequeue(QUEUE *q){
if(q == NULL || q->front == NULL)
return;
NODE *p = q->front;
q->front = q->front->next;
if(q->front == NULL)
q->back = NULL;
if(q->free_node_data != NULL)
q->free_node_data(p->data);
free(p);
q->size--;
}
void print_queue(QUEUE *q) {
if(q == NULL || q->print_node_data == NULL) {
printf("NULL\n");
return;
}
NODE *p;
if(q->front == NULL)
printf("[]\n");
else{
printf("[");
q->print_node_data(q->front->data);
for(p = q->front->next; p != NULL; p = p->next) {
printf(" ");
q->print_node_data(p->data);
}
printf("]\n");
}
}
void* front(QUEUE *q) {
if(q == NULL || q->front == NULL)
return 0;
return q->front->data;
}
void* back(QUEUE *q) {
if(q == NULL || q->back == NULL)
return 0;
return q->back->data;
}
void destroy_queue(QUEUE **q) {
if( q == NULL || *q == NULL )
return;
while( !empty(*q) )
dequeue(*q);
free(*q);
*q = NULL;
}
void* allocate_() {
return malloc(sizeof(int));
}
void free_(void *data) {
free(data);
}
void print_(void *data) {
printf("%d", *((int*)data));
}
typedef struct TREE_NODE TREE_NODE;
typedef struct TREE_NODE {
TREE_NODE *left;
TREE_NODE *right;
void *data;
};
typedef struct {
TREE_NODE *root;
int size;
void* (*allocate_node_data)();
void (*free_node_data)(void *data);
void (*print_node_data)(void *data);
int (*compare)(void *a, void *b);
} TREE;
TREE* create_tree(void*(*allocate_node_data)(),
void(*free_node_data)(void *),
void(*print_node_data)(void *),
int(*compare)(void *, void *)
) {
TREE *t = (TREE*) malloc(sizeof(TREE));
if(t == NULL)
return t;
t->root = NULL;
t->size = 0;
t->allocate_node_data = allocate_node_data;
t->free_node_data = free_node_data;
t->print_node_data = print_node_data;
t->compare = compare;
return t;
}
void add(TREE *t, TREE_NODE *root, TREE_NODE *p){
if(t->compare(root->data, p->data) > 0) {
if(root->left == NULL)
root->left = p;
else
add(t, root->left, p);
}
else {
if(root->right == NULL)
root->right = p;
else
add(t, root->right, p);
}
}
void add_node(TREE *t, void *value){
if(t == NULL)
return;
TREE_NODE *p = (TREE_NODE*)malloc(sizeof(TREE_NODE));
if(p == NULL)
return;
p->left = NULL;
p->right = NULL;
p->data = value;
if(t->root == NULL)
t->root = p;
else
add(t, t->root, p);
t->size++;
}
TREE_NODE* find_node(TREE *t, TREE_NODE *root, int value) {
if(root == NULL) return NULL;
TREE_NODE *a, *b;
if(t->compare(root->data, &value) == 0) return root;
a = find_node(t, root->left, value);
b = find_node(t, root->right, value);
if(a != NULL) return a;
if(b != NULL) return b;
return NULL;
}
TREE_NODE* find(TREE *t, int value) {
if(t == NULL || t->root == NULL) return NULL;
return find_node(t, t->root, value);
}
void destroy(TREE *t, TREE_NODE *root){
if(root != NULL){
destroy(t, root->left);
destroy(t, root->right);
if(t->free_node_data != NULL)
t->free_node_data(root->data);
free(root);
}
}
void destroy_tree(TREE** t){
if(t == NULL || *t == NULL)
return;
destroy(*t, (*t)->root);
free(*t);
*t = NULL;
}
int compare(void *a, void *b) {
if(*(int*)a == *(int*)b)
return 0;
else if(*(int*)a > *(int*)b)
return 1;
else
return -1;
}
void allocate_and_set(TREE *t, int value) {
int *p = t->allocate_node_data();
*p = value;
add_node(t, p);
}
void set_and_enqueue(QUEUE *q, int value) {
int *p = q->allocate_node_data();
*p = value;
enqueue(q, p);
}
int deep_node(TREE_NODE *root, int level) {
if(root == NULL) return level - 1;
int a, b;
a = deep_node(root->right, level+1);
b = deep_node(root->left, level+1);
if(a > b)
return a;
else
return b;
}
int deep(TREE *t) {
if(t == NULL || t->root == NULL) return 0;
return deep_node(t->root, 1);
}
void print_tree(TREE *t) {
if(t == NULL || t->root == NULL) return;
QUEUE *q = create_queue(NULL, NULL, NULL);
QUEUE *qlevel = create_queue(allocate_, free_, print_);
TREE_NODE *n;
int level, old_level, i;
enqueue(q, t->root);
set_and_enqueue(qlevel, 0);
old_level = -1;
while(!empty(q)) {
n = front(q);
dequeue(q);
level = *(int*)front(qlevel);
dequeue(qlevel);
for(i = 0; i < 2*level; i++)
printf(" ");
t->print_node_data(n->data);
printf(" (");
if(n->left != NULL) t->print_node_data(n->left->data);
printf(", ");
if(n->right != NULL) t->print_node_data(n->right->data);
printf(")");
printf("\n");
if(n->right != NULL) {
enqueue(q, n->right);
set_and_enqueue(qlevel, level + 1);
}
if(n->left != NULL) {
enqueue(q, n->left);
set_and_enqueue(qlevel, level + 1);
}
}
printf("\n");
destroy_queue(&q);
destroy_queue(&qlevel);
}
TREE_NODE* get_parent(TREE_NODE *root, TREE_NODE *n) {
if(root == NULL) return NULL;
TREE_NODE *a, *b;
if(root->left == n || root->right == n) return root;
a = get_parent(root->left, n);
b = get_parent(root->right, n);
if(a != NULL) return a;
if(b != NULL) return b;
return NULL;
}
TREE_NODE* get_successor(TREE_NODE *node) {
if(node->right == NULL)
return node;
return get_successor(node->right);
}
void delete_node(TREE *t, TREE_NODE *node) {
if(node == NULL) return;
TREE_NODE *parent, *successor;
if(node->left == NULL && node->right == NULL) {
parent = get_parent(t->root, node);
if(parent != NULL) {
if(parent->right == node) parent->right = NULL;
else parent->left = NULL;
}
t->free_node_data(node->data);
free(node);
}
else if(node->left == NULL && node->right != NULL) {
parent = get_parent(t->root, node);
if(parent != NULL) {
if(parent->right == node) parent->right = node->right;
else parent->left = node->right;
}
t->free_node_data(node->data);
free(node);
}
else if(node->left != NULL && node->right == NULL) {
parent = get_parent(t->root, node);
if(parent != NULL) {
if(parent->right == node) parent->right = node->left;
else parent->left = node->left;
}
t->free_node_data(node->data);
free(node);
}
else {
successor = get_successor(node->left);
t->free_node_data(node->data);
node->data = successor->data;
successor->data = NULL;
delete_node(t, successor);
}
}
int main(){
TREE *t;
TREE_NODE *n;
t = create_tree(allocate_, free_, print_, compare);
/*allocate_and_set(t, 4);
allocate_and_set(t, 3);
allocate_and_set(t, 9);
allocate_and_set(t, 5);
allocate_and_set(t, 8);
allocate_and_set(t, 2);
allocate_and_set(t, 0);
allocate_and_set(t, 6);
allocate_and_set(t, 7);
allocate_and_set(t, 1);*/
allocate_and_set(t, 8);
allocate_and_set(t, 4);
allocate_and_set(t, 12);
allocate_and_set(t, 2);
allocate_and_set(t, 6);
allocate_and_set(t, 10);
allocate_and_set(t, 14);
allocate_and_set(t, 15);
allocate_and_set(t, 13);
allocate_and_set(t, 11);
allocate_and_set(t, 9);
allocate_and_set(t, 7);
allocate_and_set(t, 5);
allocate_and_set(t, 3);
allocate_and_set(t, 1);
n = find(t, 8);
if(n != NULL)
t->print_node_data(n->data);
else
printf("Not found\n");
printf("\n");
print_tree(t);
delete_node(t, n);
print_tree(t);
printf("Tree depth: %d\n", deep(t));
destroy_tree(&t);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment