lib: add binary search tree implementation

This commit is contained in:
jussi 2019-11-06 23:17:28 +02:00
parent 46f45d07e3
commit 755eedde3f
2 changed files with 72 additions and 0 deletions

View File

@ -15,7 +15,9 @@ extern "C" {
// Tagged union of data types for simulating function overloading
enum tc_data_types {
TC_TYPE_NONE,
TC_TYPE_INT,
TC_TYPE_UINT,
TC_TYPE_DOUBLE,
TC_TYPE_STRING,
TC_TYPE_STRING_ARR
@ -25,6 +27,7 @@ typedef struct {
enum tc_data_types data_type;
union {
int64_t int_value;
uint64_t uint_value;
double double_value;
char *string_value;
};
@ -44,6 +47,22 @@ char **tc_str_arr_dup(uint16_t str_count, char **const strings);
// Deallocate string array
void tc_str_arr_free(uint16_t str_count, char **strings);
// Binary search tree whose left node contains the smaller value
typedef struct tc_bin_node_ {
void *key;
void *value;
struct tc_bin_node_ *left;
struct tc_bin_node_ *right;
} tc_bin_node_t;
// Create a new node with key and data in the appropriate position
tc_bin_node_t *tc_bin_node_insert(tc_bin_node_t* node, void *key, void *value);
// Find the value associated with the key
void *tc_bin_node_find_value(tc_bin_node_t *node, void *key);
// Destroy a node and its children
void tc_bin_node_destroy(tc_bin_node_t *node);
#ifdef __cplusplus
}
#endif

View File

@ -18,3 +18,56 @@ void tc_str_arr_free(uint16_t str_count, char **strings) {
}
free(strings);
}
static tc_bin_node_t *new_bin_node(void *key, void *value) {
tc_bin_node_t *new_node = calloc(1, sizeof(tc_bin_node_t));
new_node->key = key;
new_node->value = value;
return new_node;
}
static void single_destroy(tc_bin_node_t *node) {
free(node);
}
static void traverse_postorder(tc_bin_node_t *node, void (*func)(tc_bin_node_t*)) {
if (node->left) {
traverse_postorder(node, func);
}
if (node->right) {
traverse_postorder(node, func);
}
func(node);
}
tc_bin_node_t *tc_bin_node_insert(tc_bin_node_t *node, void *key, void *value) {
if (node == NULL) {
return new_bin_node(key, value);
}
if (key < node->key) {
node->left = tc_bin_node_insert(node->left, key, value);
}
else if (key > node->key) {
node->right = tc_bin_node_insert(node->right, key, value);
}
return node;
}
void *tc_bin_node_find_value(tc_bin_node_t *node, void *key) {
if (node == NULL) {
return NULL;
}
if (node->key == key) {
return node->value;
}
if (node->key < key) {
return tc_bin_node_find_value(node->right, key);
}
return tc_bin_node_find_value(node->left, key);
}
void tc_bin_node_destroy(tc_bin_node_t *node) {
traverse_postorder(node, &single_destroy);
}