Skip to content

Commit

Permalink
add project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkolson committed May 4, 2020
1 parent 16e1be4 commit ad0c34c
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 1 deletion.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
INCLUDE=./include
DEPS=$(wildcard ./deps/*.c)
OBJ=hc_avl_test
SRC=$(wildcard ./src/*.c)

.PHONY=clean

all:
gcc -I $(INCLUDE) -o $(OBJ) \
$(DEPS) \
$(SRC)

clean:
rm -rf $(OBJ)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# avl
# The HamburgChimps AVL Tree
An AVL Tree in C
243 changes: 243 additions & 0 deletions deps/hc_bst.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
#include "hc_bst.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct hc_node {
struct hc_node* left;
struct hc_node* right;
const char* key;
const char* value;
} hc_node;

static hc_node* hc_node_init(const char* k, const char* v) {
hc_node* node = malloc(sizeof(hc_node));
node->left = NULL;
node->right = NULL;

node->key = k;
node->value = v;

return node;
}

static void hc_node_print(hc_node* n) {
printf("\n----------------------------------------------\n");
printf("Key: %s\n", n->key);
printf("Value: %s", n->value);
printf("\n----------------------------------------------\n");
}

static void hc_node_destroy(hc_node** n) {
if (*n == NULL) return;

if ((*n)->left != NULL) hc_node_destroy(&(*n)->left);
if ((*n)->right != NULL) hc_node_destroy(&(*n)->right);

free(*n);
*n = NULL;
}

hc_bst* hc_bst_init() {
hc_bst* tree = malloc(sizeof(hc_bst));
tree->root = NULL;
return tree;
}

static void hc_bst_insert_worker(hc_node** n, const char* k, const char* v) {
if (*n == NULL) {
*n = hc_node_init(k, v);
return;
}

int cmp_res = strcmp(k, (*n)->key);
if (cmp_res < 0) {
return hc_bst_insert_worker(&(*n)->left, k, v);
}

if (cmp_res > 0) {
return hc_bst_insert_worker(&(*n)->right, k, v);
}
}

void hc_bst_insert(hc_bst* t, const char* k, const char* v) {
hc_bst_insert_worker(&t->root, k, v);
}

static hc_node** hc_bst_get_worker(hc_node** n, const char* k) {
if (*n == NULL) return NULL;

int cmp_res = strcmp(k, (*n)->key);
if (cmp_res == 0) return n;
if (cmp_res < 0) return hc_bst_get_worker(&(*n)->left, k);
if (cmp_res > 0) return hc_bst_get_worker(&(*n)->right, k);

return NULL;
}

const char* hc_bst_get(hc_bst* t, const char* k) {
if (k == NULL) return NULL;

hc_node** n = hc_bst_get_worker(&t->root, k);

if (n == NULL) return NULL;
return (*n)->value;
}

static void hc_bst_traverse_pre_order(hc_node* n) {
if (n == NULL) return;

hc_node_print(n);
hc_bst_traverse_pre_order(n->left);
hc_bst_traverse_pre_order(n->right);
}

static void hc_bst_traverse_in_order(hc_node* n) {
if (n == NULL) return;

hc_bst_traverse_in_order(n->left);
hc_node_print(n);
hc_bst_traverse_in_order(n->right);
}

static void hc_bst_traverse_post_order(hc_node* n) {
if (n == NULL) return;

hc_bst_traverse_post_order(n->left);
hc_bst_traverse_post_order(n->right);
hc_node_print(n);
}

static void hc_bst_traverse_level_order(hc_node* n) {
hc_q* traversal_queue = hc_q_init(5);
hc_q_enqueue(traversal_queue, n);

hc_node* visitor = NULL;

while ((visitor = (hc_node*)hc_q_dequeue(traversal_queue))) {
hc_node_print(visitor);
if (visitor->left) hc_q_enqueue(traversal_queue, visitor->left);
if (visitor->right) hc_q_enqueue(traversal_queue, visitor->right);
}

hc_q_destroy(&traversal_queue);
}

void hc_bst_traverse(hc_bst* t, int order_flag) {
if (t->root == NULL) return;
if (order_flag == -1) return hc_bst_traverse_pre_order(t->root);
if (order_flag == 0) return hc_bst_traverse_in_order(t->root);
if (order_flag == 1) return hc_bst_traverse_post_order(t->root);
if (order_flag == 2) return hc_bst_traverse_level_order(t->root);
}

static hc_node** get_in_order_successor_worker(hc_node** n) {
if ((*n)->left == NULL) return n;

return get_in_order_successor_worker(n);
}

static hc_node** get_in_order_successor(hc_node** n) {
if (*n == NULL) return NULL;
if ((*n)->right == NULL) return NULL;

return get_in_order_successor_worker(&(*n)->right);
}

static int is_leaf(hc_node* n) { return n->left == NULL && n->right == NULL; }

static int get_height_worker(hc_node* n, int h) {
if (n == NULL) return h;

++h;

int height_left = get_height_worker(n->left, h);
int height_right = get_height_worker(n->right, h);

if (height_left > height_right || height_left == height_right) {
return height_left;
}

return height_right;
}

int hc_bst_get_height(hc_bst* t) { return get_height_worker(t->root, 0); }

void hc_bst_delete_key(hc_bst* t, const char* k) {
hc_node** n = hc_bst_get_worker(&t->root, k);

if (n == NULL) return;
if ((*n)->left == NULL && (*n)->right == NULL) {
return hc_node_destroy(n);
}
if ((*n)->left == NULL && (*n)->right != NULL) {
free(*n);
if (*n == t->root) {
t->root = (*n)->right;
}
*n = (*n)->right;
return;
}

if ((*n)->left != NULL && (*n)->right == NULL) {
free(*n);
if (*n == t->root) {
t->root = (*n)->right;
}
*n = (*n)->left;
return;
}

hc_node** s = get_in_order_successor(n);
(*n)->key = (*s)->key;
(*n)->value = (*s)->value;

if (is_leaf(*s)) {
hc_node_destroy(s);
return;
}

if ((*s)->left != NULL) {
free(*s);
*s = (*s)->left;
return;
}

if ((*s)->right != NULL) {
free(*s);
*s = (*s)->right;
return;
}
}

static void hc_bst_print_worker(hc_node* n, const char* node_addr) {
if (n == NULL) return;

printf("Node: %s\n", node_addr);
hc_node_print(n);
printf("\n\n");
fflush(stdout);

char* left_node_addr = malloc((strlen(node_addr) + 6 + 1) * sizeof(char));
strcpy(left_node_addr, node_addr);
strcat(left_node_addr, "->left");
hc_bst_print_worker(n->left, left_node_addr);
free(left_node_addr);
left_node_addr = NULL;

char* right_node_addr = malloc((strlen(node_addr) + 7 + 1) * sizeof(char));
strcpy(right_node_addr, node_addr);
strcat(right_node_addr, "->right");
hc_bst_print_worker(n->right, right_node_addr);
free(right_node_addr);
right_node_addr = NULL;
}

void hc_bst_print(hc_bst* t) { hc_bst_print_worker(t->root, "root"); }

void hc_bst_destroy(hc_bst** t) {
hc_node_destroy(&(*t)->root);
free(*t);
*t = NULL;
}
38 changes: 38 additions & 0 deletions deps/hc_q.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "hc_q.h"

hc_q* hc_q_init(size_t init_capacity) {
hc_q* q = malloc(sizeof(hc_q));

q->data = malloc(sizeof(void*) * init_capacity);
q->size = 0;
q->offset = 0;
q->potential_size = init_capacity;
return q;
}

void hc_q_enqueue(hc_q* q, void* data) {
if (q->size + q->offset == q->potential_size) {
q->potential_size *= 2;
q->data = realloc(q->data, sizeof(void*) * q->potential_size);
}

*(q->data + q->size + q->offset) = data;
++q->size;
}

void* hc_q_dequeue(hc_q* q) {
if (q->size == 0) return NULL;

void* el = *(q->data + q->offset);
--q->size;
++q->offset;

return el;
}

void hc_q_destroy(hc_q** q) {
free((*q)->data);
free(*q);

*q = NULL;
}
4 changes: 4 additions & 0 deletions include/hc_avl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#ifndef HC_AVL_H
#define HC_AVL_H

#endif
26 changes: 26 additions & 0 deletions include/hc_bst.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef HC_BST_H
#define HC_BST_H

#include "hc_q.h"

typedef struct hc_bst {
struct hc_node* root;
} hc_bst;

hc_bst* hc_bst_init();

void hc_bst_insert(hc_bst* t, const char* k, const char* v);

const char* hc_bst_get(hc_bst* t, const char* k);

void hc_bst_traverse(hc_bst* t, int order_flag);

int hc_bst_get_height(hc_bst* t);

void hc_bst_delete_key(hc_bst* t, const char* k);

void hc_bst_print(hc_bst* t);

void hc_bst_destroy(hc_bst** t);

#endif
20 changes: 20 additions & 0 deletions include/hc_q.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef HC_Q_H
#define HC_Q_H

#include <stdlib.h>

typedef struct hc_q {
void** data;
size_t size;
size_t potential_size;
int offset;
} hc_q;

hc_q* hc_q_init(size_t init_capacity);

void hc_q_enqueue(hc_q* q, void* data);
void* hc_q_dequeue(hc_q* q);

void hc_q_destroy(hc_q** q);

#endif
5 changes: 5 additions & 0 deletions src/driver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stdio.h>

#include "hc_avl.h"

int main() { printf("%s\n", "Nothing here yet."); }
Empty file added src/hc_avl.c
Empty file.

0 comments on commit ad0c34c

Please sign in to comment.