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