3 @brief Adelson-Velsky and Landis self-balancing binary search tree
13 @addtogroup A_AVL AVL binary search tree
18 #define A_AVL_ROOT {A_NULL}
22 @brief instance structure for AVL binary search tree node
24 typedef struct a_avl_node
26 struct a_avl_node
*left
; /*!< pointer to left child or null */
27 struct a_avl_node
*right
; /*!< pointer to right child or null */
28 /*! pointer to parent combined with the balance factor
29 Low 2 bits: One greater than the balance factor of this subtree,
30 which is equal to height(right) - height(left). The mapping is:
35 The rest of the bits are the pointer to the parent node. It must be 4-byte aligned,
36 and it will be null if this is the root node and therefore has no parent.
38 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
40 #else /* !A_SIZE_POINTER */
41 struct a_avl_node
*parent
;
43 #endif /* A_SIZE_POINTER */
47 @brief access parent of AVL binary search tree node
48 @param[in] node points to AVL binary search tree node
49 @return a pointer to the parent of the specified AVL tree node,
50 or null if it is already the root of the tree.
52 A_INTERN a_avl_node
*a_avl_parent(a_avl_node
const *node
)
54 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
55 return a_cast_r(a_avl_node
*, node
->parent_
& ~a_uptr_c(3));
56 #else /* !A_SIZE_POINTER */
58 #endif /* A_SIZE_POINTER */
62 @brief initialize for AVL binary search tree node
63 @param[in] node node to be initialized
64 @param[in] parent node parent
65 @return initialized node
67 A_INTERN a_avl_node
*a_avl_init(a_avl_node
*node
, a_avl_node
*parent
)
69 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
70 node
->parent_
= a_cast_r(a_uptr
, parent
) | 1;
71 #else /* !A_SIZE_POINTER */
72 node
->parent
= parent
;
74 #endif /* A_SIZE_POINTER */
81 @brief instance structure for AVL binary search tree root
85 struct a_avl_node
*node
; //!< root node
89 @brief initialize for AVL binary search tree root
90 @param[in,out] root AVL binary search tree root
92 A_INTERN
void a_avl_root(a_avl
*root
) { root
->node
= A_NULL
; }
94 #if defined(__cplusplus)
96 #endif /* __cplusplus */
99 @brief access head node of AVL binary search tree in-order
100 @param[in] root AVL binary search tree root
101 @return head node or null
103 A_EXTERN a_avl_node
*a_avl_head(a_avl
const *root
);
106 @brief access tail node of AVL binary search tree in-order
107 @param[in] root AVL binary search tree root
108 @return tail node or null
110 A_EXTERN a_avl_node
*a_avl_tail(a_avl
const *root
);
113 @brief access next node of AVL binary search tree node in-order
114 @param[in] node AVL binary search tree node
115 @return next node or null
117 A_EXTERN a_avl_node
*a_avl_next(a_avl_node
*node
);
120 @brief access prev node of AVL binary search tree node in-order
121 @param[in] node AVL binary search tree node
122 @return prev node or null
124 A_EXTERN a_avl_node
*a_avl_prev(a_avl_node
*node
);
127 @brief access next node of AVL binary search tree node preorder
128 @param[in] node AVL binary search tree node
129 @return next node or null
131 A_EXTERN a_avl_node
*a_avl_pre_next(a_avl_node
*node
);
134 @brief access prev node of AVL binary search tree node preorder
135 @param[in] node AVL binary search tree node
136 @return prev node or null
138 A_EXTERN a_avl_node
*a_avl_pre_prev(a_avl_node
*node
);
141 @brief access head node of AVL binary search tree postorder
142 @param[in] root AVL binary search tree root
143 @return head node or null
145 A_EXTERN a_avl_node
*a_avl_post_head(a_avl
const *root
);
148 @brief access tail node of AVL binary search tree postorder
149 @param[in] root AVL binary search tree root
150 @return tail node or null
152 A_EXTERN a_avl_node
*a_avl_post_tail(a_avl
const *root
);
155 @brief access next node of AVL binary search tree node postorder
156 @param[in] node AVL binary search tree node
157 @return next node or null
159 A_EXTERN a_avl_node
*a_avl_post_next(a_avl_node
*node
);
162 @brief access prev node of AVL binary search tree node postorder
163 @param[in] node AVL binary search tree node
164 @return prev node or null
166 A_EXTERN a_avl_node
*a_avl_post_prev(a_avl_node
*node
);
169 @brief tear a node from AVL binary search tree
170 @param[in] root AVL binary search tree root
171 @param[in,out] next input starting node or,
172 if null, root node. output next node or null.
173 @return teared node or null
175 A_EXTERN a_avl_node
*a_avl_tear(a_avl
*root
, a_avl_node
**next
);
178 @brief search specified content from AVL binary search tree
179 @param[in] root AVL binary search tree root
180 @param[in] ctx specified content
181 @param[in] cmp a function that compares two nodes
182 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
183 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
184 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
185 @return specified node or null
187 A_EXTERN a_avl_node
*a_avl_search(a_avl
const *root
, void const *ctx
, int (*cmp
)(void const *, void const *));
190 @brief insert specified node into AVL binary search tree
191 @param[in] root AVL binary search tree root
192 @param[in] node specified tree node
193 @param[in] cmp a function that compares two nodes
194 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
195 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
196 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
197 @return null or duplicate node
199 A_EXTERN a_avl_node
*a_avl_insert(a_avl
*root
, a_avl_node
*node
, int (*cmp
)(void const *, void const *));
202 @brief rebalance the tree after insertion of the specified node
203 @param[in] root AVL binary search tree root
204 @param[in] node insert tree node
206 A_EXTERN
void a_avl_insert_adjust(a_avl
*root
, a_avl_node
*node
);
209 @brief remove specified node from AVL binary search tree
210 @param[in] root AVL binary search tree root
211 @param[in] node specified tree node
213 A_EXTERN
void a_avl_remove(a_avl
*root
, a_avl_node
*node
);
215 #if defined(__cplusplus)
217 #endif /* __cplusplus */
220 @brief access the struct for this entry
221 @param ptr the &a_avl_node pointer
222 @param type the type of the struct this is embedded in
223 @param member the name of the a_avl_node within the struct
225 #define a_avl_entry(ptr, type, member) a_container_of(ptr, type, member)
228 @brief iterate over a AVL binary search tree in-order
234 a_avl root = A_AVL_ROOT;
235 a_avl_foreach(cur, &root)
237 T *it = a_avl_entry(cur, T, node);
240 @param cur the &a_avl_node to use as a loop counter
241 @param root AVL binary search tree root
243 #define a_avl_foreach(cur, root) \
244 for (a_avl_node *cur = a_avl_head(root); cur; cur = a_avl_next(cur))
247 @brief iterate over a AVL binary search tree in-order reverse
253 a_avl root = A_AVL_ROOT;
254 a_avl_foreach_reverse(cur, &root)
256 T *it = a_avl_entry(cur, T, node);
259 @param cur the &a_avl_node to use as a loop counter
260 @param root AVL binary search tree root
262 #define a_avl_foreach_reverse(cur, root) \
263 for (a_avl_node *cur = a_avl_tail(root); cur; cur = a_avl_prev(cur))
266 @brief iterate over a AVL binary search tree preorder
272 a_avl root = A_AVL_ROOT;
273 a_avl_pre_foreach(cur, &root)
275 T *it = a_avl_entry(cur, T, node);
278 @param cur the &a_avl_node to use as a loop counter
279 @param root AVL binary search tree root
281 #define a_avl_pre_foreach(cur, root) \
282 for (a_avl_node *cur = (root)->node; cur; cur = a_avl_pre_next(cur))
285 @brief iterate over a AVL binary search tree preorder reverse
291 a_avl root = A_AVL_ROOT;
292 a_avl_pre_foreach_reverse(cur, &root)
294 T *it = a_avl_entry(cur, T, node);
297 @param cur the &a_avl_node to use as a loop counter
298 @param root AVL binary search tree root
300 #define a_avl_pre_foreach_reverse(cur, root) \
301 for (a_avl_node *cur = (root)->node; cur; cur = a_avl_pre_prev(cur))
304 @brief iterate over a AVL binary search tree postorder
310 a_avl root = A_AVL_ROOT;
311 a_avl_post_foreach(cur, &root)
313 T *it = a_avl_entry(cur, T, node);
316 @param cur the &a_avl_node to use as a loop counter
317 @param root AVL binary search tree root
319 #define a_avl_post_foreach(cur, root) \
320 for (a_avl_node *cur = a_avl_post_head(root); cur; cur = a_avl_post_next(cur))
323 @brief iterate over a AVL binary search tree postorder reverse
329 a_avl root = A_AVL_ROOT;
330 a_avl_post_foreach_reverse(cur, &root)
332 T *it = a_avl_entry(cur, T, node);
335 @param cur the &a_avl_node to use as a loop counter
336 @param root AVL binary search tree root
338 #define a_avl_post_foreach_reverse(cur, root) \
339 for (a_avl_node *cur = a_avl_post_tail(root); cur; cur = a_avl_post_prev(cur))
342 @brief tear a AVL binary search tree using postorder traversal
348 a_avl root = A_AVL_ROOT;
349 a_avl_fortear(cur, next, &root)
351 T *it = a_avl_entry(cur, T, node);
354 @param cur the &a_avl_node to use as a loop counter
355 @param next the &a_avl_node to use as next node
356 @param root AVL binary search tree root
358 #define a_avl_fortear(cur, next, root) \
359 for (a_avl_node *next = A_NULL, *cur = a_avl_tear(root, &next); cur; cur = a_avl_tear(root, &next))