blob: 67efe2e06c17451502c25749d495d4cb0745c1bd [file] [log] [blame]
Benny Prijono4766ffe2005-11-01 17:56:59 +00001/* $Id$
2 *
3 */
Benny Prijonodd859a62005-11-01 16:42:51 +00004
5#ifndef __PJ_RBTREE_H__
6#define __PJ_RBTREE_H__
7
8/**
9 * @file rbtree.h
10 * @brief Red/Black Tree
11 */
12
13#include <pj/types.h>
14
15PJ_BEGIN_DECL
16
17/**
18 * @defgroup PJ_RBTREE Red/Black Balanced Tree
19 * @ingroup PJ_DS
20 * @brief
21 * Red/Black tree is the variant of balanced tree, where the search, insert,
22 * and delete operation is \b guaranteed to take at most \a O( lg(n) ).
23 * @{
24 */
25/**
26 * Color type for Red-Black tree.
27 */
28typedef enum pj_rbcolor_t
29{
30 PJ_RBCOLOR_BLACK,
31 PJ_RBCOLOR_RED
32} pj_rbcolor_t;
33
34/**
35 * The type of the node of the R/B Tree.
36 */
37typedef struct pj_rbtree_node
38{
39 /** Pointers to the node's parent, and left and right siblings. */
40 struct pj_rbtree_node *parent, *left, *right;
41
42 /** Key associated with the node. */
43 const void *key;
44
45 /** User data associated with the node. */
46 void *user_data;
47
48 /** The R/B Tree node color. */
49 pj_rbcolor_t color;
50
51} pj_rbtree_node;
52
53
54/**
55 * The type of function use to compare key value of tree node.
56 * @return
57 * 0 if the keys are equal
58 * <0 if key1 is lower than key2
59 * >0 if key1 is greater than key2.
60 */
61typedef int pj_rbtree_comp(const void *key1, const void *key2);
62
63
64/**
65 * Declaration of a red-black tree. All elements in the tree must have UNIQUE
66 * key.
67 * A red black tree always maintains the balance of the tree, so that the
68 * tree height will not be greater than lg(N). Insert, search, and delete
69 * operation will take lg(N) on the worst case. But for insert and delete,
70 * there is additional time needed to maintain the balance of the tree.
71 */
72typedef struct pj_rbtree
73{
74 pj_rbtree_node null_node; /**< Constant to indicate NULL node. */
75 pj_rbtree_node *null; /**< Constant to indicate NULL node. */
76 pj_rbtree_node *root; /**< Root tree node. */
77 unsigned size; /**< Number of elements in the tree. */
78 pj_rbtree_comp *comp; /**< Key comparison function. */
79} pj_rbtree;
80
81
82/**
83 * Guidance on how much memory required for each of the node.
84 */
85#define PJ_RBTREE_NODE_SIZE (sizeof(pj_rbtree_node))
86
87
88/**
89 * Guidance on memory required for the tree.
90 */
91#define PJ_RBTREE_SIZE (sizeof(pj_rbtree))
92
93
94/**
95 * Initialize the tree.
96 * @param tree the tree to be initialized.
97 * @param comp key comparison function to be used for this tree.
98 */
99PJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp);
100
101/**
102 * Get the first element in the tree.
103 * The first element always has the least value for the key, according to
104 * the comparison function.
105 * @param tree the tree.
106 * @return the tree node, or NULL if the tree has no element.
107 */
108PJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree );
109
110/**
111 * Get the last element in the tree.
112 * The last element always has the greatest key value, according to the
113 * comparison function defined for the tree.
114 * @param tree the tree.
115 * @return the tree node, or NULL if the tree has no element.
116 */
117PJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree );
118
119/**
120 * Get the successive element for the specified node.
121 * The successive element is an element with greater key value.
122 * @param tree the tree.
123 * @param node the node.
124 * @return the successive node, or NULL if the node has no successor.
125 */
126PJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree,
127 pj_rbtree_node *node );
128
129/**
130 * The the previous node for the specified node.
131 * The previous node is an element with less key value.
132 * @param tree the tree.
133 * @param node the node.
134 * @return the previous node, or NULL if the node has no previous node.
135 */
136PJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree,
137 pj_rbtree_node *node );
138
139/**
140 * Insert a new node.
141 * The node will be inserted at sorted location. The key of the node must
142 * be UNIQUE, i.e. it hasn't existed in the tree.
143 * @param tree the tree.
144 * @param node the node to be inserted.
145 * @return zero on success, or -1 if the key already exist.
146 */
147PJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree,
148 pj_rbtree_node *node );
149
150/**
151 * Find a node which has the specified key.
152 * @param tree the tree.
153 * @param key the key to search.
154 * @return the tree node with the specified key, or NULL if the key can not
155 * be found.
156 */
157PJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree,
158 const void *key );
159
160/**
161 * Erase a node from the tree.
162 * @param tree the tree.
163 * @param node the node to be erased.
164 * @return the tree node itself.
165 */
166PJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree,
167 pj_rbtree_node *node );
168
169/**
170 * Get the maximum tree height from the specified node.
171 * @param tree the tree.
172 * @param node the node, or NULL to get the root of the tree.
173 * @return the maximum height, which should be at most lg(N)
174 */
175PJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree,
176 pj_rbtree_node *node );
177
178/**
179 * Get the minumum tree height from the specified node.
180 * @param tree the tree.
181 * @param node the node, or NULL to get the root of the tree.
182 * @return the height
183 */
184PJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree,
185 pj_rbtree_node *node );
186
187
188/**
189 * @}
190 */
191
192PJ_END_DECL
193
194#endif /* __PJ_RBTREE_H__ */
195