11 #define AVLF_BALMASK 3u
12 #define AVLBAL_LBIAS 1u
13 #define AVLBAL_EVEN 0u
14 #define AVLBAL_RBIAS 2u
17 /* The maximum possible height %$H_n$% for an AVL tree containing %$n$% nodes
18 * is somewhat annoying to calculate. The best way to start is to reverse
19 * the question and find the smallest number %$N_h$% of nodes which can force
20 * the tree to have height %$h$%.
22 * This is going to involve a recurrence. The base case is the rather
23 * unsurprising observations that %$N_0 = 0$% and %$N_1 = 1$%.
25 * The imbalance between the root's left and right subtrees can be at most 1.
26 * The cheapest way we can make a tree with height %$h$%, then, is if the
27 * root is biased to the left (say) and then its left and right subtrees are
28 * the smallest trees with height %$h - 1$% and %$h - 2$% respectively. We
29 * have the oddly familiar recurrence
31 * %$N_h = N_{h-1} + N_{h-2} + 1$%.
33 * Guess that %$N_h = x^h + C$% for some constants %$x$% and %$C$%. Then
35 * %$x^h + C = x^{h-1} + x^{h-2} + 2 C + 1$%,
39 * %$x^h = x^{h-1} + x^{h-2} + C + 1$%,
41 * so setting %$C = -1$% seems like the best bet; that leaves
43 * %$x^h = x^{h-1} + x^{h-2}%,
45 * which is well-known to be solved by setting %$x = \phi$% or
46 * %$x = \bar{\phi}$%, where
48 * %$\displaystyle \phi = \frac{1 + \sqrt{5}}{2}$%
52 * %$\displaystyle \bar{\phi} = \frac{1 - \sqrt{5}}{2}$%.
54 * This relationship clearly holds for any linear combination of %$\phi$% and
55 * %$\bar{\phi}$%. So we finally set
57 * %$N_h = A \phi^h + B \bar{\phi}^h - 1$%
59 * and check the initial conditions. %$N_0 = 0$% forces %$A + B = 1$%. And
62 * %$A \phi + B \bar{\phi} = 2$%;
64 * substituting %$\phi$% and %$\bar{\phi}$% and rearranging gives
66 * %$(A + B) + \sqrt{5} (A - B) = 4$%.
68 * We know %$A + B = 1$%, so %$A - B = 3/\sqrt{5} = 3 \sqrt{5}/5$%. Adding
71 * %$\displaystyle A = \frac{5 + 3 \sqrt{5}}{10}$%
75 * %$\displaystyle B = \frac{5 - 3 \sqrt{5}}{10}$%.
77 * What we actually wanted to know was the maximum possible height %$H_n$%
78 * for a red-black tree with %$n$% nodes. Suppose, then, that, for some
79 * %$h$%, the tree has %$n \ge N_h \ge A \phi^h + B \bar{\phi}^h - 1$% nodes.
80 * Notice that %$|B < 1$% and %$|\bar{\phi}| < 1$%; therefore,
81 * %$|B \bar{\phi}^h| < 1$%, and we have %$n \ge A \phi^h - 2$%. (Sadly,
82 * %$\bar{\phi}$% is negative.)
84 * Continuing, we see %$A \phi^h \le n + 2$%. Taking (binary) logs gives
85 * %$h \lg \phi + \lg A \le \lg (n + 2)$%, whence
87 * %$\displaystyle h\le\frac{\lg (n + 2) - \lg A}{\lg \phi}$%.
89 * This is pretty gnarly to evaluate with the C preprocessor. Fortunately,
90 * $%0 < 13/9 - 1/\lg \phi < 1/200$%, so
92 * %$\displaystyle h \le \frac{13}{9}\lg(n+2) - \frac{\lg A}{\lg\phi}$%.
94 * In fact, we can do better . As %$n$% gets larger, the difference
95 * %$\log (n + 2) - \log n$% tends to zero. There is therefore a value %$N$%
98 * %$\displaystyle \frac{13}{9}\lg n\ge\frac{\lg(n+2)-\lg A}{\lg\phi}$%
100 * whenever %$n \ge N$%.
102 * This is too horrid to solve by hand, but numerical methods show that
103 * %$N = 12$% satisfies our requirements. We must, of course, round up
104 * rather than down while computing this.
106 * Our %$n$% of interest is the largest value that can fit in @size_t@, which
107 * is an unsigned type; therefore %$n = 2^k - 1$% for some %$k$%, and
108 * %$\floor{\lg (n + 2)} = k$%. Alas, C doesn't give us %$k$% directly, but
109 * it can certainly be no more than @CHAR_BIT*sizeof(size_t)@; since padding
110 * bits in integers are extremely rare, this is usually the exact value. C
111 * permits objects at least %$2^{15} - 1$% bytes in size, so this must be at
112 * least that large. In particular, it's larger than %$12$%, so we can apply
113 * this simplification.
115 * On conventional 32-bit targets, this is 47; on 64-bit targets, it's 93.
116 * Both overestimate by one entry.
119 #define AVLTREE_PATHMAX (13*(sizeof(size_t)*CHAR_BIT + 8)/9)
123 struct bstnode **p[AVLTREE_PATHMAX];
128 struct bstnode *stack[AVLTREE_PATHMAX];
131 /* --- @avltree_check@ --- *
133 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
134 * @struct avlnode *const *root@ = root pointer that we're
136 * @int expht@ = expected height for tree, or %$-1$% if unknown
137 * @void *arg@ = argument to pass to check function
139 * Returns: Zero if everything was OK, %$-1$% if problems were found and
142 * Use: Recursively examine an AVL tree, checking that it satisfies
143 * all of the necessary invariants.
146 extern int avltree_check(struct bstree_nodecls */*cls*/,
147 struct bstnode *const */*root*/, int /*expht*/,
150 /* --- @avltree_height@ --- *
152 * Arguments: @const struct avlnode *node@ = pointer to a tree node
154 * Returns: The height for the (sub)tree rooted at @node@. This is
155 * primarily useful as input to @avltree_join@ and
159 extern int avltree_height(const struct avlnode */*node*/);
161 /* --- @avltree_lookup@ --- *
163 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
164 * @struct bstnode *root@ = pointer to root node
165 * @void *arg@ = argument to the navigation function
167 * Returns: Pointer to the matching node, or null if it couldn't be
170 * Use: Search for a node within the tree according to the navigation
174 extern void *avltree_lookup(struct bstree_nodecls */*cls*/,
175 struct bstnode */*root*/, void */*arg*/);
177 /* --- @avltree_probe@ --- *
179 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
180 * @struct bstnode **root@ = pointer to root link
181 * @const void *search_key@ = the key to search for
182 * @struct avlpath *path@ = path to fill in
184 * Returns: Pointer to the matching node, or null if it couldn't be
187 * Use: Search for a node within the tree according to the navigation
188 * function, recording the search path This can be used later,
189 * e.g., by @avltree_insert@ to insert a new node if none was
190 * found, or by @avltree_remove@ to remove the node that was
194 extern void *avltree_probe(struct bstree_nodecls */*cls*/,
195 struct bstnode **/*root*/, void */*arg*/,
196 struct avlpath */*path*/);
198 /* --- @avltree_inititer@ --- *
200 * Arguments: @struct bstnode *root@ = pointer to the tree header
201 * @struct avliter *it@ = pointer to iterator to initialize
205 * Use: Initialize an iterator.
208 extern void avltree_inititer(struct bstnode */*root*/,
209 struct avliter */*it*/);
211 /* --- @avltree_next@ --- *
213 * Arguments: @struct avliter *it@ = pointer to iterator
215 * Returns: A pointer to the next node in ascending order, or null
216 * if no more nodes remain.
218 * Use: Advances a tree iterator. Inserting or removing elements
219 * invalidates the iterator. As a special exception, it is
220 * permitted to free all of the nodes by iterating over the tree
221 * in the obvious manner:
223 * @avltree_inititer(tree, &it);@
225 * @node = avltree_next(&it); if (!node) break;@
229 * At this point, the tree header structure is left in an
230 * invalid state, and must not be used; it is, however, safe to
231 * discard, since it holds no resources.
234 extern void *avltree_next(struct avliter */*it*/);
236 /* --- @avltree_firstpath@, @avltree_lastpath@ --- *
238 * Arguments: @struct bstnode **root@ = address of the tree root link
239 * @struct avlpath *path@ = path to fill in
241 * Returns: Pointer to the requested node, or null if the tree is empty.
243 * Use: Return the first or last node in the tree, as ordered by
244 * their keys, together with a path to the requested node, which
245 * can be used to remove them, or to navigate to other nodes in
249 extern void *avltree_firstpath(struct bstnode **/*root*/,
250 struct avlpath */*path*/);
251 extern void *avltree_lastpath(struct bstnode **/*root*/,
252 struct avlpath */*path*/);
254 /* --- @avltree_nextpath@, @avltree_prevpath@ --- *
256 * Arguments: @struct avlpath *path@ = path to update
258 * Returns: Pointer to the requested node, or null if the tree is empty
259 * or the path is already positioned at the relevant extreme.
261 * Use: Return the next or previous node in the tree, as ordered by
262 * their keys, together with a path to the requested node, which
263 * can be used to remove them, or to navigate to other nodes in
266 * If the path is full, i.e., refers to an existing node, then
267 * the functions return that node's successor or predecessor.
268 * If the path is empty, i.e., refers to a space between nodes
269 * where a new node can be inserted, then the functions return
270 * the node at the upper or lower end of the gap, unless the
271 * `gap' is actually at an extreme of the tree and no such node
272 * exists. In the latter case, a null pointer is returned.
273 * The path is modified to refer to the new node, if any, or to
274 * the gap at the appropriate extreme of the tree.
277 extern void *avltree_nextpath(struct avlpath */*path*/);
278 extern void *avltree_prevpath(struct avlpath */*path*/);
280 /* --- @avltree_beforepath@, @avltree_afterpath@ --- *
282 * Arguments: @struct avlpath *path@ = path to update
286 * Use: Advance the path to just before or after the current node.
287 * The path thereby becomes empty, suitable to insert an element
288 * or split the tree just before or after the previously
292 extern void avltree_afterpath(struct avlpath */*path*/);
293 extern void avltree_beforepath(struct avlpath */*path*/);
295 /* --- @avltree_replace@ --- *
297 * Arguments: @struct avlpath *path@ = pointer to a full path
298 * @struct avlnode *node@ = pointer to replacement node
302 * Use: Replace the node identified by the @path@ with the given
303 * @node@. The replacement @node@ should have the same (equal,
304 * according to the node-class comparison function) key as the
305 * node it replaces, and %%\emph{must}%% be strictly between the
306 * keys of the old node's predecessor and successor. The node's
307 * links need not be initialized. Paths and iterators are not
311 extern void avltree_replace(struct avlpath */*path*/,
312 struct avlnode */*node*/);
314 /* --- @avltree_insert@ --- *
316 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
317 * @struct avlpath *path@ = pointer to an empty path
318 * @struct avlnode *node@ = the new node to add
320 * Returns: Adjustment (%$0$% or %$+1$%) to the tree height.
322 * Use: Add a new node to the tree, in the place determined by the
323 * empty path. The @new_node@'s key must be equal to the key
324 * passed to @avltree_probe@ when it produced the path.
326 * The new node is not copied, and its storage must remain valid
327 * until the node is removed or the tree is discarded.
330 extern int avltree_insert(struct bstree_nodecls */*cls*/,
331 struct avlpath */*path*/,
332 struct avlnode */*node*/);
334 /* --- @avltree_remove@ --- *
336 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
337 * @struct avlpath *path@ = pointer to a full path
339 * Returns: Adjustment (%$0$% or %$-1$%) to the tree height.
341 * Use: Removes the node identified by the path. The node was
342 * allocated by the caller, and should be freed by the caller in
343 * whatever way is appropriate.
346 extern int avltree_remove(struct bstree_nodecls */*cls*/,
347 struct avlpath */*path*/);
349 /* --- @avltree_join@ --- *
351 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
352 * @struct bstnode **root_out@ = address to store the link to
353 * the root of the combined tree
354 * @struct bstnode **left@ = address containing the current
355 * root of the left tree
356 * @int lht@ = height of the left tree, or %$-1$% if unknown
357 * @struct bstnode *mid@ = pointer to middle node, or null
358 * @struct bstnode **right@ = address containing the current
359 * root of the right tree
360 * @int rht@ = height of the right tree, or %$-1$% if unknown
362 * Returns: The height of the combined tree.
364 * Use: Concatenate two trees.
366 * Every node in the left tree must have a key strictly less
367 * than any node of the right tree. If a middle node is
368 * provided, then its key must be greater than that of any node
369 * in the left tree, and less than that of any node in the right
372 * The output is a single tree containing every node in the left
373 * and right input trees, together with the middle node, if that
376 * The @root_out@ pointer may equal either @left@ or @right@
377 * (or, indeed, both, only if both are empty). If @lroot@ is
378 * distinct from @root_out@ then it @*left@ set null on exit;
379 * similarly, if @rroot@ is distinct from @root_out@, then
380 * @*right@ is set null on exit.
383 extern int avltree_join(struct bstree_nodecls */*cls*/,
384 struct bstnode **/*root_out*/,
385 struct bstnode **/*left*/, int /*lht*/,
386 struct bstnode */*mid*/,
387 struct bstnode **/*right*/, int /*rht*/);
389 /* --- @avltree_split@ --- *
391 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
392 * @struct bstnode *left_out@ = where to leave the root of the
393 * resulting left tree
394 * @int *lht_out@ = where to leave the height of the left tree,
395 * or null to discard this information
396 * @int *mht_out@ = where to leave the height of the middle node
397 * (either zero or one), or null to discard this
399 * @struct bstnode *rirght_out@ = where to leave the root of the
400 * resulting right tree
401 * @int *rht_out@ = where to leave the height of the right tree,
402 * or null to discard this information
403 * @struct avlpath *path@ = full or empty path at which to split
406 * Returns: A pointer to the resulting middle node, or null.
408 * Use: Split a tree into two at an indicated place.
410 * The splitting operation produces two trees, a `left tree'
411 * containing every node preceding the given path, and a `right
412 * tree' containing every node following the path. If the path
413 * is full, i.e., it denotes a node in the input tree, then that
414 * becomes the `middle node', which does not appear in either
415 * tree, and is returned separately.
418 extern void *avltree_split(struct bstree_nodecls */*cls*/,
419 struct bstnode **/*left_out*/, int */*lht_out*/,
421 struct bstnode **/*right_out*/, int */*rht_out*/,
422 struct avlpath */*path*/);
424 /* --- @avltree_splitat@ --- *
426 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
427 * @struct bstnode *left_out@ = where to leave the root of the
428 * resulting left tree
429 * @int *lht_out@ = where to leave the height of the left tree,
430 * or null to discard this information
431 * @int *mht_out@ = where to leave the height of the middle
432 * node (either zero or one), or null to discard this
434 * @struct bstnode *right_out@ = where to leave the root of the
435 * resulting right tree
436 * @int *rht_out@ = where to leave the height of the right tree,
437 * or null to discard this information
438 * @struct bstnode **root@ = address of the root link of the
440 * @const void *key@ = key at which to split the tree.
442 * Returns: A pointer to the matching middle node, or null.
444 * Use: Split a tree into two at an indicated key.
446 * The splitting operation produces two trees, a `left tree'
447 * containing every node whose key is less than @key@, and a
448 * `right tree' containing every node whose key is greater than
449 * @key@. If a node matching the @key@ exists in the input
450 * tree, then that becomes the `middle node', which does not
451 * appear in either tree, and is returned separately.
454 extern void *avltree_splitat(struct bstree_nodecls */*cls*/,
455 struct bstnode **/*left_out*/,
458 struct bstnode **/*right_out*/,
460 struct bstnode **/*root*/, const void */*key*/);
462 /* --- @avltree_splitroot@ --- *
464 * Arguments: @struct bstnode *left_out@ = where to leave the root of the
465 * resulting left tree
466 * @int *lht_out@ = where to leave the height of the left
467 * tree, or null to discard this information
468 * @int *mht_out@ = where to leave the height of the
469 * middle node (either zero or one), or null to discard
471 * @struct bstnode *right_out@ = where to leave the root of the
472 * resulting right tree
473 * @int *rht_out@ = where to leave the height of the right
474 * tree, or null to discard this information
475 * @struct bstnode **root@ = tree root node, or null
476 * @int ht@ = height of the tree, or %$-1$% if unknown
478 * Returns: A pointer to the resulting middle node, or null.
480 * Use: Split a tree into two at its root.
482 * The splitting operation produces two trees, a `left tree'
483 * containing every node preceding the root, and a `right
484 * tree' containing every node following the root, together with
485 * the root. If the root is null, then the left and right trees
489 extern void *avltree_splitroot(struct bstnode **/*left_out*/,
492 struct bstnode **/*right_out*/,
494 struct bstnode **/*root*/, int /*ht*/);
496 /* --- @avltree_unisect@ --- *
498 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
499 * @struct bstnode **uni_out@ = where to write the union root
500 * @int *uniht_out@ = where to put the union height (or null)
501 * @struct bstnode **isect_out@ = where to write the
503 * @int *isectht_out@ = where to put the intersection height (or
505 * @struct bstnode *a@ = pointer to first operand root node
506 * @int aht@ = first operand height, or %$-1$%
507 * @struct bstnode *b@ = pointer to second operand root node
508 * @int bht@ = second operand height, or %$-1$%
512 * Use: Compute the union and intersection of the two operand trees.
514 * The original trees are destroyed. Each node in the original
515 * operands trees ends up in exactly one of the result trees.
518 extern void avltree_unisect(struct bstree_nodecls */*cls*/,
519 struct bstnode **/*uni_out*/,
521 struct bstnode **/*isect_out*/,
522 int */*isectht_out*/,
523 struct bstnode **/*aroot*/, int /*aht*/,
524 struct bstnode **/*broot*/, int /*bht*/);
526 /* --- @avltree_diffsect@ --- *
528 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
529 * @struct bstnode **diff_out@ = where to write the difference
531 * @int *diffht_out@ = where to put the difference height (or
533 * @struct bstnode **isect_out@ = where to write the
535 * @int *isectht_out@ = where to put the intersection height (or
537 * @struct bstnode *a@ = pointer to first operand root node
538 * @int aht@ = first operand height, or %$-1$%
539 * @struct bstnode *b@ = pointer to second operand root node
543 * Use: Compute the difference -- i.e., those nodes in %$a$% without
544 * matching nodes in %$b$% -- and intersection of the two
547 * The original tree %$a$% is destroyed. Each node in the
548 * original operands tree ends up in exactly one of the result
549 * trees. The input tree %$b$% is unchanged.
552 extern void avltree_diffsect(struct bstree_nodecls */*cls*/,
553 struct bstnode **/*diff_out*/,
555 struct bstnode **/*isect_out*/,
556 int */*isectht_out*/,
557 struct bstnode **/*aroot*/, int /*aht*/,
558 struct bstnode **/*broot*/);