mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
lib: add binary search tree implementation
This commit is contained in:
parent
46f45d07e3
commit
755eedde3f
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user