14 /* The maximum possible height %$H_n$% for a red-black tree containing %$n$%
15 * nodes is surprisingly hard to pin down. The best way to start is to
16 * reverse the question and find the smallest number %$N_h$% of nodes which
17 * can force the tree to have height %$h$%.
19 * A red-black tree has the same number -- the tree's `black-height' -- of
20 * black nodes on every path from root to leaf, and this will be the primary
21 * limitation on the structure of our trees. It's pretty obvious that the
22 * complete binary tree %$B_h$% containing %$2^h - 1$% nodes is the lightest
23 * red-black tree with black-height %$h$%.
25 * This is going to involve a recurrence. The base cases are the rather
26 * unsurprising observation that %$N_0 = 0$% and %$N_1 = 1$%.
28 * Because of the asymmetry between red and black nodes, the minimal tree
29 * structures will differ according to whether %$h$% is odd or even. Let's
30 * tackle the even case first.
32 * I claim that a minimal structure for a red-black tree with even height
33 * %$h \ge 2$% is %$S_h$%, which looks like this.
42 * Firstly, it has height %$h = (h - 2) + 2$%, node count %$2^{h/2+1} - 2$%,
43 * and black-height %$h/2$%; all of these are clear from induction.
45 * Secondly, this is a valid red-black tree. Inductively, %$S_{h-2}$% is a
46 * red-black tree, and therefore its root is black.
48 * And, thirdly, the node count and black-height are minimal for a tree of
49 * this height. That the black-height is minimal is immediate from the
50 * height, since a red node can only have black children. If a tree has
51 * height %$h$%, one of the root's grandchildren, %$s$% say, must be the
52 * root of a subtree with height %$h - 2$%. Let %$n$% and %$h'$% be
53 * respectively the node count and black-height of %$s$%; clearly
54 * %$h' \ge h/2 - 1$%. Let %$l$% be the parent of %$s$%, with %$b$% its
55 * sibling; let %$r$% be the sibling of %$l$%, and %$t$% be the tree root.
56 * The node %$b$% must have black-height %$h'$%, and hence at least
57 * %$2^{h'} - 1$% nodes. If %$l$% is red, then %$r$% must also have
58 * black-height %$h'$%; otherwise it has black-height %$h' + 1$%, and an
59 * additional %$2^{h'}$% nodes. These node counts are all minimized if %$s$%
60 * has minimal black-height and %$l$% is black. Furthermore, if %$s$% has
61 * more than %$2^{h/2} - 2$% nodes, then it can be replaced by a copy of
62 * %$S_{h-2}$% to reduce the overall node count.
64 * This proves that a red-black tree with even height %$h$% has at least
65 * %$2^{h/2+1} - 2$% nodes.
67 * We now turn to the case where %$h$% is odd. I claim that a minimal
68 * structure for a red-black tree with odd height %$h \ge 3$% is %$S_h$%,
69 * which looks like this.
76 * Firstly, it has height %$h = (h - 1) + 1$%, node count
77 * %$3 \cdot 2^{(h-1)/2} - 2$%, and black-height %$(h + 1)/2$%; all of these
78 * are immediate from the above, since %$h - 1$% is even.
80 * Secondly, this is a valid red-black tree. This is clear because the
81 * additional structure contains no red nodes, and the black-height is
84 * And, thirdly, the node count and black-height are minimal for a tree of
85 * this height. That the black-height is minimal is again immediate from the
86 * height. Let %$t$% be the root. One of %$t$%'s children, %$s$% say, must
87 * have height %$h - 1$%; let %$b$% be the sibling of %$s$%. The black-
88 * height of %$s$% must be at least %$(h - 1)/2$%, and therefore %$b$% must
89 * have at least %$2^{(h-1)/2}$% nodes. Suppose for a moment that the node
90 * %$s$% is red. Then, %$s$% has two children; one has height %$h - 2$%, and
91 * both have black-height %$(h - 1)/2$%. Inductively, these will have node
92 * counts of at least %$3 \cdot 2^{(h-3)/2} - 2$% and %$2^{(h-1)/2} - 1$%
93 * respectively, giving a total of %$5 \cdot 2^{(h-3)/2} - 3$%, so
94 * %$5 \cdot 2^{h-3}/2} - 2$% including %$s$% itself. On the other hand, if
95 * %$s$% is black, then its subtree has only %$2^{(h-1)/2+1} - 2$% nodes,
96 * which is fewer by %$2^{(h-3)/2}$%.
98 * This proves that a red-black tree with odd height %$h$% has at least
99 * %$3 \cdot 2^{(h-1)/2} - 2$% nodes.
101 * Having two different expressions is annoying. We'll take the smaller of
102 * the two. Notice that
104 * %$3 \cdot 2^{(h-1)/2} - 2 = 3/\sqrt{2} \cdot 2^{h/2} - 2$%,
108 * %$2^{h/2+1} - 2 = 2 \cdot 2^{h/2} - 2$%.
110 * Both %$3/\sqrt{2}$% and %$2$% are nonnegative, so squaring them will
111 * preserve their relative order; %$(3/\sqrt{2})^2 = 9/4$%, while
112 * %$2^2 = 4 = 8/4$%, so the former is larger. We therefore conclude that
113 * a red-black tree with height %$h$% must have at least %$2^{h/2+1} - 2$%
116 * Where were we? Oh, yes. What we actually wanted to know was the maximum
117 * possible height %$H_n$% for a red-black tree with %$n$% nodes. Suppose,
118 * then, that, for some %$h$%, the tree has %$n \ge N_h \ge 2^{h/2+1} - 2$%
119 * nodes. Then %$n + 2 \ge 2^{h/2+1}$%. Taking (binary) logs gives
120 * %$h/2 + 1 \le \lg (n + 2)$%, so
122 * %$h \le 2 \lg (n + 2) - 2$%.
124 * Our %$n$% of interest is the largest value that can fit in @size_t@, which
125 * is an unsigned type; therefore %$n = 2^k - 1$% for some %$k$%, and
126 * %$\floor{\lg (n + 2)} = k$%. Alas, C doesn't give us %$k$% directly, but
127 * it can certainly be no more than @CHAR_BIT*sizeof(size_t)@; since padding
128 * bits in integers are extremely rare, this is usually the exact value.
130 * On conventional 32-bit targets, this is 62; on 64-bit targets, it's 126.
132 #define RBTREE_PATHMAX (2*CHAR_BIT*sizeof(size_t) - 2)
136 struct bstnode **p[RBTREE_PATHMAX];
141 struct bstnode *stack[RBTREE_PATHMAX];
144 /* --- @rbtree_check@ --- *
146 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
147 * @struct rbnode *const *root@ = root pointer that we're
149 * @int blkht@ = expected black-height for tree, or %$-1$% if
151 * @void *arg@ = argument to pass to check function
153 * Returns: Zero if everything was OK, %$-1$% if problems were found and
156 * Use: Recursively examine a red-black tree, checking that it
157 * satisfies all of the necessary invariants.
160 extern int rbtree_check(struct bstree_nodecls */*cls*/,
161 struct bstnode *const */*root*/, int /*blkht*/,
164 /* --- @rbtree_height@ --- *
166 * Arguments: @const struct rbnode *node@ = pointer to a tree node
168 * Returns: The `black height' for the (sub)tree rooted at @node@. This
169 * is primarily useful as input to @rbtree_join@ and
173 extern int rbtree_height(const struct rbnode */*node*/);
175 /* --- @rbtree_lookup@ --- *
177 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
178 * @struct bstnode *root@ = pointer to root node
179 * @void *arg@ = argument to the navigation function
181 * Returns: Pointer to the matching node, or null if it couldn't be
184 * Use: Search for a node within the tree according to the navigation
188 extern void *rbtree_lookup(struct bstree_nodecls */*cls*/,
189 struct bstnode */*root*/, void */*arg*/);
191 /* --- @rbtree_probe@ --- *
193 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
194 * @struct bstnode **root@ = pointer to root link
195 * @const void *search_key@ = the key to search for
196 * @struct rbpath *path@ = path to fill in
198 * Returns: Pointer to the matching node, or null if it couldn't be
201 * Use: Search for a node within the tree according to the navigation
202 * function, recording the search path This can be used later,
203 * e.g., by @rbtree_insert@ to insert a new node if none was
204 * found, or by @rbtree_remove@ to remove the node that was
208 extern void *rbtree_probe(struct bstree_nodecls */*cls*/,
209 struct bstnode **/*root*/, void */*arg*/,
210 struct rbpath */*path*/);
212 /* --- @rbtree_inititer@ --- *
214 * Arguments: @struct bstnode *root@ = pointer to the tree header
215 * @struct rbiter *it@ = pointer to iterator to initialize
219 * Use: Initialize an iterator.
222 extern void rbtree_inititer(struct bstnode */*root*/, struct rbiter */*it*/);
224 /* --- @rbtree_next@ --- *
226 * Arguments: @struct rbiter *it@ = pointer to iterator
228 * Returns: A pointer to the next node in ascending order, or null
229 * if no more nodes remain.
231 * Use: Advances a tree iterator. Inserting or removing elements
232 * invalidates the iterator. As a special exception, it is
233 * permitted to free all of the nodes by iterating over the tree
234 * in the obvious manner:
236 * @rbtree_inititer(tree, &it);@
238 * @node = rbtree_next(&it); if (!node) break;@
242 * At this point, the tree header structure is left in an
243 * invalid state, and must not be used; it is, however, safe to
244 * discard, since it holds no resources.
247 extern void *rbtree_next(struct rbiter */*it*/);
249 /* --- @rbtree_firstpath@, @rbtree_lastpath@ --- *
251 * Arguments: @struct bstnode **root@ = address of the tree root link
252 * @struct rbpath *path@ = path to fill in
254 * Returns: Pointer to the requested node, or null if the tree is empty.
256 * Use: Return the first or last node in the tree, as ordered by
257 * their keys, together with a path to the requested node, which
258 * can be used to remove them, or to navigate to other nodes in
262 extern void *rbtree_firstpath(struct bstnode **/*root*/,
263 struct rbpath */*path*/);
264 extern void *rbtree_lastpath(struct bstnode **/*root*/,
265 struct rbpath */*path*/);
267 /* --- @rbtree_nextpath@, @rbtree_prevpath@ --- *
269 * Arguments: @struct rbpath *path@ = path to update
271 * Returns: Pointer to the requested node, or null if the tree is empty
272 * or the path is already positioned at the relevant extreme.
274 * Use: Return the next or previous node in the tree, as ordered by
275 * their keys, together with a path to the requested node, which
276 * can be used to remove them, or to navigate to other nodes in
279 * If the path is full, i.e., refers to an existing node, then
280 * the functions return that node's successor or predecessor.
281 * If the path is empty, i.e., refers to a space between nodes
282 * where a new node can be inserted, then the functions return
283 * the node at the upper or lower end of the gap, unless the
284 * `gap' is actually at an extreme of the tree and no such node
285 * exists. In the latter case, a null pointer is returned.
286 * The path is modified to refer to the new node, if any, or to
287 * the gap at the appropriate extreme of the tree.
290 extern void *rbtree_nextpath(struct rbpath */*path*/);
291 extern void *rbtree_prevpath(struct rbpath */*path*/);
293 /* --- @rbtree_beforepath@, @rbtree_afterpath@ --- *
295 * Arguments: @struct rbpath *path@ = path to update
299 * Use: Advance the path to just before or after the current node.
300 * The path thereby becomes empty, suitable to insert an element
301 * or split the tree just before or after the previously
305 extern void rbtree_afterpath(struct rbpath */*path*/);
306 extern void rbtree_beforepath(struct rbpath */*path*/);
308 /* --- @rbtree_replace@ --- *
310 * Arguments: @struct rbpath *path@ = pointer to a full path
311 * @struct rbnode *node@ = pointer to replacement node
315 * Use: Replace the node identified by the @path@ with the given
316 * @node@. The replacement @node@ should have the same (equal,
317 * according to the node-class comparison function) key as the
318 * node it replaces, and %%\emph{must}%% be strictly between the
319 * keys of the old node's predecessor and successor. The node's
320 * links need not be initialized. Paths and iterators are not
324 extern void rbtree_replace(struct rbpath */*path*/, struct rbnode */*node*/);
326 /* --- @rbtree_insert@ --- *
328 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
329 * @struct rbpath *path@ = pointer to an empty path
330 * @struct rbnode *node@ = the new node to add
332 * Returns: Adjustment (%$0$% or %$+1$%) to the tree black-height.
334 * Use: Add a new node to the tree, in the place determined by the
335 * empty path. The @new_node@'s key must be equal to the key
336 * passed to @rbtree_probe@ when it produced the path.
338 * The new node is not copied, and its storage must remain valid
339 * until the node is removed or the tree is discarded.
342 extern int rbtree_insert(struct bstree_nodecls */*cls*/,
343 struct rbpath */*path*/, struct rbnode */*node*/);
345 /* --- @rbtree_remove@ --- *
347 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
348 * @struct rbpath *path@ = pointer to a full path
350 * Returns: Adjustment (%$0$% or %$-1$%) to the tree black-height.
352 * Use: Removes the node identified by the path. The node was
353 * allocated by the caller, and should be freed by the caller in
354 * whatever way is appropriate.
357 extern int rbtree_remove(struct bstree_nodecls */*cls*/,
358 struct rbpath */*path*/);
360 /* --- @rbtree_join@ --- *
362 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
363 * @struct bstnode **root_out@ = address to store the link to
364 * the root of the combined tree
365 * @struct bstnode **left@ = address containing the current
366 * root of the left tree
367 * @int lht@ = black-height of the left tree, or %$-1$% if
369 * @struct bstnode *mid@ = pointer to middle node, or null
370 * @struct bstnode **right@ = address containing the current
371 * root of the right tree
372 * @int rht@ = black-height of the right tree, or %$-1$% if
375 * Returns: The black-height of the combined tree.
377 * Use: Concatenate two trees.
379 * Every node in the left tree must have a key strictly less
380 * than any node of the right tree. If a middle node is
381 * provided, then its key must be greater than that of any node
382 * in the left tree, and less than that of any node in the right
385 * The output is a single tree containing every node in the left
386 * and right input trees, together with the middle node, if that
389 * The @root_out@ pointer may equal either @left@ or @right@
390 * (or, indeed, both, only if both are empty). If @left@ is
391 * distinct from @root_out@ then @*left@ set null on exit;
392 * similarly, if @right@ is distinct from @root_out@, then
393 * @*right@ is set null on exit.
396 extern int rbtree_join(struct bstree_nodecls */*cls*/,
397 struct bstnode **/*root_out*/,
398 struct bstnode **/*left*/, int /*lht*/,
399 struct bstnode */*mid*/,
400 struct bstnode **/*right*/, int /*rht*/);
402 /* --- @rbtree_split@ --- *
404 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
405 * @struct bstnode *left_out@ = where to leave the root of the
406 * resulting left tree
407 * @int *lht_out@ = where to leave the black-height of the left
408 * tree, or null to discard this information
409 * @int *mht_out@ = where to leave the black-height of the
410 * middle node (either zero or one), or null to discard
412 * @struct bstnode *rirght_out@ = where to leave the root of the
413 * resulting right tree
414 * @int *rht_out@ = where to leave the black-height of the right
415 * tree, or null to discard this information
416 * @struct rbpath *path@ = full or empty path at which to split
419 * Returns: A pointer to the resulting middle node, or null.
421 * Use: Split a tree into two at an indicated place.
423 * The splitting operation produces two trees, a `left tree'
424 * containing every node preceding the given path, and a `right
425 * tree' containing every node following the path. If the path
426 * is full, i.e., it denotes a node in the input tree, then that
427 * becomes the `middle node', which does not appear in either
428 * tree, and is returned separately.
431 extern void *rbtree_split(struct bstree_nodecls */*cls*/,
432 struct bstnode **/*left_out*/, int */*lht_out*/,
434 struct bstnode **/*right_out*/, int */*rht_out*/,
435 struct rbpath */*path*/);
437 /* --- @rbtree_splitat@ --- *
439 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
440 * @struct bstnode *left_out@ = where to leave the root of the
441 * resulting left tree
442 * @int *lht_out@ = where to leave the black-height of the left
443 * tree, or null to discard this information
444 * @int *mht_out@ = where to leave the black-height of the
445 * middle node (either zero or one), or null to discard
447 * @struct bstnode *right_out@ = where to leave the root of the
448 * resulting right tree
449 * @int *rht_out@ = where to leave the black-height of the right
450 * tree, or null to discard this information
451 * @struct bstnode **root@ = address of the root link of the
453 * @const void *key@ = key at which to split the tree.
455 * Returns: A pointer to the matching middle node, or null.
457 * Use: Split a tree into two at an indicated key.
459 * The splitting operation produces two trees, a `left tree'
460 * containing every node whose key is less than @key@, and a
461 * `right tree' containing every node whose key is greater than
462 * @key@. If a node matching the @key@ exists in the input
463 * tree, then that becomes the `middle node', which does not
464 * appear in either tree, and is returned separately.
467 extern void *rbtree_splitat(struct bstree_nodecls */*cls*/,
468 struct bstnode **/*left_out*/, int */*lht_out*/,
470 struct bstnode **/*right_out*/, int */*rht_out*/,
471 struct bstnode **/*root*/, const void */*key*/);
473 /* --- @rbtree_splitroot@ --- *
475 * Arguments: @struct bstnode *left_out@ = where to leave the root of the
476 * resulting left tree
477 * @int *lht_out@ = where to leave the black-height of the left
478 * tree, or null to discard this information
479 * @int *mht_out@ = where to leave the black-height of the
480 * middle node (either zero or one), or null to discard
482 * @struct bstnode *right_out@ = where to leave the root of the
483 * resulting right tree
484 * @int *rht_out@ = where to leave the black-height of the right
485 * tree, or null to discard this information
486 * @struct bstnode **root@ = tree root node, or null
487 * @int blkht@ = black-height of the tree, or %$-1$% if unknown
489 * Returns: A pointer to the resulting middle node, or null.
491 * Use: Split a tree into two at its root.
493 * The splitting operation produces two trees, a `left tree'
494 * containing every node preceding the root, and a `right
495 * tree' containing every node following the root, together with
496 * the root. If the root is null, then the left and right trees
500 extern void *rbtree_splitroot(struct bstnode **/*left_out*/,
503 struct bstnode **/*right_out*/,
505 struct bstnode **/*root*/, int /*blkht*/);
507 /* --- @rbtree_unisect@ --- *
509 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
510 * @struct bstnode **uni_out@ = where to write the union root
511 * @int *uniht_out@ = where to put the union height (or null)
512 * @struct bstnode **isect_out@ = where to write the
514 * @int *isectht_out@ = where to put the intersection height (or
516 * @struct bstnode *a@ = pointer to first operand root node
517 * @int aht@ = first operand height, or %$-1$%
518 * @struct bstnode *b@ = pointer to second operand root node
519 * @int bht@ = second operand height, or %$-1$%
523 * Use: Compute the union and intersection of the two operand trees.
525 * The original trees are destroyed. Each node in the original
526 * operands trees ends up in exactly one of the result trees.
529 extern void rbtree_unisect(struct bstree_nodecls */*cls*/,
530 struct bstnode **/*uni_out*/,
532 struct bstnode **/*isect_out*/,
533 int */*isectht_out*/,
534 struct bstnode **/*aroot*/, int /*aht*/,
535 struct bstnode **/*broot*/, int /*bht*/);
537 /* --- @rbtree_diffsect@ --- *
539 * Arguments: @struct bstree_nodecls *cls@ = node class for the tree
540 * @struct bstnode **diff_out@ = where to write the difference
542 * @int *diffht_out@ = where to put the difference height (or
544 * @struct bstnode **isect_out@ = where to write the
546 * @int *isectht_out@ = where to put the intersection height (or
548 * @struct bstnode *a@ = pointer to first operand root node
549 * @int aht@ = first operand height, or %$-1$%
550 * @struct bstnode *b@ = pointer to second operand root node
554 * Use: Compute the difference -- i.e., those nodes in %$a$% without
555 * matching nodes in %$b$% -- and intersection of the two
558 * The original tree %$a$% is destroyed. Each node in the
559 * original operands tree ends up in exactly one of the result
560 * trees. The input tree %$b$% is unchanged.
563 extern void rbtree_diffsect(struct bstree_nodecls */*cls*/,
564 struct bstnode **/*diff_out*/, int */*diffht_out*/,
565 struct bstnode **/*isect_out*/,
566 int */*isectht_out*/,
567 struct bstnode **/*aroot*/, int /*aht*/,
568 struct bstnode **/*broot*/);