xref: /dflybsd-src/share/man/man3/tree.3 (revision 37149c60342ce21064029fedf00ed32f4cce006b)
1d19613acSJoerg Sonnenberger.\"	$NetBSD: tree.3,v 1.3 2004/04/14 11:05:19 pooka Exp $
2d19613acSJoerg Sonnenberger.\"	$OpenBSD: tree.3,v 1.9 2003/05/20 09:13:38 jmc Exp $
3d19613acSJoerg Sonnenberger.\"/*
4d19613acSJoerg Sonnenberger.\" * Copyright 2002 Niels Provos <provos@citi.umich.edu>
5d19613acSJoerg Sonnenberger.\" * All rights reserved.
6d19613acSJoerg Sonnenberger.\" *
7d19613acSJoerg Sonnenberger.\" * Redistribution and use in source and binary forms, with or without
8d19613acSJoerg Sonnenberger.\" * modification, are permitted provided that the following conditions
9d19613acSJoerg Sonnenberger.\" * are met:
10d19613acSJoerg Sonnenberger.\" * 1. Redistributions of source code must retain the above copyright
11d19613acSJoerg Sonnenberger.\" *    notice, this list of conditions and the following disclaimer.
12d19613acSJoerg Sonnenberger.\" * 2. Redistributions in binary form must reproduce the above copyright
13d19613acSJoerg Sonnenberger.\" *    notice, this list of conditions and the following disclaimer in the
14d19613acSJoerg Sonnenberger.\" *    documentation and/or other materials provided with the distribution.
15d19613acSJoerg Sonnenberger.\" * 3. All advertising materials mentioning features or use of this software
16d19613acSJoerg Sonnenberger.\" *    must display the following acknowledgement:
17d19613acSJoerg Sonnenberger.\" *      This product includes software developed by Niels Provos.
18d19613acSJoerg Sonnenberger.\" * 4. The name of the author may not be used to endorse or promote products
19d19613acSJoerg Sonnenberger.\" *    derived from this software without specific prior written permission.
20d19613acSJoerg Sonnenberger.\" *
21d19613acSJoerg Sonnenberger.\" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22d19613acSJoerg Sonnenberger.\" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23d19613acSJoerg Sonnenberger.\" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24d19613acSJoerg Sonnenberger.\" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25d19613acSJoerg Sonnenberger.\" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26d19613acSJoerg Sonnenberger.\" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27d19613acSJoerg Sonnenberger.\" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28d19613acSJoerg Sonnenberger.\" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29d19613acSJoerg Sonnenberger.\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30d19613acSJoerg Sonnenberger.\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31d19613acSJoerg Sonnenberger.\" */
32*37149c60SSascha Wildner.Dd August 9, 2015
33d19613acSJoerg Sonnenberger.Dt TREE 3
34d19613acSJoerg Sonnenberger.Os
35d19613acSJoerg Sonnenberger.Sh NAME
36d19613acSJoerg Sonnenberger.Nm SPLAY_PROTOTYPE ,
37d19613acSJoerg Sonnenberger.Nm SPLAY_GENERATE ,
38d19613acSJoerg Sonnenberger.Nm SPLAY_ENTRY ,
39d19613acSJoerg Sonnenberger.Nm SPLAY_HEAD ,
40d19613acSJoerg Sonnenberger.Nm SPLAY_INITIALIZER ,
41d19613acSJoerg Sonnenberger.Nm SPLAY_ROOT ,
42d19613acSJoerg Sonnenberger.Nm SPLAY_EMPTY ,
43d19613acSJoerg Sonnenberger.Nm SPLAY_NEXT ,
44d19613acSJoerg Sonnenberger.Nm SPLAY_MIN ,
45d19613acSJoerg Sonnenberger.Nm SPLAY_MAX ,
46d19613acSJoerg Sonnenberger.Nm SPLAY_FIND ,
47d19613acSJoerg Sonnenberger.Nm SPLAY_LEFT ,
48d19613acSJoerg Sonnenberger.Nm SPLAY_RIGHT ,
49d19613acSJoerg Sonnenberger.Nm SPLAY_FOREACH ,
50d19613acSJoerg Sonnenberger.Nm SPLAY_INIT ,
51d19613acSJoerg Sonnenberger.Nm SPLAY_INSERT ,
52d19613acSJoerg Sonnenberger.Nm SPLAY_REMOVE ,
53d19613acSJoerg Sonnenberger.Nm RB_PROTOTYPE ,
54d19613acSJoerg Sonnenberger.Nm RB_GENERATE ,
55d19613acSJoerg Sonnenberger.Nm RB_ENTRY ,
56d19613acSJoerg Sonnenberger.Nm RB_HEAD ,
57d19613acSJoerg Sonnenberger.Nm RB_INITIALIZER ,
58d19613acSJoerg Sonnenberger.Nm RB_ROOT ,
59d19613acSJoerg Sonnenberger.Nm RB_EMPTY ,
60d19613acSJoerg Sonnenberger.Nm RB_NEXT ,
61d19613acSJoerg Sonnenberger.Nm RB_MIN ,
62d19613acSJoerg Sonnenberger.Nm RB_MAX ,
63d19613acSJoerg Sonnenberger.Nm RB_FIND ,
64d19613acSJoerg Sonnenberger.Nm RB_LEFT ,
65d19613acSJoerg Sonnenberger.Nm RB_RIGHT ,
66d19613acSJoerg Sonnenberger.Nm RB_PARENT ,
67d19613acSJoerg Sonnenberger.Nm RB_FOREACH ,
68*37149c60SSascha Wildner.Nm RB_FOREACH_FROM ,
69*37149c60SSascha Wildner.Nm RB_FOREACH_SAFE ,
70*37149c60SSascha Wildner.Nm RB_FOREACH_REVERSE ,
71*37149c60SSascha Wildner.Nm RB_FOREACH_REVERSE_FROM ,
72*37149c60SSascha Wildner.Nm RB_FOREACH_REVERSE_SAFE ,
73d19613acSJoerg Sonnenberger.Nm RB_INIT ,
74d19613acSJoerg Sonnenberger.Nm RB_INSERT ,
75d19613acSJoerg Sonnenberger.Nm RB_REMOVE
76d19613acSJoerg Sonnenberger.Nd implementations of splay and red-black trees
77d19613acSJoerg Sonnenberger.Sh SYNOPSIS
78d19613acSJoerg Sonnenberger.In sys/tree.h
79d19613acSJoerg Sonnenberger.Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
80d19613acSJoerg Sonnenberger.Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP"
81d19613acSJoerg Sonnenberger.Fn SPLAY_ENTRY "TYPE"
82d19613acSJoerg Sonnenberger.Fn SPLAY_HEAD "HEADNAME" "TYPE"
83d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
84d19613acSJoerg Sonnenberger.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
85d19613acSJoerg Sonnenberger.Fn SPLAY_ROOT "SPLAY_HEAD *head"
86d19613acSJoerg Sonnenberger.Ft "bool"
87d19613acSJoerg Sonnenberger.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
88d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
89d19613acSJoerg Sonnenberger.Fn SPLAY_NEXT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
90d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
91d19613acSJoerg Sonnenberger.Fn SPLAY_MIN "NAME" "SPLAY_HEAD *head"
92d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
93d19613acSJoerg Sonnenberger.Fn SPLAY_MAX "NAME" "SPLAY_HEAD *head"
94d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
95d19613acSJoerg Sonnenberger.Fn SPLAY_FIND "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
96d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
97d19613acSJoerg Sonnenberger.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
98d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
99d19613acSJoerg Sonnenberger.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
100d19613acSJoerg Sonnenberger.Fn SPLAY_FOREACH "VARNAME" "NAME" "SPLAY_HEAD *head"
101d19613acSJoerg Sonnenberger.Ft void
102d19613acSJoerg Sonnenberger.Fn SPLAY_INIT "SPLAY_HEAD *head"
103d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
104d19613acSJoerg Sonnenberger.Fn SPLAY_INSERT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
105d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
106d19613acSJoerg Sonnenberger.Fn SPLAY_REMOVE "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
107d19613acSJoerg Sonnenberger.Pp
108d19613acSJoerg Sonnenberger.Fn RB_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
109d19613acSJoerg Sonnenberger.Fn RB_GENERATE "NAME" "TYPE" "FIELD" "CMP"
110d19613acSJoerg Sonnenberger.Fn RB_ENTRY "TYPE"
111d19613acSJoerg Sonnenberger.Fn RB_HEAD "HEADNAME" "TYPE"
112d19613acSJoerg Sonnenberger.Fn RB_INITIALIZER "RB_HEAD *head"
113d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
114d19613acSJoerg Sonnenberger.Fn RB_ROOT "RB_HEAD *head"
115d19613acSJoerg Sonnenberger.Ft "bool"
116d19613acSJoerg Sonnenberger.Fn RB_EMPTY "RB_HEAD *head"
117d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
118d19613acSJoerg Sonnenberger.Fn RB_NEXT "NAME" "RB_HEAD *head" "struct TYPE *elm"
119d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
120d19613acSJoerg Sonnenberger.Fn RB_MIN "NAME" "RB_HEAD *head"
121d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
122d19613acSJoerg Sonnenberger.Fn RB_MAX "NAME" "RB_HEAD *head"
123d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
124d19613acSJoerg Sonnenberger.Fn RB_FIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
125d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
126d19613acSJoerg Sonnenberger.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
127d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
128d19613acSJoerg Sonnenberger.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
129d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
130d19613acSJoerg Sonnenberger.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
131d19613acSJoerg Sonnenberger.Fn RB_FOREACH "VARNAME" "NAME" "RB_HEAD *head"
132*37149c60SSascha Wildner.Fn RB_FOREACH_FROM "VARNAME" "NAME" "POS_VARNAME"
133*37149c60SSascha Wildner.Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
134*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head"
135*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE_FROM "VARNAME" "NAME" "POS_VARNAME"
136*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
137d19613acSJoerg Sonnenberger.Ft void
138d19613acSJoerg Sonnenberger.Fn RB_INIT "RB_HEAD *head"
139d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
140d19613acSJoerg Sonnenberger.Fn RB_INSERT "NAME" "RB_HEAD *head" "struct TYPE *elm"
141d19613acSJoerg Sonnenberger.Ft "struct TYPE *"
142d19613acSJoerg Sonnenberger.Fn RB_REMOVE "NAME" "RB_HEAD *head" "struct TYPE *elm"
143d19613acSJoerg Sonnenberger.Sh DESCRIPTION
144d19613acSJoerg SonnenbergerThese macros define data structures for different types of trees:
145d19613acSJoerg Sonnenbergersplay trees and red-black trees.
146d19613acSJoerg Sonnenberger.Pp
147d19613acSJoerg SonnenbergerIn the macro definitions,
148d19613acSJoerg Sonnenberger.Fa TYPE
149d19613acSJoerg Sonnenbergeris the name tag of a user defined structure that must contain a field of type
150d19613acSJoerg Sonnenberger.Li SPLAY_ENTRY ,
151d19613acSJoerg Sonnenbergeror
152d19613acSJoerg Sonnenberger.Li RB_ENTRY ,
153d19613acSJoerg Sonnenbergernamed
154d19613acSJoerg Sonnenberger.Fa ENTRYNAME .
155d19613acSJoerg SonnenbergerThe argument
156d19613acSJoerg Sonnenberger.Fa HEADNAME
157d19613acSJoerg Sonnenbergeris the name tag of a user defined structure that must be declared
158d19613acSJoerg Sonnenbergerusing the macros
159d19613acSJoerg Sonnenberger.Fn SPLAY_HEAD
160d19613acSJoerg Sonnenbergeror
161d19613acSJoerg Sonnenberger.Fn RB_HEAD .
162d19613acSJoerg SonnenbergerThe argument
163d19613acSJoerg Sonnenberger.Fa NAME
164d19613acSJoerg Sonnenbergerhas to be a unique name prefix for every tree that is defined.
165d19613acSJoerg Sonnenberger.Pp
166d19613acSJoerg SonnenbergerThe function prototypes are declared with either
167d19613acSJoerg Sonnenberger.Li SPLAY_PROTOTYPE
168d19613acSJoerg Sonnenbergeror
169d19613acSJoerg Sonnenberger.Li RB_PROTOTYPE .
170d19613acSJoerg SonnenbergerThe function bodies are generated with either
171d19613acSJoerg Sonnenberger.Li SPLAY_GENERATE
172d19613acSJoerg Sonnenbergeror
173d19613acSJoerg Sonnenberger.Li RB_GENERATE .
174d19613acSJoerg SonnenbergerSee the examples below for further explanation of how these macros are used.
175d19613acSJoerg Sonnenberger.Sh SPLAY TREES
176d19613acSJoerg SonnenbergerA splay tree is a self-organizing data structure.
177d19613acSJoerg SonnenbergerEvery operation on the tree causes a splay to happen.
178d19613acSJoerg SonnenbergerThe splay moves the requested node to the root of the tree and partly
179d19613acSJoerg Sonnenbergerrebalances it.
180d19613acSJoerg Sonnenberger.Pp
181d19613acSJoerg SonnenbergerThis has the benefit that request locality causes faster lookups as
182d19613acSJoerg Sonnenbergerthe requested nodes move to the top of the tree.
183d19613acSJoerg SonnenbergerOn the other hand, every lookup causes memory writes.
184d19613acSJoerg Sonnenberger.Pp
185d19613acSJoerg SonnenbergerThe Balance Theorem bounds the total access time for m operations
186d19613acSJoerg Sonnenbergerand n inserts on an initially empty tree as O((m + n)lg n).
187d19613acSJoerg SonnenbergerThe amortized cost for a sequence of m accesses to a splay tree is O(lg n).
188d19613acSJoerg Sonnenberger.Pp
189d19613acSJoerg SonnenbergerA splay tree is headed by a structure defined by the
190d19613acSJoerg Sonnenberger.Fn SPLAY_HEAD
191d19613acSJoerg Sonnenbergermacro.
192d19613acSJoerg SonnenbergerA
193d19613acSJoerg Sonnenberger.Fa SPLAY_HEAD
194d19613acSJoerg Sonnenbergerstructure is declared as follows:
195d19613acSJoerg Sonnenberger.Bd -literal -offset indent
196d19613acSJoerg SonnenbergerSPLAY_HEAD(HEADNAME, TYPE) head;
197d19613acSJoerg Sonnenberger.Ed
198d19613acSJoerg Sonnenberger.Pp
199d19613acSJoerg Sonnenbergerwhere
200d19613acSJoerg Sonnenberger.Fa HEADNAME
201d19613acSJoerg Sonnenbergeris the name of the structure to be defined, and struct
202d19613acSJoerg Sonnenberger.Fa TYPE
203d19613acSJoerg Sonnenbergeris the type of the elements to be inserted into the tree.
204d19613acSJoerg Sonnenberger.Pp
205d19613acSJoerg SonnenbergerThe
206d19613acSJoerg Sonnenberger.Fn SPLAY_ENTRY
207d19613acSJoerg Sonnenbergermacro declares a structure that allows elements to be connected in the tree.
208d19613acSJoerg Sonnenberger.Pp
209d19613acSJoerg SonnenbergerIn order to use the functions that manipulate the tree structure,
210d19613acSJoerg Sonnenbergertheir prototypes need to be declared with the
211d19613acSJoerg Sonnenberger.Fn SPLAY_PROTOTYPE
212d19613acSJoerg Sonnenbergermacro,
213d19613acSJoerg Sonnenbergerwhere
214d19613acSJoerg Sonnenberger.Fa NAME
215d19613acSJoerg Sonnenbergeris a unique identifier for this particular tree.
216d19613acSJoerg SonnenbergerThe
217d19613acSJoerg Sonnenberger.Fa TYPE
218d19613acSJoerg Sonnenbergerargument is the type of the structure that is being managed
219d19613acSJoerg Sonnenbergerby the tree.
220d19613acSJoerg SonnenbergerThe
221d19613acSJoerg Sonnenberger.Fa FIELD
222d19613acSJoerg Sonnenbergerargument is the name of the element defined by
223d19613acSJoerg Sonnenberger.Fn SPLAY_ENTRY .
224d19613acSJoerg Sonnenberger.Pp
225d19613acSJoerg SonnenbergerThe function bodies are generated with the
226d19613acSJoerg Sonnenberger.Fn SPLAY_GENERATE
227d19613acSJoerg Sonnenbergermacro.
228d19613acSJoerg SonnenbergerIt takes the same arguments as the
229d19613acSJoerg Sonnenberger.Fn SPLAY_PROTOTYPE
230d19613acSJoerg Sonnenbergermacro, but should be used only once.
231d19613acSJoerg Sonnenberger.Pp
232d19613acSJoerg SonnenbergerFinally,
233d19613acSJoerg Sonnenbergerthe
234d19613acSJoerg Sonnenberger.Fa CMP
235d19613acSJoerg Sonnenbergerargument is the name of a function used to compare trees noded
236d19613acSJoerg Sonnenbergerwith each other.
237d19613acSJoerg SonnenbergerThe function takes two arguments of type
238d19613acSJoerg Sonnenberger.Fa "struct TYPE *" .
239d19613acSJoerg SonnenbergerIf the first argument is smaller than the second, the function returns a
240d19613acSJoerg Sonnenbergervalue smaller than zero.
241d19613acSJoerg SonnenbergerIf they are equal, the function returns zero.
242d19613acSJoerg SonnenbergerOtherwise, it should return a value greater than zero.
243d19613acSJoerg SonnenbergerThe compare function defines the order of the tree elements.
244d19613acSJoerg Sonnenberger.Pp
245d19613acSJoerg SonnenbergerThe
246d19613acSJoerg Sonnenberger.Fn SPLAY_INIT
247d19613acSJoerg Sonnenbergermacro initializes the tree referenced by
248d19613acSJoerg Sonnenberger.Fa head .
249d19613acSJoerg Sonnenberger.Pp
250d19613acSJoerg SonnenbergerThe splay tree can also be initialized statically by using the
251d19613acSJoerg Sonnenberger.Fn SPLAY_INITIALIZER
252d19613acSJoerg Sonnenbergermacro like this:
253d19613acSJoerg Sonnenberger.Bd -literal -offset indent
254d19613acSJoerg SonnenbergerSPLAY_HEAD(HEADNAME, TYPE) head = SPLAY_INITIALIZER(\*[Am]head);
255d19613acSJoerg Sonnenberger.Ed
256d19613acSJoerg Sonnenberger.Pp
257d19613acSJoerg SonnenbergerThe
258d19613acSJoerg Sonnenberger.Fn SPLAY_INSERT
259d19613acSJoerg Sonnenbergermacro inserts the new element
260d19613acSJoerg Sonnenberger.Fa elm
261d19613acSJoerg Sonnenbergerinto the tree.
262d19613acSJoerg Sonnenberger.Pp
263d19613acSJoerg SonnenbergerThe
264d19613acSJoerg Sonnenberger.Fn SPLAY_REMOVE
265d19613acSJoerg Sonnenbergermacro removes the element
266d19613acSJoerg Sonnenberger.Fa elm
267d19613acSJoerg Sonnenbergerfrom the tree pointed by
268d19613acSJoerg Sonnenberger.Fa head .
269d19613acSJoerg Sonnenberger.Pp
270d19613acSJoerg SonnenbergerThe
271d19613acSJoerg Sonnenberger.Fn SPLAY_FIND
272d19613acSJoerg Sonnenbergermacro can be used to find a particular element in the tree.
273d19613acSJoerg Sonnenberger.Bd -literal -offset indent
274d19613acSJoerg Sonnenbergerstruct TYPE find, *res;
275d19613acSJoerg Sonnenbergerfind.key = 30;
276d19613acSJoerg Sonnenbergerres = SPLAY_FIND(NAME, head, \*[Am]find);
277d19613acSJoerg Sonnenberger.Ed
278d19613acSJoerg Sonnenberger.Pp
279d19613acSJoerg SonnenbergerThe
280d19613acSJoerg Sonnenberger.Fn SPLAY_ROOT ,
281d19613acSJoerg Sonnenberger.Fn SPLAY_MIN ,
282d19613acSJoerg Sonnenberger.Fn SPLAY_MAX ,
283d19613acSJoerg Sonnenbergerand
284d19613acSJoerg Sonnenberger.Fn SPLAY_NEXT
285d19613acSJoerg Sonnenbergermacros can be used to traverse the tree:
286d19613acSJoerg Sonnenberger.Bd -literal -offset indent
287d19613acSJoerg Sonnenbergerfor (np = SPLAY_MIN(NAME, \*[Am]head); np != NULL; np = SPLAY_NEXT(NAME, \*[Am]head, np))
288d19613acSJoerg Sonnenberger.Ed
289d19613acSJoerg Sonnenberger.Pp
290d19613acSJoerg SonnenbergerOr, for simplicity, one can use the
291d19613acSJoerg Sonnenberger.Fn SPLAY_FOREACH
292d19613acSJoerg Sonnenbergermacro:
293d19613acSJoerg Sonnenberger.Bd -literal -offset indent
294d19613acSJoerg SonnenbergerSPLAY_FOREACH(np, NAME, head)
295d19613acSJoerg Sonnenberger.Ed
296d19613acSJoerg Sonnenberger.Pp
297d19613acSJoerg SonnenbergerThe
298d19613acSJoerg Sonnenberger.Fn SPLAY_EMPTY
299d19613acSJoerg Sonnenbergermacro should be used to check whether a splay tree is empty.
300d19613acSJoerg Sonnenberger.Sh RED-BLACK TREES
301d19613acSJoerg SonnenbergerA red-black tree is a binary search tree with the node color as an
302d19613acSJoerg Sonnenbergerextra attribute.
303d19613acSJoerg SonnenbergerIt fulfills a set of conditions:
304d19613acSJoerg Sonnenberger.Bl -enum -compact -offset indent
305d19613acSJoerg Sonnenberger.It
306d19613acSJoerg Sonnenbergerevery search path from the root to a leaf consists of the same number of
307d19613acSJoerg Sonnenbergerblack nodes,
308d19613acSJoerg Sonnenberger.It
309d19613acSJoerg Sonnenbergereach red node (except for the root) has a black parent,
310d19613acSJoerg Sonnenberger.It
311d19613acSJoerg Sonnenbergereach leaf node is black.
312d19613acSJoerg Sonnenberger.El
313d19613acSJoerg Sonnenberger.Pp
314d19613acSJoerg SonnenbergerEvery operation on a red-black tree is bounded as O(lg n).
315d19613acSJoerg SonnenbergerThe maximum height of a red-black tree is 2lg (n+1).
316d19613acSJoerg Sonnenberger.Pp
317d19613acSJoerg SonnenbergerA red-black tree is headed by a structure defined by the
318d19613acSJoerg Sonnenberger.Fn RB_HEAD
319d19613acSJoerg Sonnenbergermacro.
320d19613acSJoerg SonnenbergerA
321d19613acSJoerg Sonnenberger.Fa RB_HEAD
322d19613acSJoerg Sonnenbergerstructure is declared as follows:
323d19613acSJoerg Sonnenberger.Bd -literal -offset indent
324d19613acSJoerg SonnenbergerRB_HEAD(HEADNAME, TYPE) head;
325d19613acSJoerg Sonnenberger.Ed
326d19613acSJoerg Sonnenberger.Pp
327d19613acSJoerg Sonnenbergerwhere
328d19613acSJoerg Sonnenberger.Fa HEADNAME
329d19613acSJoerg Sonnenbergeris the name of the structure to be defined, and struct
330d19613acSJoerg Sonnenberger.Fa TYPE
331d19613acSJoerg Sonnenbergeris the type of the elements to be inserted into the tree.
332d19613acSJoerg Sonnenberger.Pp
333d19613acSJoerg SonnenbergerThe
334d19613acSJoerg Sonnenberger.Fn RB_ENTRY
335d19613acSJoerg Sonnenbergermacro declares a structure that allows elements to be connected in the tree.
336d19613acSJoerg Sonnenberger.Pp
337d19613acSJoerg SonnenbergerIn order to use the functions that manipulate the tree structure,
338d19613acSJoerg Sonnenbergertheir prototypes need to be declared with the
339d19613acSJoerg Sonnenberger.Fn RB_PROTOTYPE
340d19613acSJoerg Sonnenbergermacro,
341d19613acSJoerg Sonnenbergerwhere
342d19613acSJoerg Sonnenberger.Fa NAME
343d19613acSJoerg Sonnenbergeris a unique identifier for this particular tree.
344d19613acSJoerg SonnenbergerThe
345d19613acSJoerg Sonnenberger.Fa TYPE
346d19613acSJoerg Sonnenbergerargument is the type of the structure that is being managed
347d19613acSJoerg Sonnenbergerby the tree.
348d19613acSJoerg SonnenbergerThe
349d19613acSJoerg Sonnenberger.Fa FIELD
350d19613acSJoerg Sonnenbergerargument is the name of the element defined by
351d19613acSJoerg Sonnenberger.Fn RB_ENTRY .
352d19613acSJoerg Sonnenberger.Pp
353d19613acSJoerg SonnenbergerThe function bodies are generated with the
354d19613acSJoerg Sonnenberger.Fn RB_GENERATE
355d19613acSJoerg Sonnenbergermacro.
356d19613acSJoerg SonnenbergerIt takes the same arguments as the
357d19613acSJoerg Sonnenberger.Fn RB_PROTOTYPE
358d19613acSJoerg Sonnenbergermacro, but should be used only once.
359d19613acSJoerg Sonnenberger.Pp
360d19613acSJoerg SonnenbergerFinally,
361d19613acSJoerg Sonnenbergerthe
362d19613acSJoerg Sonnenberger.Fa CMP
363d19613acSJoerg Sonnenbergerargument is the name of a function used to compare trees noded
364d19613acSJoerg Sonnenbergerwith each other.
365d19613acSJoerg SonnenbergerThe function takes two arguments of type
366d19613acSJoerg Sonnenberger.Fa "struct TYPE *" .
367d19613acSJoerg SonnenbergerIf the first argument is smaller than the second, the function returns a
368d19613acSJoerg Sonnenbergervalue smaller than zero.
369d19613acSJoerg SonnenbergerIf they are equal, the function returns zero.
370d19613acSJoerg SonnenbergerOtherwise, it should return a value greater than zero.
371d19613acSJoerg SonnenbergerThe compare function defines the order of the tree elements.
372d19613acSJoerg Sonnenberger.Pp
373d19613acSJoerg SonnenbergerThe
374d19613acSJoerg Sonnenberger.Fn RB_INIT
375d19613acSJoerg Sonnenbergermacro initializes the tree referenced by
376d19613acSJoerg Sonnenberger.Fa head .
377d19613acSJoerg Sonnenberger.Pp
378d19613acSJoerg SonnenbergerThe redblack tree can also be initialized statically by using the
379d19613acSJoerg Sonnenberger.Fn RB_INITIALIZER
380d19613acSJoerg Sonnenbergermacro like this:
381d19613acSJoerg Sonnenberger.Bd -literal -offset indent
382d19613acSJoerg SonnenbergerRB_HEAD(HEADNAME, TYPE) head = RB_INITIALIZER(\*[Am]head);
383d19613acSJoerg Sonnenberger.Ed
384d19613acSJoerg Sonnenberger.Pp
385d19613acSJoerg SonnenbergerThe
386d19613acSJoerg Sonnenberger.Fn RB_INSERT
387d19613acSJoerg Sonnenbergermacro inserts the new element
388d19613acSJoerg Sonnenberger.Fa elm
389d19613acSJoerg Sonnenbergerinto the tree.
390d19613acSJoerg Sonnenberger.Pp
391d19613acSJoerg SonnenbergerThe
392d19613acSJoerg Sonnenberger.Fn RB_REMOVE
393d19613acSJoerg Sonnenbergermacro removes the element
394d19613acSJoerg Sonnenberger.Fa elm
395d19613acSJoerg Sonnenbergerfrom the tree pointed by
396d19613acSJoerg Sonnenberger.Fa head .
397d19613acSJoerg Sonnenberger.Pp
398d19613acSJoerg SonnenbergerThe
399d19613acSJoerg Sonnenberger.Fn RB_FIND
400d19613acSJoerg Sonnenbergermacro can be used to find a particular element in the tree.
401d19613acSJoerg Sonnenberger.Bd -literal -offset indent
402d19613acSJoerg Sonnenbergerstruct TYPE find, *res;
403d19613acSJoerg Sonnenbergerfind.key = 30;
404d19613acSJoerg Sonnenbergerres = RB_FIND(NAME, head, \*[Am]find);
405d19613acSJoerg Sonnenberger.Ed
406d19613acSJoerg Sonnenberger.Pp
407d19613acSJoerg SonnenbergerThe
408d19613acSJoerg Sonnenberger.Fn RB_ROOT ,
409d19613acSJoerg Sonnenberger.Fn RB_MIN ,
410d19613acSJoerg Sonnenberger.Fn RB_MAX ,
411d19613acSJoerg Sonnenbergerand
412d19613acSJoerg Sonnenberger.Fn RB_NEXT
413d19613acSJoerg Sonnenbergermacros can be used to traverse the tree:
414d19613acSJoerg Sonnenberger.Bd -literal -offset indent
415d19613acSJoerg Sonnenbergerfor (np = RB_MIN(NAME, \*[Am]head); np != NULL; np = RB_NEXT(NAME, \*[Am]head, np))
416d19613acSJoerg Sonnenberger.Ed
417d19613acSJoerg Sonnenberger.Pp
418d19613acSJoerg SonnenbergerOr, for simplicity, one can use the
419d19613acSJoerg Sonnenberger.Fn RB_FOREACH
420*37149c60SSascha Wildneror
421*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE
422d19613acSJoerg Sonnenbergermacro:
423d19613acSJoerg Sonnenberger.Bd -literal -offset indent
424d19613acSJoerg SonnenbergerRB_FOREACH(np, NAME, head)
425d19613acSJoerg Sonnenberger.Ed
426d19613acSJoerg Sonnenberger.Pp
427*37149c60SSascha WildnerThe macros
428*37149c60SSascha Wildner.Fn RB_FOREACH_SAFE
429*37149c60SSascha Wildnerand
430*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE_SAFE
431*37149c60SSascha Wildnertraverse the tree referenced by head
432*37149c60SSascha Wildnerin a forward or reverse direction respectively,
433*37149c60SSascha Wildnerassigning each element in turn to np.
434*37149c60SSascha WildnerHowever, unlike their unsafe counterparts,
435*37149c60SSascha Wildnerthey permit both the removal of np
436*37149c60SSascha Wildneras well as freeing it from within the loop safely
437*37149c60SSascha Wildnerwithout interfering with the traversal.
438*37149c60SSascha Wildner.Pp
439*37149c60SSascha WildnerBoth
440*37149c60SSascha Wildner.Fn RB_FOREACH_FROM
441*37149c60SSascha Wildnerand
442*37149c60SSascha Wildner.Fn RB_FOREACH_REVERSE_FROM
443*37149c60SSascha Wildnermay be used to continue an interrupted traversal
444*37149c60SSascha Wildnerin a forward or reverse direction respectively.
445*37149c60SSascha WildnerThe head pointer is not required.
446*37149c60SSascha WildnerThe pointer to the node from where to resume the traversal
447*37149c60SSascha Wildnershould be passed as their last argument,
448*37149c60SSascha Wildnerand will be overwritten to provide safe traversal.
449*37149c60SSascha Wildner.Pp
450d19613acSJoerg SonnenbergerThe
451d19613acSJoerg Sonnenberger.Fn RB_EMPTY
452d19613acSJoerg Sonnenbergermacro should be used to check whether a red-black tree is empty.
453d19613acSJoerg Sonnenberger.Sh NOTES
454d19613acSJoerg SonnenbergerTrying to free a tree in the following way is a common error:
455d19613acSJoerg Sonnenberger.Bd -literal -offset indent
456d19613acSJoerg SonnenbergerSPLAY_FOREACH(var, NAME, head) {
457d19613acSJoerg Sonnenberger	SPLAY_REMOVE(NAME, head, var);
458d19613acSJoerg Sonnenberger	free(var);
459d19613acSJoerg Sonnenberger}
460d19613acSJoerg Sonnenbergerfree(head);
461d19613acSJoerg Sonnenberger.Ed
462d19613acSJoerg Sonnenberger.Pp
463d19613acSJoerg SonnenbergerSince
464d19613acSJoerg Sonnenberger.Va var
465d19613acSJoerg Sonnenbergeris free'd, the
466aeb4517eSSascha Wildner.Fn SPLAY_FOREACH
467d19613acSJoerg Sonnenbergermacro refers to a pointer that may have been reallocated already.
468d19613acSJoerg SonnenbergerProper code needs a second variable.
469d19613acSJoerg Sonnenberger.Bd -literal -offset indent
470d19613acSJoerg Sonnenbergerfor (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
471d19613acSJoerg Sonnenberger	nxt = SPLAY_NEXT(NAME, head, var);
472d19613acSJoerg Sonnenberger	SPLAY_REMOVE(NAME, head, var);
473d19613acSJoerg Sonnenberger	free(var);
474d19613acSJoerg Sonnenberger}
475d19613acSJoerg Sonnenberger.Ed
476d19613acSJoerg Sonnenberger.Pp
477d19613acSJoerg SonnenbergerBoth
478d19613acSJoerg Sonnenberger.Fn RB_INSERT
479d19613acSJoerg Sonnenbergerand
480d19613acSJoerg Sonnenberger.Fn SPLAY_INSERT
481d19613acSJoerg Sonnenbergerreturn
482d19613acSJoerg Sonnenberger.Dv NULL
483d19613acSJoerg Sonnenbergerif the element was inserted in the tree successfully, otherwise they
484d19613acSJoerg Sonnenbergerreturn a pointer to the element with the colliding key.
485d19613acSJoerg Sonnenberger.Pp
486d19613acSJoerg SonnenbergerAccordingly,
487d19613acSJoerg Sonnenberger.Fn RB_REMOVE
488d19613acSJoerg Sonnenbergerand
489d19613acSJoerg Sonnenberger.Fn SPLAY_REMOVE
490d19613acSJoerg Sonnenbergerreturn the pointer to the removed element, otherwise they return
491d19613acSJoerg Sonnenberger.Dv NULL
492d19613acSJoerg Sonnenbergerto indicate an error.
493d19613acSJoerg Sonnenberger.Sh AUTHORS
494d19613acSJoerg SonnenbergerThe author of the tree macros is
495d19613acSJoerg Sonnenberger.An Niels Provos .
496