1 .\" $OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $
3 .\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in the
13 .\" documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\" must display the following acknowledgement:
16 .\" This product includes software developed by Niels Provos.
17 .\" 4. The name of the author may not be used to endorse or promote products
18 .\" derived from this software without specific prior written permission.
20 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 .Nm SPLAY_INITIALIZER ,
55 .Nm RB_PROTOTYPE_STATIC ,
57 .Nm RB_GENERATE_STATIC ,
74 .Nm RB_FOREACH_REVERSE ,
75 .Nm RB_FOREACH_REVERSE_SAFE ,
79 .Nd "implementations of splay and red-black trees"
82 .Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP
83 .Fn SPLAY_GENERATE NAME TYPE FIELD CMP
85 .Fn SPLAY_HEAD HEADNAME TYPE
87 .Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
88 .Fn SPLAY_ROOT "SPLAY_HEAD *head"
90 .Fn SPLAY_EMPTY "SPLAY_HEAD *head"
92 .Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
94 .Fn SPLAY_MIN NAME "SPLAY_HEAD *head"
96 .Fn SPLAY_MAX NAME "SPLAY_HEAD *head"
98 .Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm"
100 .Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
102 .Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
103 .Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head"
105 .Fn SPLAY_INIT "SPLAY_HEAD *head"
107 .Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
109 .Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
110 .Fn RB_PROTOTYPE NAME TYPE FIELD CMP
111 .Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
112 .Fn RB_GENERATE NAME TYPE FIELD CMP
113 .Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
115 .Fn RB_HEAD HEADNAME TYPE
116 .Fn RB_INITIALIZER "RB_HEAD *head"
118 .Fn RB_ROOT "RB_HEAD *head"
120 .Fn RB_EMPTY "RB_HEAD *head"
122 .Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm"
124 .Fn RB_PREV NAME "RB_HEAD *head" "struct TYPE *elm"
126 .Fn RB_MIN NAME "RB_HEAD *head"
128 .Fn RB_MAX NAME "RB_HEAD *head"
130 .Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm"
132 .Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm"
134 .Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
136 .Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
138 .Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
139 .Fn RB_FOREACH VARNAME NAME "RB_HEAD *head"
140 .Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
141 .Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head"
142 .Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
144 .Fn RB_INIT "RB_HEAD *head"
146 .Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm"
148 .Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm"
150 These macros define data structures for different types of trees:
151 splay trees and red-black trees.
153 In the macro definitions,
155 is the name tag of a user defined structure that must contain a field of type
163 is the name tag of a user defined structure that must be declared
170 has to be a unique name prefix for every tree that is defined.
172 The function prototypes are declared with
173 .Fn SPLAY_PROTOTYPE ,
176 .Fn RB_PROTOTYPE_STATIC .
177 The function bodies are generated with
181 .Fn RB_GENERATE_STATIC .
182 See the examples below for further explanation of how these macros are used.
184 A splay tree is a self-organizing data structure.
185 Every operation on the tree causes a splay to happen.
186 The splay moves the requested
187 node to the root of the tree and partly rebalances it.
189 This has the benefit that request locality causes faster lookups as
190 the requested nodes move to the top of the tree.
191 On the other hand, every lookup causes memory writes.
193 The Balance Theorem bounds the total access time for
197 inserts on an initially empty tree as
198 .Fn O "\*[lp]m + n\*[rp]lg n" .
200 amortized cost for a sequence of
202 accesses to a splay tree is
205 A splay tree is headed by a structure defined by the
209 structure is declared as follows:
210 .Bd -ragged -offset indent
211 .Fn SPLAY_HEAD HEADNAME TYPE
217 is the name of the structure to be defined, and struct
219 is the type of the elements to be inserted into the tree.
223 macro declares a structure that allows elements to be connected in the tree.
225 In order to use the functions that manipulate the tree structure,
226 their prototypes need to be declared with the
231 is a unique identifier for this particular tree.
234 argument is the type of the structure that is being managed
238 argument is the name of the element defined by
241 The function bodies are generated with the
244 It takes the same arguments as the
246 macro, but should be used only once.
251 argument is the name of a function used to compare tree nodes
253 The function takes two arguments of type
254 .Vt "struct TYPE *" .
255 If the first argument is smaller than the second, the function returns a
256 value smaller than zero.
257 If they are equal, the function returns zero.
258 Otherwise, it should return a value greater than zero.
260 function defines the order of the tree elements.
264 macro initializes the tree referenced by
267 The splay tree can also be initialized statically by using the
268 .Fn SPLAY_INITIALIZER
270 .Bd -ragged -offset indent
271 .Fn SPLAY_HEAD HEADNAME TYPE
274 .Fn SPLAY_INITIALIZER &head ;
279 macro inserts the new element
285 macro removes the element
287 from the tree pointed by
292 macro can be used to find a particular element in the tree.
293 .Bd -literal -offset indent
294 struct TYPE find, *res;
296 res = SPLAY_FIND(NAME, head, &find);
305 macros can be used to traverse the tree:
306 .Bd -literal -offset indent
307 for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
310 Or, for simplicity, one can use the
313 .Bd -ragged -offset indent
314 .Fn SPLAY_FOREACH np NAME head
319 macro should be used to check whether a splay tree is empty.
321 A red-black tree is a binary search tree with the node color as an
323 It fulfills a set of conditions:
324 .Bl -enum -offset indent
326 Every search path from the root to a leaf consists of the same number of
329 Each red node (except for the root) has a black parent.
331 Each leaf node is black.
334 Every operation on a red-black tree is bounded as
336 The maximum height of a red-black tree is
339 A red-black tree is headed by a structure defined by the
343 structure is declared as follows:
344 .Bd -ragged -offset indent
345 .Fn RB_HEAD HEADNAME TYPE
351 is the name of the structure to be defined, and struct
353 is the type of the elements to be inserted into the tree.
357 macro declares a structure that allows elements to be connected in the tree.
359 In order to use the functions that manipulate the tree structure,
360 their prototypes need to be declared with the
363 .Fn RB_PROTOTYPE_STATIC
367 is a unique identifier for this particular tree.
370 argument is the type of the structure that is being managed
374 argument is the name of the element defined by
377 The function bodies are generated with the
380 .Fn RB_GENERATE_STATIC
382 These macros take the same arguments as the
385 .Fn RB_PROTOTYPE_STATIC
386 macros, but should be used only once.
391 argument is the name of a function used to compare tree nodes
393 The function takes two arguments of type
394 .Vt "struct TYPE *" .
395 If the first argument is smaller than the second, the function returns a
396 value smaller than zero.
397 If they are equal, the function returns zero.
398 Otherwise, it should return a value greater than zero.
400 function defines the order of the tree elements.
404 macro initializes the tree referenced by
407 The red-black tree can also be initialized statically by using the
410 .Bd -ragged -offset indent
411 .Fn RB_HEAD HEADNAME TYPE
414 .Fn RB_INITIALIZER &head ;
419 macro inserts the new element
425 macro removes the element
427 from the tree pointed by
434 macros can be used to find a particular element in the tree.
435 .Bd -literal -offset indent
436 struct TYPE find, *res;
438 res = RB_FIND(NAME, head, &find);
448 macros can be used to traverse the tree:
450 .Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))"
452 Or, for simplicity, one can use the
455 .Fn RB_FOREACH_REVERSE
457 .Bd -ragged -offset indent
458 .Fn RB_FOREACH np NAME head
464 .Fn RB_FOREACH_REVERSE_SAFE
465 traverse the tree referenced by head
466 in a forward or reverse direction respectively,
467 assigning each element in turn to np.
468 However, unlike their unsafe counterparts,
469 they permit both the removal of np
470 as well as freeing it from within the loop safely
471 without interfering with the traversal.
475 macro should be used to check whether a red-black tree is empty.
477 Trying to free a tree in the following way is a common error:
478 .Bd -literal -offset indent
479 SPLAY_FOREACH(var, NAME, head) {
480 SPLAY_REMOVE(NAME, head, var);
490 macro refers to a pointer that may have been reallocated already.
491 Proper code needs a second variable.
492 .Bd -literal -offset indent
493 for (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
494 nxt = SPLAY_NEXT(NAME, head, var);
495 SPLAY_REMOVE(NAME, head, var);
506 if the element was inserted in the tree successfully, otherwise they
507 return a pointer to the element with the colliding key.
513 return the pointer to the removed element otherwise they return
515 to indicate an error.
519 The author of the tree macros is