prick_btree: provide a general btree_t structure
This structure stores our comparator and allocator functions, as well as a root node, ensuring we're using the same functions on one tree. Makes the API much cleaner to use.
This commit is contained in:
@@ -25,12 +25,22 @@ typedef struct BNode
|
|||||||
} bnode_t;
|
} bnode_t;
|
||||||
|
|
||||||
typedef int (*bnode_comp_fn)(void *, void *);
|
typedef int (*bnode_comp_fn)(void *, void *);
|
||||||
typedef bnode_t *(*bnode_allocator_fn)();
|
typedef bnode_t *(*bnode_alloc_fn)();
|
||||||
typedef void (*bnode_free_fn)(bnode_t *);
|
typedef void (*bnode_free_fn)(bnode_t *);
|
||||||
|
|
||||||
bnode_t *bnode_insert(bnode_t *node, void *value, bnode_comp_fn comparator,
|
typedef struct
|
||||||
bnode_allocator_fn allocator);
|
{
|
||||||
void bnode_free(bnode_t *btree, bnode_free_fn);
|
bnode_t *root;
|
||||||
|
bnode_comp_fn comp;
|
||||||
|
bnode_alloc_fn alloc;
|
||||||
|
bnode_free_fn free;
|
||||||
|
} btree_t;
|
||||||
|
|
||||||
|
void btree_init(btree_t *tree, bnode_comp_fn comparator,
|
||||||
|
bnode_alloc_fn allocator, bnode_free_fn free);
|
||||||
|
bnode_t *btree_insert(btree_t *tree, void *value);
|
||||||
|
void btree_free(btree_t *tree);
|
||||||
|
|
||||||
void bnode_right_rotate(bnode_t **node);
|
void bnode_right_rotate(bnode_t **node);
|
||||||
void bnode_left_rotate(bnode_t **node);
|
void bnode_left_rotate(bnode_t **node);
|
||||||
void bnode_print(FILE *fp, bnode_t *root);
|
void bnode_print(FILE *fp, bnode_t *root);
|
||||||
@@ -39,19 +49,30 @@ void bnode_print(FILE *fp, bnode_t *root);
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
bnode_t *bnode_insert(bnode_t *node, void *value, bnode_comp_fn comparator,
|
void btree_init(btree_t *tree, bnode_comp_fn comparator,
|
||||||
bnode_allocator_fn allocator)
|
bnode_alloc_fn allocator, bnode_free_fn free)
|
||||||
|
{
|
||||||
|
if (tree)
|
||||||
|
{
|
||||||
|
tree->root = NULL;
|
||||||
|
tree->comp = comparator;
|
||||||
|
tree->alloc = allocator;
|
||||||
|
tree->free = free;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bnode_t *bnode_insert(bnode_t *node, btree_t *tree, void *value)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
node = allocator();
|
node = tree->alloc();
|
||||||
node->value = value;
|
node->value = value;
|
||||||
node->left = NULL;
|
node->left = NULL;
|
||||||
node->right = NULL;
|
node->right = NULL;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comp = comparator(value, node->value);
|
int comp = tree->comp(value, node->value);
|
||||||
bnode_t **picked_node = NULL;
|
bnode_t **picked_node = NULL;
|
||||||
if (comp < 0)
|
if (comp < 0)
|
||||||
picked_node = &node->left;
|
picked_node = &node->left;
|
||||||
@@ -59,10 +80,10 @@ bnode_t *bnode_insert(bnode_t *node, void *value, bnode_comp_fn comparator,
|
|||||||
picked_node = &node->right;
|
picked_node = &node->right;
|
||||||
|
|
||||||
if (*picked_node)
|
if (*picked_node)
|
||||||
bnode_insert(*picked_node, value, comparator, allocator);
|
bnode_insert(*picked_node, tree, value);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*picked_node = allocator();
|
*picked_node = tree->alloc();
|
||||||
picked_node[0]->value = value;
|
picked_node[0]->value = value;
|
||||||
picked_node[0]->left = NULL;
|
picked_node[0]->left = NULL;
|
||||||
picked_node[0]->right = NULL;
|
picked_node[0]->right = NULL;
|
||||||
@@ -71,6 +92,12 @@ bnode_t *bnode_insert(bnode_t *node, void *value, bnode_comp_fn comparator,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bnode_t *btree_insert(btree_t *tree, void *value)
|
||||||
|
{
|
||||||
|
tree->root = bnode_insert(tree->root, tree, value);
|
||||||
|
return tree->root;
|
||||||
|
}
|
||||||
|
|
||||||
void bnode_free(bnode_t *bnode, bnode_free_fn free_fn)
|
void bnode_free(bnode_t *bnode, bnode_free_fn free_fn)
|
||||||
{
|
{
|
||||||
if (!bnode)
|
if (!bnode)
|
||||||
@@ -83,6 +110,14 @@ void bnode_free(bnode_t *bnode, bnode_free_fn free_fn)
|
|||||||
bnode_free(right, free_fn);
|
bnode_free(right, free_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btree_free(btree_t *tree)
|
||||||
|
{
|
||||||
|
if (!tree)
|
||||||
|
return;
|
||||||
|
bnode_free(tree->root, tree->free);
|
||||||
|
tree->root = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void bnode_right_rotate(bnode_t **node)
|
void bnode_right_rotate(bnode_t **node)
|
||||||
{
|
{
|
||||||
if (!node || !*node)
|
if (!node || !*node)
|
||||||
|
|||||||
Reference in New Issue
Block a user