3 @brief red–black self-balancing binary search tree
13 @addtogroup A_RBT red–black binary search tree
18 #define A_RBT_ROOT {A_NULL}
21 #define A_RBT_R 0 //!< red
22 #define A_RBT_B 1 //!< black
25 @brief instance structure for red–black binary search tree node
27 typedef struct a_rbt_node
29 struct a_rbt_node
*left
; /*!< pointer to left child or null */
30 struct a_rbt_node
*right
; /*!< pointer to right child or null */
31 /*! pointer to parent combined with the color. The mapping is: 0 => red, 1 => black.
32 The rest of the bits are the pointer to the parent node. It must be 2-byte aligned,
33 and it will be null if this is the root node and therefore has no parent.
35 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
37 #else /* !A_SIZE_POINTER */
38 struct a_rbt_node
*parent
;
40 #endif /* A_SIZE_POINTER */
44 @brief access parent of red–black binary search tree node
45 @param[in] node points to red–black binary search tree node
46 @return a pointer to the parent of the specified red–black tree node,
47 or null if it is already the root of the tree.
49 A_INTERN a_rbt_node
*a_rbt_parent(a_rbt_node
const *node
)
51 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
52 return a_cast_r(a_rbt_node
*, node
->parent_
& ~a_uptr_c(1));
53 #else /* !A_SIZE_POINTER */
55 #endif /* A_SIZE_POINTER */
59 @brief initialize for red–black binary search tree node
60 @param[in] node node to be initialized
61 @param[in] parent node parent
62 @return initialized node
64 A_INTERN a_rbt_node
*a_rbt_init(a_rbt_node
*node
, a_rbt_node
*parent
)
66 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 1)
67 node
->parent_
= a_cast_r(a_uptr
, parent
);
68 #else /* !A_SIZE_POINTER */
69 node
->parent
= parent
;
70 node
->color
= A_RBT_R
;
71 #endif /* A_SIZE_POINTER */
78 @brief instance structure for red–black binary search tree root
82 struct a_rbt_node
*node
; //!< root node
86 @brief initialize for red–black binary search tree root
87 @param[in,out] root red–black binary search tree root
89 A_INTERN
void a_rbt_root(a_rbt
*root
) { root
->node
= A_NULL
; }
91 #if defined(__cplusplus)
93 #endif /* __cplusplus */
96 @brief access head node of red–black binary search tree in-order
97 @param[in] root red–black binary search tree root
98 @return head node or null
100 A_EXTERN a_rbt_node
*a_rbt_head(a_rbt
const *root
);
103 @brief access tail node of red–black binary search tree in-order
104 @param[in] root red–black binary search tree root
105 @return tail node or null
107 A_EXTERN a_rbt_node
*a_rbt_tail(a_rbt
const *root
);
110 @brief access next node of red–black binary search tree node in-order
111 @param[in] node red–black binary search tree node
112 @return next node or null
114 A_EXTERN a_rbt_node
*a_rbt_next(a_rbt_node
*node
);
117 @brief access prev node of red–black binary search tree node in-order
118 @param[in] node red–black binary search tree node
119 @return prev node or null
121 A_EXTERN a_rbt_node
*a_rbt_prev(a_rbt_node
*node
);
124 @brief access next node of red–black binary search tree node preorder
125 @param[in] node red–black binary search tree node
126 @return next node or null
128 A_EXTERN a_rbt_node
*a_rbt_pre_next(a_rbt_node
*node
);
131 @brief access prev node of red–black binary search tree node preorder
132 @param[in] node red–black binary search tree node
133 @return prev node or null
135 A_EXTERN a_rbt_node
*a_rbt_pre_prev(a_rbt_node
*node
);
138 @brief access head node of red–black binary search tree postorder
139 @param[in] root red–black binary search tree root
140 @return head node or null
142 A_EXTERN a_rbt_node
*a_rbt_post_head(a_rbt
const *root
);
145 @brief access tail node of red–black binary search tree postorder
146 @param[in] root red–black binary search tree root
147 @return tail node or null
149 A_EXTERN a_rbt_node
*a_rbt_post_tail(a_rbt
const *root
);
152 @brief access next node of red–black binary search tree node postorder
153 @param[in] node red–black binary search tree node
154 @return next node or null
156 A_EXTERN a_rbt_node
*a_rbt_post_next(a_rbt_node
*node
);
159 @brief access prev node of red–black binary search tree node postorder
160 @param[in] node red–black binary search tree node
161 @return prev node or null
163 A_EXTERN a_rbt_node
*a_rbt_post_prev(a_rbt_node
*node
);
166 @brief tear a node from red–black binary search tree
167 @param[in] root red–black binary search tree root
168 @param[in,out] next input starting node or,
169 if null, root node. output next node or null.
170 @return teared node or null
172 A_EXTERN a_rbt_node
*a_rbt_tear(a_rbt
*root
, a_rbt_node
**next
);
175 @brief search specified content from red–black binary search tree
176 @param[in] root red–black binary search tree root
177 @param[in] ctx specified content
178 @param[in] cmp a function that compares two nodes
179 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
180 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
181 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
182 @return specified node or null
184 A_EXTERN a_rbt_node
*a_rbt_search(a_rbt
const *root
, void const *ctx
, int (*cmp
)(void const *, void const *));
187 @brief insert specified node into red–black binary search tree
188 @param[in] root red–black binary search tree root
189 @param[in] node specified tree node
190 @param[in] cmp a function that compares two nodes
191 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
192 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
193 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
194 @return null or duplicate node
196 A_EXTERN a_rbt_node
*a_rbt_insert(a_rbt
*root
, a_rbt_node
*node
, int (*cmp
)(void const *, void const *));
199 @brief rebalance the tree after insertion of the specified node
200 @param[in] root red–black binary search tree root
201 @param[in] node insert tree node
203 A_EXTERN
void a_rbt_insert_adjust(a_rbt
*root
, a_rbt_node
*node
);
206 @brief remove specified node from red–black binary search tree
207 @param[in] root red–black binary search tree root
208 @param[in] node specified tree node
210 A_EXTERN
void a_rbt_remove(a_rbt
*root
, a_rbt_node
*node
);
212 #if defined(__cplusplus)
214 #endif /* __cplusplus */
217 @brief access the struct for this entry
218 @param ptr the &a_rbt_node pointer
219 @param type the type of the struct this is embedded in
220 @param member the name of the a_rbt_node within the struct
222 #define a_rbt_entry(ptr, type, member) a_container_of(ptr, type, member)
225 @brief iterate over a red–black binary search tree in-order
231 a_rbt root = A_RBT_ROOT;
232 a_rbt_foreach(cur, &root)
234 T *it = a_rbt_entry(cur, T, node);
237 @param cur the &a_rbt_node to use as a loop counter
238 @param root red–black binary search tree root
240 #define a_rbt_foreach(cur, root) \
241 for (a_rbt_node *cur = a_rbt_head(root); cur; cur = a_rbt_next(cur))
244 @brief iterate over a red–black binary search tree in-order reverse
250 a_rbt root = A_RBT_ROOT;
251 a_rbt_foreach_reverse(cur, &root)
253 T *it = a_rbt_entry(cur, T, node);
256 @param cur the &a_rbt_node to use as a loop counter
257 @param root red–black binary search tree root
259 #define a_rbt_foreach_reverse(cur, root) \
260 for (a_rbt_node *cur = a_rbt_tail(root); cur; cur = a_rbt_prev(cur))
263 @brief iterate over a red–black binary search tree preorder
269 a_rbt root = A_RBT_ROOT;
270 a_rbt_pre_foreach(cur, &root)
272 T *it = a_rbt_entry(cur, T, node);
275 @param cur the &a_rbt_node to use as a loop counter
276 @param root red–black binary search tree root
278 #define a_rbt_pre_foreach(cur, root) \
279 for (a_rbt_node *cur = (root)->node; cur; cur = a_rbt_pre_next(cur))
282 @brief iterate over a red–black binary search tree preorder reverse
288 a_rbt root = A_RBT_ROOT;
289 a_rbt_pre_foreach_reverse(cur, &root)
291 T *it = a_rbt_entry(cur, T, node);
294 @param cur the &a_rbt_node to use as a loop counter
295 @param root red–black binary search tree root
297 #define a_rbt_pre_foreach_reverse(cur, root) \
298 for (a_rbt_node *cur = (root)->node; cur; cur = a_rbt_pre_prev(cur))
301 @brief iterate over a red–black binary search tree postorder
307 a_rbt root = A_RBT_ROOT;
308 a_rbt_post_foreach(cur, &root)
310 T *it = a_rbt_entry(cur, T, node);
313 @param cur the &a_rbt_node to use as a loop counter
314 @param root red–black binary search tree root
316 #define a_rbt_post_foreach(cur, root) \
317 for (a_rbt_node *cur = a_rbt_post_head(root); cur; cur = a_rbt_post_next(cur))
320 @brief iterate over a red–black binary search tree postorder reverse
326 a_rbt root = A_RBT_ROOT;
327 a_rbt_post_foreach_reverse(cur, &root)
329 T *it = a_rbt_entry(cur, T, node);
332 @param cur the &a_rbt_node to use as a loop counter
333 @param root red–black binary search tree root
335 #define a_rbt_post_foreach_reverse(cur, root) \
336 for (a_rbt_node *cur = a_rbt_post_tail(root); cur; cur = a_rbt_post_prev(cur))
339 @brief tear a red–black binary search tree using postorder traversal
345 a_rbt root = A_AVL_ROOT;
346 a_rbt_fortear(cur, next, &root)
348 T *it = a_rbt_entry(cur, T, node);
351 @param cur the &a_rbt_node to use as a loop counter
352 @param next the &a_rbt_node to use as next node
353 @param root red–black binary search tree root
355 #define a_rbt_fortear(cur, next, root) \
356 for (a_rbt_node *next = A_NULL, *cur = a_rbt_tear(root, &next); cur; cur = a_rbt_tear(root, &next))