Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement search le/lt/ge/gt functions for red-black tree.

  • Loading branch information...
commit 60ed5079842164d59bc798014cb8d4549d52fb43 1 parent 6a9aff6
@fmela authored
Showing with 172 additions and 15 deletions.
  1. +8 −0 include/rb_tree.h
  2. +164 −15 src/rb_tree.c
View
8 include/rb_tree.h
@@ -49,6 +49,10 @@ rb_tree* rb_tree_clone(rb_tree* tree,
void** rb_tree_insert(rb_tree* tree, void* key, bool* inserted);
void* rb_tree_search(rb_tree* tree, const void* key);
+void* rb_tree_search_le(rb_tree* tree, const void* key);
+void* rb_tree_search_lt(rb_tree* tree, const void* key);
+void* rb_tree_search_ge(rb_tree* tree, const void* key);
+void* rb_tree_search_gt(rb_tree* tree, const void* key);
bool rb_tree_remove(rb_tree* tree, const void* key);
size_t rb_tree_clear(rb_tree* tree);
size_t rb_tree_traverse(rb_tree* tree, dict_visit_func visit);
@@ -75,6 +79,10 @@ bool rb_itor_prevn(rb_itor* itor, size_t count);
bool rb_itor_first(rb_itor* itor);
bool rb_itor_last(rb_itor* itor);
bool rb_itor_search(rb_itor* itor, const void* key);
+bool rb_itor_search_le(rb_itor* itor, const void* key);
+bool rb_itor_search_lt(rb_itor* itor, const void* key);
+bool rb_itor_search_ge(rb_itor* itor, const void* key);
+bool rb_itor_search_gt(rb_itor* itor, const void* key);
const void* rb_itor_key(const rb_itor* itor);
void** rb_itor_data(rb_itor* itor);
bool rb_itor_remove(rb_itor* itor);
View
179 src/rb_tree.c
@@ -72,10 +72,10 @@ static dict_vtable rb_tree_vtable = {
(dict_dfree_func) rb_tree_free,
(dict_insert_func) rb_tree_insert,
(dict_search_func) rb_tree_search,
- (dict_search_func) NULL,/* search_le: not implemented */
- (dict_search_func) NULL,/* search_lt: not implemented */
- (dict_search_func) NULL,/* search_ge: not implemented */
- (dict_search_func) NULL,/* search_gt: not implemented */
+ (dict_search_func) rb_tree_search_le,
+ (dict_search_func) rb_tree_search_lt,
+ (dict_search_func) rb_tree_search_ge,
+ (dict_search_func) rb_tree_search_gt,
(dict_remove_func) rb_tree_remove,
(dict_clear_func) rb_tree_clear,
(dict_traverse_func) rb_tree_traverse,
@@ -97,16 +97,16 @@ static itor_vtable rb_tree_itor_vtable = {
(dict_key_func) rb_itor_key,
(dict_data_func) rb_itor_data,
(dict_isearch_func) rb_itor_search,
- (dict_isearch_func) NULL,/* itor_search_le: not implemented */
- (dict_isearch_func) NULL,/* itor_search_lt: not implemented */
- (dict_isearch_func) NULL,/* itor_search_ge: not implemented */
- (dict_isearch_func) NULL,/* itor_search_gt: not implemented */
+ (dict_isearch_func) rb_itor_search_le,
+ (dict_isearch_func) rb_itor_search_lt,
+ (dict_isearch_func) rb_itor_search_ge,
+ (dict_isearch_func) rb_itor_search_gt,
(dict_iremove_func) NULL,/* rb_itor_remove not implemented yet */
(dict_icompare_func) NULL /* rb_itor_compare not implemented yet */
};
-static rb_node _null = { NULL, NULL, NULL, NULL, { RB_BLACK } };
-#define RB_NULL &_null
+static rb_node rb_null = { NULL, NULL, NULL, NULL, { RB_BLACK } };
+#define RB_NULL &rb_null
static void rot_left(rb_tree* tree, rb_node* node);
static void rot_right(rb_tree* tree, rb_node* node);
@@ -192,11 +192,10 @@ rb_tree_clone(rb_tree* tree, dict_key_datum_clone_func clone_func)
return clone;
}
-void*
-rb_tree_search(rb_tree* tree, const void* key)
+rb_node*
+rb_tree_search_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);
-
rb_node* node = tree->root;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
@@ -205,9 +204,127 @@ rb_tree_search(rb_tree* tree, const void* key)
else if (cmp)
node = RLINK(node);
else
- return node->datum;
+ return node;
+ }
+ return RB_NULL;
+}
+
+void*
+rb_tree_search(rb_tree* tree, const void* key)
+{
+ ASSERT(tree != NULL);
+
+ rb_node* node = rb_tree_search_node(tree, key);
+ return (node != RB_NULL) ? node->datum : NULL;
+}
+
+rb_node*
+rb_tree_search_le_node(rb_tree* tree, const void* key)
+{
+ ASSERT(tree != NULL);
+
+ rb_node* node = tree->root, *ret = RB_NULL;
+ while (node != RB_NULL) {
+ int cmp = tree->cmp_func(key, node->key);
+ if (cmp == 0) {
+ return node;
+ } else if (cmp < 0) {
+ node = node->llink;
+ } else {
+ ret = node;
+ node = RLINK(node);
+ }
+ }
+ return ret;
+}
+
+void*
+rb_tree_search_le(rb_tree* tree, const void* key)
+{
+ rb_node* node = rb_tree_search_le_node(tree, key);
+
+ return (node != RB_NULL) ? node->datum : NULL;
+}
+
+rb_node*
+rb_tree_search_lt_node(rb_tree* tree, const void* key)
+{
+ ASSERT(tree != NULL);
+
+ rb_node* node = tree->root, *ret = RB_NULL;
+ while (node != RB_NULL) {
+ int cmp = tree->cmp_func(key, node->key);
+ if (cmp <= 0) {
+ node = node->llink;
+ } else {
+ ret = node;
+ node = RLINK(node);
+ }
}
- return NULL;
+ return ret;
+}
+
+void*
+rb_tree_search_lt(rb_tree* tree, const void* key)
+{
+ rb_node* node = rb_tree_search_lt_node(tree, key);
+
+ return (node != RB_NULL) ? node->datum : NULL;
+}
+
+rb_node*
+rb_tree_search_ge_node(rb_tree* tree, const void* key)
+{
+ ASSERT(tree != NULL);
+
+ rb_node* node = tree->root, *ret = RB_NULL;
+ while (node != RB_NULL) {
+ int cmp = tree->cmp_func(key, node->key);
+ if (cmp == 0) {
+ return node;
+ }
+ if (cmp < 0) {
+ ret = node;
+ node = node->llink;
+ } else {
+ node = RLINK(node);
+ }
+ }
+ return ret;
+}
+
+void*
+rb_tree_search_ge(rb_tree* tree, const void* key)
+{
+ rb_node* node = rb_tree_search_ge_node(tree, key);
+
+ return (node != RB_NULL) ? node->datum : NULL;
+}
+
+rb_node*
+rb_tree_search_gt_node(rb_tree* tree, const void* key)
+{
+ ASSERT(tree != NULL);
+
+ rb_node* node = tree->root, *ret = RB_NULL;
+ while (node != RB_NULL) {
+ int cmp = tree->cmp_func(key, node->key);
+ if (cmp < 0) {
+ ret = node;
+ node = node->llink;
+ } else {
+ node = RLINK(node);
+ }
+ }
+ return ret;
+}
+
+void*
+rb_tree_search_gt(rb_tree* tree, const void* key)
+{
+ rb_node* node = rb_tree_search_gt_node(tree, key);
+
+ return (node != RB_NULL) ? node->datum : NULL;
}
void**
@@ -892,6 +1009,38 @@ rb_itor_search(rb_itor* itor, const void* key)
return false;
}
+bool
+rb_itor_search_le(rb_itor* itor, const void* key)
+{
+ ASSERT(itor != NULL);
+ ASSERT(itor->tree != NULL);
+ return (itor->node = rb_tree_search_le_node(itor->tree, key)) != RB_NULL;
+}
+
+bool
+rb_itor_search_lt(rb_itor* itor, const void* key)
+{
+ ASSERT(itor != NULL);
+ ASSERT(itor->tree != NULL);
+ return (itor->node = rb_tree_search_lt_node(itor->tree, key)) != RB_NULL;
+}
+
+bool
+rb_itor_search_ge(rb_itor* itor, const void* key)
+{
+ ASSERT(itor != NULL);
+ ASSERT(itor->tree != NULL);
+ return (itor->node = rb_tree_search_ge_node(itor->tree, key)) != RB_NULL;
+}
+
+bool
+rb_itor_search_gt(rb_itor* itor, const void* key)
+{
+ ASSERT(itor != NULL);
+ ASSERT(itor->tree != NULL);
+ return (itor->node = rb_tree_search_gt_node(itor->tree, key)) != RB_NULL;
+}
+
const void*
rb_itor_key(const rb_itor* itor)
{
Please sign in to comment.
Something went wrong with that request. Please try again.