3 @brief red–black self-balancing binary search tree
13 @addtogroup a_rbt red–black binary search tree
17 /* clang-format off */
18 #define A_RBT_ROOT {A_NULL}
22 @brief instance structure for red–black binary search tree node
24 typedef struct a_rbt_node
26 struct a_rbt_node
*left
; /*!< pointer to left child or null */
27 struct a_rbt_node
*right
; /*!< pointer to right child or null */
28 /*! pointer to parent combined with the color. The mapping is: 0 => red, 1 => black.
29 The rest of the bits are the pointer to the parent node. It must be 2-byte aligned,
30 and it will be null if this is the root node and therefore has no parent.
32 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
34 #else /* !A_SIZE_POINTER */
35 struct a_rbt_node
*parent
;
37 #endif /* A_SIZE_POINTER */
41 @brief access parent of red–black binary search tree node
42 @param[in] node points to red–black binary search tree node
43 @return a pointer to the parent of the specified red–black tree node,
44 or null if it is already the root of the tree.
46 A_INTERN a_rbt_node
*a_rbt_parent(a_rbt_node
const *node
)
48 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
49 return a_cast_r(a_rbt_node
*, node
->parent_
& ~a_uptr_c(1));
50 #else /* !A_SIZE_POINTER */
52 #endif /* A_SIZE_POINTER */
56 @brief initialize for red–black binary search tree node
57 @param[in] node node to be initialized
58 @param[in] parent node parent
59 @return initialized node
61 A_INTERN a_rbt_node
*a_rbt_init(a_rbt_node
*node
, a_rbt_node
*parent
)
63 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
64 node
->parent_
= a_cast_r(a_uptr
, parent
);
65 #else /* !A_SIZE_POINTER */
66 node
->parent
= parent
;
68 #endif /* A_SIZE_POINTER */
75 @brief instance structure for red–black binary search tree root
79 struct a_rbt_node
*node
; /*!< root node */
83 @brief initialize for red–black binary search tree root
84 @param[in,out] root red–black binary search tree root
86 A_INTERN
void a_rbt_root(a_rbt
*root
) { root
->node
= A_NULL
; }
88 #if defined(__cplusplus)
90 #endif /* __cplusplus */
93 @brief access head node of red–black binary search tree in-order
94 @param[in] root red–black binary search tree root
95 @return head node or null
97 A_EXTERN a_rbt_node
*a_rbt_head(a_rbt
const *root
);
100 @brief access tail node of red–black binary search tree in-order
101 @param[in] root red–black binary search tree root
102 @return tail node or null
104 A_EXTERN a_rbt_node
*a_rbt_tail(a_rbt
const *root
);
107 @brief access next node of red–black binary search tree node in-order
108 @param[in] node red–black binary search tree node
109 @return next node or null
111 A_EXTERN a_rbt_node
*a_rbt_next(a_rbt_node
*node
);
114 @brief access prev node of red–black binary search tree node in-order
115 @param[in] node red–black binary search tree node
116 @return prev node or null
118 A_EXTERN a_rbt_node
*a_rbt_prev(a_rbt_node
*node
);
121 @brief access next node of red–black binary search tree node preorder
122 @param[in] node red–black binary search tree node
123 @return next node or null
125 A_EXTERN a_rbt_node
*a_rbt_pre_next(a_rbt_node
*node
);
128 @brief access prev node of red–black binary search tree node preorder
129 @param[in] node red–black binary search tree node
130 @return prev node or null
132 A_EXTERN a_rbt_node
*a_rbt_pre_prev(a_rbt_node
*node
);
135 @brief access head node of red–black binary search tree postorder
136 @param[in] root red–black binary search tree root
137 @return head node or null
139 A_EXTERN a_rbt_node
*a_rbt_post_head(a_rbt
const *root
);
142 @brief access tail node of red–black binary search tree postorder
143 @param[in] root red–black binary search tree root
144 @return tail node or null
146 A_EXTERN a_rbt_node
*a_rbt_post_tail(a_rbt
const *root
);
149 @brief access next node of red–black binary search tree node postorder
150 @param[in] node red–black binary search tree node
151 @return next node or null
153 A_EXTERN a_rbt_node
*a_rbt_post_next(a_rbt_node
*node
);
156 @brief access prev node of red–black binary search tree node postorder
157 @param[in] node red–black binary search tree node
158 @return prev node or null
160 A_EXTERN a_rbt_node
*a_rbt_post_prev(a_rbt_node
*node
);
163 @brief tear a node from red–black binary search tree
164 @param[in] root red–black binary search tree root
165 @param[in,out] next input starting node or,
166 if null, root node. output next node or null.
167 @return teared node or null
169 A_EXTERN a_rbt_node
*a_rbt_tear(a_rbt
*root
, a_rbt_node
**next
);
172 @brief search specified content from red–black binary search tree
173 @param[in] root red–black binary search tree root
174 @param[in] ctx specified content
175 @param[in] cmp a function that compares two nodes
176 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
177 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
178 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
179 @return specified node or null
181 A_EXTERN a_rbt_node
*a_rbt_search(a_rbt
const *root
, void const *ctx
, int (*cmp
)(void const *, void const *));
184 @brief insert specified node into red–black binary search tree
185 @param[in] root red–black binary search tree root
186 @param[in] node specified tree node
187 @param[in] cmp a function that compares two nodes
188 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
189 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
190 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
191 @return null or duplicate node
193 A_EXTERN a_rbt_node
*a_rbt_insert(a_rbt
*root
, a_rbt_node
*node
, int (*cmp
)(void const *, void const *));
196 @brief rebalance the tree after insertion of the specified node
197 @param[in] root red–black binary search tree root
198 @param[in] node insert tree node
200 A_EXTERN
void a_rbt_insert_adjust(a_rbt
*root
, a_rbt_node
*node
);
203 @brief remove specified node from red–black binary search tree
204 @param[in] root red–black binary search tree root
205 @param[in] node specified tree node
207 A_EXTERN
void a_rbt_remove(a_rbt
*root
, a_rbt_node
*node
);
209 #if defined(__cplusplus)
211 #endif /* __cplusplus */
214 @brief access the struct for this entry
215 @param ptr the &a_rbt_node pointer
216 @param type the type of the struct this is embedded in
217 @param member the name of the a_rbt_node within the struct
219 #define a_rbt_entry(ptr, type, member) a_container_of(ptr, type, member)
222 @brief iterate over a red–black binary search tree in-order
228 a_rbt root = A_RBT_ROOT;
229 a_rbt_foreach(cur, &root)
231 T *it = a_rbt_entry(cur, T, node);
234 @param cur the &a_rbt_node to use as a loop counter
235 @param root red–black binary search tree root
237 #define a_rbt_foreach(cur, root) \
238 for (a_rbt_node *cur = a_rbt_head(root); cur; cur = a_rbt_next(cur))
239 #define A_RBT_FOREACH(cur, root) \
240 for (cur = a_rbt_head(root); cur; cur = a_rbt_next(cur))
243 @brief iterate over a red–black binary search tree in-order reverse
249 a_rbt root = A_RBT_ROOT;
250 a_rbt_foreach_reverse(cur, &root)
252 T *it = a_rbt_entry(cur, T, node);
255 @param cur the &a_rbt_node to use as a loop counter
256 @param root red–black binary search tree root
258 #define a_rbt_foreach_reverse(cur, root) \
259 for (a_rbt_node *cur = a_rbt_tail(root); cur; cur = a_rbt_prev(cur))
260 #define A_RBT_FOREACH_REVERSE(cur, root) \
261 for (cur = a_rbt_tail(root); cur; cur = a_rbt_prev(cur))
264 @brief iterate over a red–black binary search tree preorder
270 a_rbt root = A_RBT_ROOT;
271 a_rbt_pre_foreach(cur, &root)
273 T *it = a_rbt_entry(cur, T, node);
276 @param cur the &a_rbt_node to use as a loop counter
277 @param root red–black binary search tree root
279 #define a_rbt_pre_foreach(cur, root) \
280 for (a_rbt_node *cur = (root)->node; cur; cur = a_rbt_pre_next(cur))
281 #define A_RBT_PRE_FOREACH(cur, root) \
282 for (cur = (root)->node; cur; cur = a_rbt_pre_next(cur))
285 @brief iterate over a red–black binary search tree preorder reverse
291 a_rbt root = A_RBT_ROOT;
292 a_rbt_pre_foreach_reverse(cur, &root)
294 T *it = a_rbt_entry(cur, T, node);
297 @param cur the &a_rbt_node to use as a loop counter
298 @param root red–black binary search tree root
300 #define a_rbt_pre_foreach_reverse(cur, root) \
301 for (a_rbt_node *cur = (root)->node; cur; cur = a_rbt_pre_prev(cur))
302 #define A_RBT_PRE_FOREACH_REVERSE(cur, root) \
303 for (cur = (root)->node; cur; cur = a_rbt_pre_prev(cur))
306 @brief iterate over a red–black binary search tree postorder
312 a_rbt root = A_RBT_ROOT;
313 a_rbt_post_foreach(cur, &root)
315 T *it = a_rbt_entry(cur, T, node);
318 @param cur the &a_rbt_node to use as a loop counter
319 @param root red–black binary search tree root
321 #define a_rbt_post_foreach(cur, root) \
322 for (a_rbt_node *cur = a_rbt_post_head(root); cur; cur = a_rbt_post_next(cur))
323 #define A_RBT_POST_FOREACH(cur, root) \
324 for (cur = a_rbt_post_head(root); cur; cur = a_rbt_post_next(cur))
327 @brief iterate over a red–black binary search tree postorder reverse
333 a_rbt root = A_RBT_ROOT;
334 a_rbt_post_foreach_reverse(cur, &root)
336 T *it = a_rbt_entry(cur, T, node);
339 @param cur the &a_rbt_node to use as a loop counter
340 @param root red–black binary search tree root
342 #define a_rbt_post_foreach_reverse(cur, root) \
343 for (a_rbt_node *cur = a_rbt_post_tail(root); cur; cur = a_rbt_post_prev(cur))
344 #define A_RBT_POST_FOREACH_REVERSE(cur, root) \
345 for (cur = a_rbt_post_tail(root); cur; cur = a_rbt_post_prev(cur))
348 @brief tear a red–black binary search tree using postorder traversal
354 a_rbt root = A_AVL_ROOT;
355 a_rbt_fortear(cur, next, &root)
357 T *it = a_rbt_entry(cur, T, node);
360 @param cur the &a_rbt_node to use as a loop counter
361 @param next the &a_rbt_node to use as next node
362 @param root red–black binary search tree root
364 #define a_rbt_fortear(cur, next, root) \
365 for (a_rbt_node *next = A_NULL, *cur = a_rbt_tear(root, &next); cur; cur = a_rbt_tear(root, &next))
366 #define A_RBT_FORTEAR(cur, next, root) \
367 for ((void)(next = A_NULL), cur = a_rbt_tear(root, &next); cur; cur = a_rbt_tear(root, &next))