core: rename btree to bst
This commit is contained in:
@@ -25,10 +25,10 @@
|
|||||||
this file implements an extensible AVL binary tree data structure.
|
this file implements an extensible AVL binary tree data structure.
|
||||||
|
|
||||||
the primary rule of an AVL binary tree is that for a given node N,
|
the primary rule of an AVL binary tree is that for a given node N,
|
||||||
the heights of N's left and right subtrees can differ by at most 1.
|
the heights of N's left and right substs can differ by at most 1.
|
||||||
|
|
||||||
the height of a subtree is the length of the longest path between
|
the height of a subst is the length of the longest path between
|
||||||
the root of the subtree and a leaf node, including the root node itself.
|
the root of the subst and a leaf node, including the root node itself.
|
||||||
|
|
||||||
the height of a leaf node is 1.
|
the height of a leaf node is 1.
|
||||||
|
|
||||||
@@ -52,12 +52,12 @@
|
|||||||
it is up to the programmer to implement their own tree node type
|
it is up to the programmer to implement their own tree node type
|
||||||
using fx_bst_node, and their own search function using fx_bst.
|
using fx_bst_node, and their own search function using fx_bst.
|
||||||
this allows the programmer to define their own node types with complex
|
this allows the programmer to define their own node types with complex
|
||||||
non-integer key types. btree.h contains a number of macros to help
|
non-integer key types. bst.h contains a number of macros to help
|
||||||
define these functions. the macros do all the work, you just have to
|
define these functions. the macros do all the work, you just have to
|
||||||
provide a comparator function.
|
provide a comparator function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fx/core/btree.h>
|
#include <fx/core/bst.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
@@ -107,7 +107,7 @@ static inline int bf(struct fx_bst_node *x)
|
|||||||
return bf;
|
return bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform a left rotation on a subtree
|
/* perform a left rotation on a subst
|
||||||
|
|
||||||
if you have a tree like this:
|
if you have a tree like this:
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ static void update_height_to_root(struct fx_bst_node *x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* perform a right rotation on a subtree
|
/* perform a right rotation on a subst
|
||||||
|
|
||||||
if you have a tree like this:
|
if you have a tree like this:
|
||||||
|
|
||||||
@@ -304,8 +304,8 @@ static void rotate_double_right(struct fx_bst *tree, struct fx_bst_node *z)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* run after an insert operation. checks that the balance factor
|
/* run after an insert operation. checks that the balance factor
|
||||||
of the local subtree is within the range -1 <= BF <= 1. if it
|
of the local subst is within the range -1 <= BF <= 1. if it
|
||||||
is not, rotate the subtree to restore balance.
|
is not, rotate the subst to restore balance.
|
||||||
|
|
||||||
note that at most one rotation should be required after a node
|
note that at most one rotation should be required after a node
|
||||||
is inserted into the tree.
|
is inserted into the tree.
|
||||||
@@ -349,8 +349,8 @@ static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* run after a delete operation. checks that the balance factor
|
/* run after a delete operation. checks that the balance factor
|
||||||
of the local subtree is within the range -1 <= BF <= 1. if it
|
of the local subst is within the range -1 <= BF <= 1. if it
|
||||||
is not, rotate the subtree to restore balance.
|
is not, rotate the subst to restore balance.
|
||||||
|
|
||||||
note that, unlike insert_fixup, multiple rotations may be required
|
note that, unlike insert_fixup, multiple rotations may be required
|
||||||
to restore balance after a node is deleted.
|
to restore balance after a node is deleted.
|
||||||
@@ -451,7 +451,7 @@ static struct fx_bst_node *remove_node_with_no_children(
|
|||||||
|
|
||||||
@param node the node to delete.
|
@param node the node to delete.
|
||||||
*/
|
*/
|
||||||
static struct fx_bst_node *replace_node_with_one_subtree(
|
static struct fx_bst_node *replace_node_with_one_subst(
|
||||||
struct fx_bst *tree, struct fx_bst_node *node)
|
struct fx_bst *tree, struct fx_bst_node *node)
|
||||||
{
|
{
|
||||||
struct fx_bst_node *p = node->n_parent;
|
struct fx_bst_node *p = node->n_parent;
|
||||||
@@ -500,7 +500,7 @@ static struct fx_bst_node *replace_node_with_one_subtree(
|
|||||||
|
|
||||||
@param z the node to delete.
|
@param z the node to delete.
|
||||||
*/
|
*/
|
||||||
static struct fx_bst_node *replace_node_with_two_subtrees(
|
static struct fx_bst_node *replace_node_with_two_substs(
|
||||||
struct fx_bst *tree, struct fx_bst_node *z)
|
struct fx_bst *tree, struct fx_bst_node *z)
|
||||||
{
|
{
|
||||||
/* x will replace z */
|
/* x will replace z */
|
||||||
@@ -572,9 +572,9 @@ void fx_bst_delete(struct fx_bst *tree, struct fx_bst_node *node)
|
|||||||
if (HAS_NO_CHILDREN(node)) {
|
if (HAS_NO_CHILDREN(node)) {
|
||||||
w = remove_node_with_no_children(tree, node);
|
w = remove_node_with_no_children(tree, node);
|
||||||
} else if (HAS_ONE_CHILD(node)) {
|
} else if (HAS_ONE_CHILD(node)) {
|
||||||
w = replace_node_with_one_subtree(tree, node);
|
w = replace_node_with_one_subst(tree, node);
|
||||||
} else if (HAS_TWO_CHILDREN(node)) {
|
} else if (HAS_TWO_CHILDREN(node)) {
|
||||||
w = replace_node_with_two_subtrees(tree, node);
|
w = replace_node_with_two_substs(tree, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w) {
|
if (w) {
|
||||||
@@ -648,7 +648,7 @@ static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
|
|||||||
|
|
||||||
1. if `node` has a right sub-tree, every node in this sub-tree is
|
1. if `node` has a right sub-tree, every node in this sub-tree is
|
||||||
bigger than node. the in-order successor of `node` is the smallest
|
bigger than node. the in-order successor of `node` is the smallest
|
||||||
node in this subtree.
|
node in this subst.
|
||||||
2. if `node` has no right sub-tree, we've reached the largest node in
|
2. if `node` has no right sub-tree, we've reached the largest node in
|
||||||
the sub-tree rooted at `node`. we need to go back to our parent
|
the sub-tree rooted at `node`. we need to go back to our parent
|
||||||
and continue the search elsewhere.
|
and continue the search elsewhere.
|
||||||
@@ -692,7 +692,7 @@ static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
|
|||||||
|
|
||||||
1. if `node` has a left sub-tree, every node in this sub-tree is
|
1. if `node` has a left sub-tree, every node in this sub-tree is
|
||||||
smaller than `node`. the in-order predecessor of `node` is the
|
smaller than `node`. the in-order predecessor of `node` is the
|
||||||
largest node in this subtree.
|
largest node in this subst.
|
||||||
2. if `node` has no left sub-tree, we've reached the smallest node in
|
2. if `node` has no left sub-tree, we've reached the smallest node in
|
||||||
the sub-tree rooted at `node`. we need to go back to our parent
|
the sub-tree rooted at `node`. we need to go back to our parent
|
||||||
and continue the search elsewhere.
|
and continue the search elsewhere.
|
||||||
@@ -764,13 +764,13 @@ void fx_bst_move(
|
|||||||
|
|
||||||
fx_iterator *fx_bst_begin(struct fx_bst *tree)
|
fx_iterator *fx_bst_begin(struct fx_bst *tree)
|
||||||
{
|
{
|
||||||
fx_iterator *it_obj = fx_object_create(FX_TYPE_BTREE_ITERATOR);
|
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR);
|
||||||
if (!it_obj) {
|
if (!it_obj) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(it_obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR);
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
||||||
it->_b = (struct fx_bst *)tree;
|
it->_b = (struct fx_bst *)tree;
|
||||||
@@ -783,13 +783,13 @@ fx_iterator *fx_bst_begin(struct fx_bst *tree)
|
|||||||
|
|
||||||
const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
|
const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
|
||||||
{
|
{
|
||||||
fx_iterator *it_obj = fx_object_create(FX_TYPE_BTREE_ITERATOR);
|
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR);
|
||||||
if (!it_obj) {
|
if (!it_obj) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(it_obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR);
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
||||||
it->_b = (struct fx_bst *)tree;
|
it->_b = (struct fx_bst *)tree;
|
||||||
@@ -803,7 +803,7 @@ const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
|
|||||||
static enum fx_status iterator_move_next(const fx_iterator *obj)
|
static enum fx_status iterator_move_next(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
|
||||||
|
|
||||||
int depth_diff = 0;
|
int depth_diff = 0;
|
||||||
struct fx_bst_node *next = next_node(it->node, &depth_diff);
|
struct fx_bst_node *next = next_node(it->node, &depth_diff);
|
||||||
@@ -824,7 +824,7 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
|
|||||||
static enum fx_status iterator_erase(fx_iterator *obj)
|
static enum fx_status iterator_erase(fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
|
||||||
|
|
||||||
if (!it->node) {
|
if (!it->node) {
|
||||||
return FX_ERR_OUT_OF_BOUNDS;
|
return FX_ERR_OUT_OF_BOUNDS;
|
||||||
@@ -854,7 +854,7 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
|||||||
static fx_iterator_value iterator_get_value(fx_iterator *obj)
|
static fx_iterator_value iterator_get_value(fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
|
||||||
|
|
||||||
return FX_ITERATOR_VALUE_PTR(it->node);
|
return FX_ITERATOR_VALUE_PTR(it->node);
|
||||||
}
|
}
|
||||||
@@ -862,7 +862,7 @@ static fx_iterator_value iterator_get_value(fx_iterator *obj)
|
|||||||
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj)
|
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj)
|
||||||
{
|
{
|
||||||
struct fx_bst_iterator_p *it
|
struct fx_bst_iterator_p *it
|
||||||
= fx_object_get_private(obj, FX_TYPE_BTREE_ITERATOR);
|
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR);
|
||||||
|
|
||||||
return FX_ITERATOR_VALUE_CPTR(it->node);
|
return FX_ITERATOR_VALUE_CPTR(it->node);
|
||||||
}
|
}
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
FX_DECLS_BEGIN;
|
FX_DECLS_BEGIN;
|
||||||
|
|
||||||
#define FX_BTREE_INIT {0}
|
#define FX_BST_INIT {0}
|
||||||
#define FX_TYPE_BTREE_ITERATOR (fx_bst_iterator_get_type())
|
#define FX_TYPE_BST_ITERATOR (fx_bst_iterator_get_type())
|
||||||
|
|
||||||
FX_DECLARE_TYPE(fx_bst_iterator);
|
FX_DECLARE_TYPE(fx_bst_iterator);
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
You would use the following call to generate an insert function for a tree
|
You would use the following call to generate an insert function for a tree
|
||||||
with this node type:
|
with this node type:
|
||||||
|
|
||||||
BTREE_DEFINE_SIMPLE_INSERT(
|
BST_DEFINE_SIMPLE_INSERT(
|
||||||
struct my_tree_node,
|
struct my_tree_node,
|
||||||
base,
|
base,
|
||||||
key,
|
key,
|
||||||
@@ -51,7 +51,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
custom type.
|
custom type.
|
||||||
@param function_name the name of the function to generate.
|
@param function_name the name of the function to generate.
|
||||||
*/
|
*/
|
||||||
#define FX_BTREE_DEFINE_SIMPLE_INSERT( \
|
#define FX_BST_DEFINE_SIMPLE_INSERT( \
|
||||||
node_type, container_node_member, container_key_member, function_name) \
|
node_type, container_node_member, container_key_member, function_name) \
|
||||||
void function_name(fx_bst *tree, node_type *node) \
|
void function_name(fx_bst *tree, node_type *node) \
|
||||||
{ \
|
{ \
|
||||||
@@ -122,7 +122,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
You would use the following call to generate an insert function for a tree
|
You would use the following call to generate an insert function for a tree
|
||||||
with this node type:
|
with this node type:
|
||||||
|
|
||||||
BTREE_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert,
|
BST_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert,
|
||||||
my_comparator);
|
my_comparator);
|
||||||
|
|
||||||
Which would emit a function defined like:
|
Which would emit a function defined like:
|
||||||
@@ -139,7 +139,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
@param comparator the name of a comparator function or functional-macro that
|
@param comparator the name of a comparator function or functional-macro that
|
||||||
conforms to the requirements listed above.
|
conforms to the requirements listed above.
|
||||||
*/
|
*/
|
||||||
#define FX_BTREE_DEFINE_INSERT( \
|
#define FX_BST_DEFINE_INSERT( \
|
||||||
node_type, container_node_member, container_key_member, function_name, \
|
node_type, container_node_member, container_key_member, function_name, \
|
||||||
comparator) \
|
comparator) \
|
||||||
void function_name(fx_bst *tree, node_type *node) \
|
void function_name(fx_bst *tree, node_type *node) \
|
||||||
@@ -200,7 +200,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
You would use the following call to generate a search function for a tree
|
You would use the following call to generate a search function for a tree
|
||||||
with this node type:
|
with this node type:
|
||||||
|
|
||||||
BTREE_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key,
|
BST_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key,
|
||||||
my_tree_node_get);
|
my_tree_node_get);
|
||||||
|
|
||||||
Which would emit a function defined like:
|
Which would emit a function defined like:
|
||||||
@@ -217,7 +217,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
|
|||||||
custom type.
|
custom type.
|
||||||
@param function_name the name of the function to generate.
|
@param function_name the name of the function to generate.
|
||||||
*/
|
*/
|
||||||
#define FX_BTREE_DEFINE_SIMPLE_GET( \
|
#define FX_BST_DEFINE_SIMPLE_GET( \
|
||||||
node_type, key_type, container_node_member, container_key_member, \
|
node_type, key_type, container_node_member, container_key_member, \
|
||||||
function_name) \
|
function_name) \
|
||||||
node_type *function_name(const fx_bst *tree, key_type key) \
|
node_type *function_name(const fx_bst *tree, key_type key) \
|
||||||
@@ -263,7 +263,7 @@ FX_API fx_type fx_bst_iterator_get_type(void);
|
|||||||
|
|
||||||
/* re-balance a binary tree after an insertion operation.
|
/* re-balance a binary tree after an insertion operation.
|
||||||
|
|
||||||
NOTE that, if you define an insertion function using BTREE_DEFINE_INSERT or
|
NOTE that, if you define an insertion function using BST_DEFINE_INSERT or
|
||||||
similar, this function will automatically called for you.
|
similar, this function will automatically called for you.
|
||||||
|
|
||||||
@param tree the tree to re-balance.
|
@param tree the tree to re-balance.
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
#include <fx/core/btree.h>
|
#include <fx/core/bst.h>
|
||||||
#include <fx/core/endian.h>
|
#include <fx/core/endian.h>
|
||||||
#include <fx/core/object.h>
|
#include <fx/core/object.h>
|
||||||
#include <fx/core/type.h>
|
#include <fx/core/type.h>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static struct fx_bst type_list = FX_BTREE_INIT;
|
static struct fx_bst type_list = FX_BST_INIT;
|
||||||
static union fx_type zero_id = {0};
|
static union fx_type zero_id = {0};
|
||||||
|
|
||||||
struct type_init_ctx {
|
struct type_init_ctx {
|
||||||
@@ -31,10 +31,10 @@ static inline int component_compare(
|
|||||||
return fx_type_id_compare(&a->c_type->r_info->t_id, &b->c_type->r_info->t_id);
|
return fx_type_id_compare(&a->c_type->r_info->t_id, &b->c_type->r_info->t_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
FX_BTREE_DEFINE_INSERT(
|
FX_BST_DEFINE_INSERT(
|
||||||
struct fx_type_registration, r_node, r_info->r_id, put_type,
|
struct fx_type_registration, r_node, r_info->r_id, put_type,
|
||||||
registration_compare)
|
registration_compare)
|
||||||
FX_BTREE_DEFINE_INSERT(
|
FX_BST_DEFINE_INSERT(
|
||||||
struct fx_type_component, c_node, &c_type->r_info->t_id,
|
struct fx_type_component, c_node, &c_type->r_info->t_id,
|
||||||
put_type_component, component_compare)
|
put_type_component, component_compare)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef _TYPE_H_
|
#ifndef _TYPE_H_
|
||||||
#define _TYPE_H_
|
#define _TYPE_H_
|
||||||
|
|
||||||
#include <fx/core/btree.h>
|
#include <fx/core/bst.h>
|
||||||
#include <fx/core/queue.h>
|
#include <fx/core/queue.h>
|
||||||
#include <fx/core/type.h>
|
#include <fx/core/type.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
#include <fx/core/btree.h>
|
#include <fx/core/bst.h>
|
||||||
#include <fx/core/misc.h>
|
#include <fx/core/misc.h>
|
||||||
#include <fx/core/queue.h>
|
#include <fx/core/queue.h>
|
||||||
#include <fx/core/stringstream.h>
|
#include <fx/core/stringstream.h>
|
||||||
@@ -16,9 +16,9 @@ struct test_queue_entry {
|
|||||||
fx_queue_entry entry;
|
fx_queue_entry entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
FX_BTREE_DEFINE_SIMPLE_INSERT(struct test_tree_node, node, value, test_tree_insert);
|
FX_BST_DEFINE_SIMPLE_INSERT(struct test_tree_node, node, value, test_tree_insert);
|
||||||
|
|
||||||
void test_btree_insert(CuTest *tc)
|
void test_bst_insert(CuTest *tc)
|
||||||
{
|
{
|
||||||
fx_bst tree = {0};
|
fx_bst tree = {0};
|
||||||
struct test_tree_node nodes[3] = {0};
|
struct test_tree_node nodes[3] = {0};
|
||||||
@@ -58,7 +58,7 @@ void test_btree_insert(CuTest *tc)
|
|||||||
CuAssertIntEquals(tc, 1, nodes[2].node.n_height);
|
CuAssertIntEquals(tc, 1, nodes[2].node.n_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_btree_iterate(CuTest *tc)
|
void test_bst_iterate(CuTest *tc)
|
||||||
{
|
{
|
||||||
static const size_t nr_nodes = 256;
|
static const size_t nr_nodes = 256;
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
@@ -191,8 +191,8 @@ CuSuite *get_all_tests(void)
|
|||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
|
||||||
SUITE_ADD_TEST(suite, test_btree_insert);
|
SUITE_ADD_TEST(suite, test_bst_insert);
|
||||||
SUITE_ADD_TEST(suite, test_btree_iterate);
|
SUITE_ADD_TEST(suite, test_bst_iterate);
|
||||||
SUITE_ADD_TEST(suite, test_queue_insert);
|
SUITE_ADD_TEST(suite, test_queue_insert);
|
||||||
SUITE_ADD_TEST(suite, test_queue_iterate);
|
SUITE_ADD_TEST(suite, test_queue_iterate);
|
||||||
SUITE_ADD_TEST(suite, test_stringstream_1);
|
SUITE_ADD_TEST(suite, test_stringstream_1);
|
||||||
|
|||||||
Reference in New Issue
Block a user