A wrapper around sys/tree.h.
Macro RBTREE_DEFINE(name, type, field, cmp) defines a red-black tree
with type name and its operations. type is the name of the structure that
represents the nodes of the tree, and are linked through a user defined field
field. Finally, cmp is a function pointer of type
int (*cmp)(struct type*).
Macro RB_ENTRY(type) defines a structure that contains the links to the
left, right and parent nodes.
The example below shows how to declare a red-black tree containing integer keys.
struct node {
int key;
RB_ENTRY(node) entry;
};
int node_cmp(struct node* n);
RBTREE_DEFINE(tree, node, entry, cmp);Same as above, except that the macros are SPLAY_ENTRY() and SPLAYTREE_DEFINE().
RBTREE_DEFINE(tree, node, entry, cmp) or the equivalent
SPLAYTREE_DEFINE generate the following API:
void tree_init_node(struct tree *t);Initializes an empty tree t.
struct node* tree_insert_node(struct tree* t, struct node* e);Inserts node e in tree t.
struct node* tree_remove_node(struct tree *t, struct node *e);Removes the first node in tree t, that matches node e, according
to the comparator function. Returns the removed node, or NULL.
struct node* tree_find_node(struct tree* t, struct node* e);Returns a pointer to the first node that matches e, or NULL.
struct node* tree_min_node(struct tree* t);Returns the smallest node in t, or NULL if the t is empty.
struct node* tree_max_node(struct tree* t);Returns the largest node in t, or NULL if the t is empty.
struct node* tree_next_node(struct tree* t, struct node* e);Returns the next node in tree t larger than e, or NULL.
void tree_apply_node(struct tree* t, void(*cb)(struct node*));Calls the given function cb on every node in tree t.
void tree_destroy_node(struct tree* t, void(*free_cb)(struct node*));Removes all nodes in the given tree t and frees their memory by calling
the given function free_cb.
void tree_each(name, type, iter, block);tree_each is a macro that iterates over all nodes in the tree.
struct tree t;
tree_each(&t, node, n, {
printf("%d", n->key);
});void tree_each_safe(name, type, iter, block);Same as tree_each, except that it is safe to remove node iter from
the tree while iterating.
The following program reads lines from stdin, inserts them into a
red-black tree, and on EOF prints them to stdout in order.
#include "tree.h"
struct node {
char* line;
RB_ENTRY(node) entry;
};
struct node* node_new(char* string);
int node_cmp(struct node* a, struct node* b);
RBTREE_DEFINE(tree, node, entry, node_cmp);
struct node*
node_new(char* line)
{
struct node* n = calloc(1, sizeof(struct node));
n->line = strdup(line);
return n;
}
int
node_cmp(struct node* a, struct node* b)
{
return strcmp(a->line, b->line);
}
int
main(int argc, char const* argv[])
{
struct tree t;
size_t len = 0;
char* line = NULL;
tree_init_node(&t);
while (getline(&line, &len, stdin) != -1) {
struct node query = { line };
if (!tree_find_node(&t, &query))
tree_insert_node(&t, node_new(line));
}
printf("Sorted lines:\n");
tree_each(&t, node, n, {
printf("%s", n->line);
});
return 0;
}