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