diff --git a/sandbox/btree/btree.c b/sandbox/btree/btree.c index ca43c95..12de68a 100644 --- a/sandbox/btree/btree.c +++ b/sandbox/btree/btree.c @@ -231,51 +231,6 @@ void btree_insert_fixup(btree_t *tree, btree_node_t *node) insert_fixup(tree, node); } -#if 0 -void btree_insert(btree_t *tree, btree_node_t *node) -{ - if (!tree->b_root) { - tree->b_root = node; - node->b_parent = NULL; - node->b_height = 1; - return; - } - - btree_node_t *cur = tree->b_root; - while (1) { - btree_node_t **nextp = NULL; - - if (node->b_key == cur->b_key) { - return; - } - - if (node->b_key >= cur->b_key) { - nextp = &cur->b_right; - } else { - nextp = &cur->b_left; - } - - if (*nextp) { - cur = *nextp; - } else { - node->b_parent = cur; - *nextp = node; - break; - } - } - - node->b_height = 0; - - cur = node; - while (cur) { - update_height(cur); - cur = cur->b_parent; - } - - insert_fixup(tree, node); -} -#endif - static btree_node_t *remove_node_with_no_children(btree_t *tree, btree_node_t *node) { btree_node_t *w = node->b_parent; @@ -412,3 +367,75 @@ void btree_delete(btree_t *tree, btree_node_t *node) node->b_left = node->b_right = node->b_parent = NULL; } + +btree_node_t *btree_first(btree_t *tree) +{ + btree_node_t *cur = tree->b_root; + if (!cur) { + return NULL; + } + + while (cur->b_left) { + cur = cur->b_left; + } + + return cur; +} + +btree_node_t *btree_last(btree_t *tree) +{ + btree_node_t *cur = tree->b_root; + if (!cur) { + return NULL; + } + + while (cur->b_right) { + cur = cur->b_right; + } + + return cur; +} + +btree_node_t *btree_next(btree_node_t *node) +{ + if (!node) { + return NULL; + } + + if (node->b_right) { + btree_node_t *cur = node->b_right; + while (cur->b_left) { + cur = cur->b_left; + } + + return cur; + } + + while (node->b_parent && node->b_parent->b_left != node) { + node = node->b_parent; + } + + return node->b_parent; +} + +btree_node_t *btree_prev(btree_node_t *node) +{ + if (!node) { + return NULL; + } + + if (node->b_left) { + btree_node_t *cur = node->b_left; + while (cur->b_right) { + cur = cur->b_right; + } + + return cur; + } + + while (node->b_parent && node->b_parent->b_right != node) { + node = node->b_parent; + } + + return node->b_parent; +} diff --git a/sandbox/btree/include/socks/btree.h b/sandbox/btree/include/socks/btree.h index 4bc5554..d5e1970 100644 --- a/sandbox/btree/include/socks/btree.h +++ b/sandbox/btree/include/socks/btree.h @@ -80,7 +80,35 @@ } \ \ btree_insert_fixup(tree, &node->container_node_member); \ - } + } + +#define BTREE_DEFINE_SIMPLE_GET(node_type, key_type, container_node_member, container_key_member, function_name) \ +node_type *get(btree_t *tree, key_type key) \ +{ \ + btree_node_t *cur = tree->b_root; \ + while (cur) { \ + node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ + if (key > cur_node->container_key_member) { \ + cur = btree_right(cur); \ + } else if (key < cur_node->container_key_member) { \ + cur = btree_left(cur); \ + } else { \ + return cur_node; \ + } \ + } \ + \ + return NULL; \ +} + +#define btree_foreach(iter_type, iter_name, tree_name, node_member) \ + for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_first(tree_name)); \ + iter_name; \ + iter_name = BTREE_CONTAINER(iter_type, node_member, btree_next(&((iter_name)->node_member)))) + +#define btree_foreach_r(iter_type, iter_name, tree_name, node_member) \ + for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_last(tree_name)); \ + iter_name; \ + iter_name = BTREE_CONTAINER(iter_type, node_member, btree_prev(&((iter_name)->node_member)))) typedef struct btree_node { struct btree_node *b_parent, *b_left, *b_right; @@ -94,6 +122,11 @@ typedef struct btree { extern void btree_insert_fixup(btree_t *tree, btree_node_t *node); extern void btree_delete(btree_t *tree, btree_node_t *node); +extern btree_node_t *btree_first(btree_t *tree); +extern btree_node_t *btree_last(btree_t *tree); +extern btree_node_t *btree_next(btree_node_t *node); +extern btree_node_t *btree_prev(btree_node_t *node); + static inline void btree_put_left(btree_node_t *parent, btree_node_t *child) { parent->b_left = child;