xref: /freebsd/share/man/man3/tree.3 (revision d72cd7797508ade2029a315e878fac65950b1bbb)
187f5f0ecSDag-Erling Smørgrav.\"	$OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $
2480565d5SRuslan Ermilov.\"
3480565d5SRuslan Ermilov.\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
4480565d5SRuslan Ermilov.\" All rights reserved.
5480565d5SRuslan Ermilov.\"
6480565d5SRuslan Ermilov.\" Redistribution and use in source and binary forms, with or without
7480565d5SRuslan Ermilov.\" modification, are permitted provided that the following conditions
8480565d5SRuslan Ermilov.\" are met:
9480565d5SRuslan Ermilov.\" 1. Redistributions of source code must retain the above copyright
10480565d5SRuslan Ermilov.\"    notice, this list of conditions and the following disclaimer.
11480565d5SRuslan Ermilov.\" 2. Redistributions in binary form must reproduce the above copyright
12480565d5SRuslan Ermilov.\"    notice, this list of conditions and the following disclaimer in the
13480565d5SRuslan Ermilov.\"    documentation and/or other materials provided with the distribution.
14480565d5SRuslan Ermilov.\" 3. All advertising materials mentioning features or use of this software
15480565d5SRuslan Ermilov.\"    must display the following acknowledgement:
16480565d5SRuslan Ermilov.\"      This product includes software developed by Niels Provos.
17480565d5SRuslan Ermilov.\" 4. The name of the author may not be used to endorse or promote products
18480565d5SRuslan Ermilov.\"    derived from this software without specific prior written permission.
19480565d5SRuslan Ermilov.\"
20480565d5SRuslan Ermilov.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21480565d5SRuslan Ermilov.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22480565d5SRuslan Ermilov.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23480565d5SRuslan Ermilov.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24480565d5SRuslan Ermilov.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25480565d5SRuslan Ermilov.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26480565d5SRuslan Ermilov.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27480565d5SRuslan Ermilov.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28480565d5SRuslan Ermilov.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29480565d5SRuslan Ermilov.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30480565d5SRuslan Ermilov.\"
31480565d5SRuslan Ermilov.\" $FreeBSD$
32480565d5SRuslan Ermilov.\"
33d72cd779SJason Evans.Dd January 17, 2006
3487f5f0ecSDag-Erling Smørgrav.Dt TREE 3
3587f5f0ecSDag-Erling Smørgrav.Os
3687f5f0ecSDag-Erling Smørgrav.Sh NAME
3787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_PROTOTYPE ,
3887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_GENERATE ,
3987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ENTRY ,
4087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_HEAD ,
4187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INITIALIZER ,
4287f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ROOT ,
4387f5f0ecSDag-Erling Smørgrav.Nm SPLAY_EMPTY ,
4487f5f0ecSDag-Erling Smørgrav.Nm SPLAY_NEXT ,
4587f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MIN ,
4687f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MAX ,
4787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FIND ,
4887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_LEFT ,
4987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_RIGHT ,
5087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FOREACH ,
5187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INIT ,
5287f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INSERT ,
5387f5f0ecSDag-Erling Smørgrav.Nm SPLAY_REMOVE ,
5487f5f0ecSDag-Erling Smørgrav.Nm RB_PROTOTYPE ,
55d72cd779SJason Evans.Nm RB_PROTOTYPE_STATIC ,
5687f5f0ecSDag-Erling Smørgrav.Nm RB_GENERATE ,
57d72cd779SJason Evans.Nm RB_GENERATE_STATIC ,
5887f5f0ecSDag-Erling Smørgrav.Nm RB_ENTRY ,
5987f5f0ecSDag-Erling Smørgrav.Nm RB_HEAD ,
6087f5f0ecSDag-Erling Smørgrav.Nm RB_INITIALIZER ,
6187f5f0ecSDag-Erling Smørgrav.Nm RB_ROOT ,
6287f5f0ecSDag-Erling Smørgrav.Nm RB_EMPTY ,
6387f5f0ecSDag-Erling Smørgrav.Nm RB_NEXT ,
6487f5f0ecSDag-Erling Smørgrav.Nm RB_MIN ,
6587f5f0ecSDag-Erling Smørgrav.Nm RB_MAX ,
6687f5f0ecSDag-Erling Smørgrav.Nm RB_FIND ,
6706115e08SJason Evans.Nm RB_NFIND ,
6887f5f0ecSDag-Erling Smørgrav.Nm RB_LEFT ,
6987f5f0ecSDag-Erling Smørgrav.Nm RB_RIGHT ,
7087f5f0ecSDag-Erling Smørgrav.Nm RB_PARENT ,
7187f5f0ecSDag-Erling Smørgrav.Nm RB_FOREACH ,
7287f5f0ecSDag-Erling Smørgrav.Nm RB_INIT ,
7387f5f0ecSDag-Erling Smørgrav.Nm RB_INSERT ,
7487f5f0ecSDag-Erling Smørgrav.Nm RB_REMOVE
7587f5f0ecSDag-Erling Smørgrav.Nd "implementations of splay and red-black trees"
7687f5f0ecSDag-Erling Smørgrav.Sh SYNOPSIS
77480565d5SRuslan Ermilov.In sys/tree.h
78480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP
79480565d5SRuslan Ermilov.Fn SPLAY_GENERATE NAME TYPE FIELD CMP
80480565d5SRuslan Ermilov.Fn SPLAY_ENTRY TYPE
81480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
8287f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
8387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
8487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT "SPLAY_HEAD *head"
85480565d5SRuslan Ermilov.Ft bool
8687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
8787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
88480565d5SRuslan Ermilov.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
8987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
90480565d5SRuslan Ermilov.Fn SPLAY_MIN NAME "SPLAY_HEAD *head"
9187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
92480565d5SRuslan Ermilov.Fn SPLAY_MAX NAME "SPLAY_HEAD *head"
9387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
94480565d5SRuslan Ermilov.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm"
9587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
9787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
99480565d5SRuslan Ermilov.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head"
10087f5f0ecSDag-Erling Smørgrav.Ft void
10187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT "SPLAY_HEAD *head"
10287f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
103480565d5SRuslan Ermilov.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
10487f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
105480565d5SRuslan Ermilov.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
106480565d5SRuslan Ermilov.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
107d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
108480565d5SRuslan Ermilov.Fn RB_GENERATE NAME TYPE FIELD CMP
109d72cd779SJason Evans.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
110480565d5SRuslan Ermilov.Fn RB_ENTRY TYPE
111480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
11287f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER "RB_HEAD *head"
11387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
11487f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT "RB_HEAD *head"
11587f5f0ecSDag-Erling Smørgrav.Ft "bool"
11687f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY "RB_HEAD *head"
11787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
118480565d5SRuslan Ermilov.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm"
11987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
120480565d5SRuslan Ermilov.Fn RB_MIN NAME "RB_HEAD *head"
12187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
122480565d5SRuslan Ermilov.Fn RB_MAX NAME "RB_HEAD *head"
12387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
124480565d5SRuslan Ermilov.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm"
12587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
12606115e08SJason Evans.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm"
12706115e08SJason Evans.Ft "struct TYPE *"
12887f5f0ecSDag-Erling Smørgrav.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
12987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13087f5f0ecSDag-Erling Smørgrav.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
13187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13287f5f0ecSDag-Erling Smørgrav.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
133480565d5SRuslan Ermilov.Fn RB_FOREACH VARNAME NAME "RB_HEAD *head"
13487f5f0ecSDag-Erling Smørgrav.Ft void
13587f5f0ecSDag-Erling Smørgrav.Fn RB_INIT "RB_HEAD *head"
13687f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
137480565d5SRuslan Ermilov.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm"
13887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
139480565d5SRuslan Ermilov.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm"
14087f5f0ecSDag-Erling Smørgrav.Sh DESCRIPTION
141480565d5SRuslan ErmilovThese macros define data structures for different types of trees:
14287f5f0ecSDag-Erling Smørgravsplay trees and red-black trees.
14387f5f0ecSDag-Erling Smørgrav.Pp
14487f5f0ecSDag-Erling SmørgravIn the macro definitions,
14587f5f0ecSDag-Erling Smørgrav.Fa TYPE
14687f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must contain a field of type
147480565d5SRuslan Ermilov.Vt SPLAY_ENTRY ,
14887f5f0ecSDag-Erling Smørgravor
149480565d5SRuslan Ermilov.Vt RB_ENTRY ,
15087f5f0ecSDag-Erling Smørgravnamed
15187f5f0ecSDag-Erling Smørgrav.Fa ENTRYNAME .
15287f5f0ecSDag-Erling SmørgravThe argument
15387f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
15487f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must be declared
15587f5f0ecSDag-Erling Smørgravusing the macros
15687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD ,
15787f5f0ecSDag-Erling Smørgravor
15887f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD .
15987f5f0ecSDag-Erling SmørgravThe argument
16087f5f0ecSDag-Erling Smørgrav.Fa NAME
16187f5f0ecSDag-Erling Smørgravhas to be a unique name prefix for every tree that is defined.
16287f5f0ecSDag-Erling Smørgrav.Pp
163d72cd779SJason EvansThe function prototypes are declared with
164480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE ,
165d72cd779SJason Evans.Fn RB_PROTOTYPE ,
16687f5f0ecSDag-Erling Smørgravor
167d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC .
168d72cd779SJason EvansThe function bodies are generated with
169480565d5SRuslan Ermilov.Fn SPLAY_GENERATE ,
170d72cd779SJason Evans.Fn RB_GENERATE ,
17187f5f0ecSDag-Erling Smørgravor
172d72cd779SJason Evans.Fn RB_GENERATE_STATIC .
17387f5f0ecSDag-Erling SmørgravSee the examples below for further explanation of how these macros are used.
17487f5f0ecSDag-Erling Smørgrav.Sh SPLAY TREES
175480565d5SRuslan ErmilovA splay tree is a self-organizing data structure.
176480565d5SRuslan ErmilovEvery operation on the tree causes a splay to happen.
177480565d5SRuslan ErmilovThe splay moves the requested
17887f5f0ecSDag-Erling Smørgravnode to the root of the tree and partly rebalances it.
17987f5f0ecSDag-Erling Smørgrav.Pp
18087f5f0ecSDag-Erling SmørgravThis has the benefit that request locality causes faster lookups as
181480565d5SRuslan Ermilovthe requested nodes move to the top of the tree.
182480565d5SRuslan ErmilovOn the other hand, every lookup causes memory writes.
18387f5f0ecSDag-Erling Smørgrav.Pp
184480565d5SRuslan ErmilovThe Balance Theorem bounds the total access time for
185480565d5SRuslan Ermilov.Ar m
186480565d5SRuslan Ermilovoperations and
187480565d5SRuslan Ermilov.Ar n
188480565d5SRuslan Ermilovinserts on an initially empty tree as
189480565d5SRuslan Ermilov.Fn O "\*[lp]m + n\*[rp]lg n" .
190480565d5SRuslan ErmilovThe
191480565d5SRuslan Ermilovamortized cost for a sequence of
192480565d5SRuslan Ermilov.Ar m
193480565d5SRuslan Ermilovaccesses to a splay tree is
194480565d5SRuslan Ermilov.Fn O "lg n" .
19587f5f0ecSDag-Erling Smørgrav.Pp
19687f5f0ecSDag-Erling SmørgravA splay tree is headed by a structure defined by the
19787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD
19887f5f0ecSDag-Erling Smørgravmacro.
19987f5f0ecSDag-Erling SmørgravA
20087f5f0ecSDag-Erling Smørgravstructure is declared as follows:
201480565d5SRuslan Ermilov.Bd -ragged -offset indent
202480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
203480565d5SRuslan Ermilov.Va head ;
20487f5f0ecSDag-Erling Smørgrav.Ed
20587f5f0ecSDag-Erling Smørgrav.Pp
20687f5f0ecSDag-Erling Smørgravwhere
20787f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
20887f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
20987f5f0ecSDag-Erling Smørgrav.Fa TYPE
21087f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
21187f5f0ecSDag-Erling Smørgrav.Pp
21287f5f0ecSDag-Erling SmørgravThe
21387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY
21487f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
21587f5f0ecSDag-Erling Smørgrav.Pp
21687f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
21787f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
21887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
21987f5f0ecSDag-Erling Smørgravmacro,
22087f5f0ecSDag-Erling Smørgravwhere
22187f5f0ecSDag-Erling Smørgrav.Fa NAME
22287f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
22387f5f0ecSDag-Erling SmørgravThe
22487f5f0ecSDag-Erling Smørgrav.Fa TYPE
22587f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
22687f5f0ecSDag-Erling Smørgravby the tree.
22787f5f0ecSDag-Erling SmørgravThe
22887f5f0ecSDag-Erling Smørgrav.Fa FIELD
22987f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
23087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY .
23187f5f0ecSDag-Erling Smørgrav.Pp
23287f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
23387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_GENERATE
234480565d5SRuslan Ermilovmacro.
235480565d5SRuslan ErmilovIt takes the same arguments as the
23687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
23787f5f0ecSDag-Erling Smørgravmacro, but should be used only once.
23887f5f0ecSDag-Erling Smørgrav.Pp
23987f5f0ecSDag-Erling SmørgravFinally,
24087f5f0ecSDag-Erling Smørgravthe
24187f5f0ecSDag-Erling Smørgrav.Fa CMP
242480565d5SRuslan Ermilovargument is the name of a function used to compare tree nodes
243480565d5SRuslan Ermilovwith each other.
244480565d5SRuslan ErmilovThe function takes two arguments of type
245480565d5SRuslan Ermilov.Vt "struct TYPE *" .
24687f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
247480565d5SRuslan Ermilovvalue smaller than zero.
248480565d5SRuslan ErmilovIf they are equal, the function returns zero.
249480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero.
250480565d5SRuslan ErmilovThe compare
25187f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
25287f5f0ecSDag-Erling Smørgrav.Pp
25387f5f0ecSDag-Erling SmørgravThe
25487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT
25587f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
25687f5f0ecSDag-Erling Smørgrav.Fa head .
25787f5f0ecSDag-Erling Smørgrav.Pp
25887f5f0ecSDag-Erling SmørgravThe splay tree can also be initialized statically by using the
25987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER
26087f5f0ecSDag-Erling Smørgravmacro like this:
261480565d5SRuslan Ermilov.Bd -ragged -offset indent
262480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
263480565d5SRuslan Ermilov.Va head
264480565d5SRuslan Ermilov=
265480565d5SRuslan Ermilov.Fn SPLAY_INITIALIZER &head ;
26687f5f0ecSDag-Erling Smørgrav.Ed
26787f5f0ecSDag-Erling Smørgrav.Pp
26887f5f0ecSDag-Erling SmørgravThe
26987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
27087f5f0ecSDag-Erling Smørgravmacro inserts the new element
27187f5f0ecSDag-Erling Smørgrav.Fa elm
27287f5f0ecSDag-Erling Smørgravinto the tree.
27387f5f0ecSDag-Erling Smørgrav.Pp
27487f5f0ecSDag-Erling SmørgravThe
27587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
27687f5f0ecSDag-Erling Smørgravmacro removes the element
27787f5f0ecSDag-Erling Smørgrav.Fa elm
27887f5f0ecSDag-Erling Smørgravfrom the tree pointed by
27987f5f0ecSDag-Erling Smørgrav.Fa head .
28087f5f0ecSDag-Erling Smørgrav.Pp
28187f5f0ecSDag-Erling SmørgravThe
28287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FIND
28387f5f0ecSDag-Erling Smørgravmacro can be used to find a particular element in the tree.
28487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
28587f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
28687f5f0ecSDag-Erling Smørgravfind.key = 30;
28787f5f0ecSDag-Erling Smørgravres = SPLAY_FIND(NAME, head, &find);
28887f5f0ecSDag-Erling Smørgrav.Ed
28987f5f0ecSDag-Erling Smørgrav.Pp
29087f5f0ecSDag-Erling SmørgravThe
29187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT ,
29287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MIN ,
29387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MAX ,
29487f5f0ecSDag-Erling Smørgravand
29587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_NEXT
29687f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
29787f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
29887f5f0ecSDag-Erling Smørgravfor (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
29987f5f0ecSDag-Erling Smørgrav.Ed
30087f5f0ecSDag-Erling Smørgrav.Pp
30187f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
30287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FOREACH
30387f5f0ecSDag-Erling Smørgravmacro:
304480565d5SRuslan Ermilov.Bd -ragged -offset indent
305480565d5SRuslan Ermilov.Fn SPLAY_FOREACH np NAME head
30687f5f0ecSDag-Erling Smørgrav.Ed
30787f5f0ecSDag-Erling Smørgrav.Pp
30887f5f0ecSDag-Erling SmørgravThe
30987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY
31087f5f0ecSDag-Erling Smørgravmacro should be used to check whether a splay tree is empty.
31187f5f0ecSDag-Erling Smørgrav.Sh RED-BLACK TREES
31287f5f0ecSDag-Erling SmørgravA red-black tree is a binary search tree with the node color as an
313480565d5SRuslan Ermilovextra attribute.
314480565d5SRuslan ErmilovIt fulfills a set of conditions:
315480565d5SRuslan Ermilov.Bl -enum -offset indent
31687f5f0ecSDag-Erling Smørgrav.It
317480565d5SRuslan ErmilovEvery search path from the root to a leaf consists of the same number of
318480565d5SRuslan Ermilovblack nodes.
31987f5f0ecSDag-Erling Smørgrav.It
320480565d5SRuslan ErmilovEach red node (except for the root) has a black parent.
32187f5f0ecSDag-Erling Smørgrav.It
322480565d5SRuslan ErmilovEach leaf node is black.
32387f5f0ecSDag-Erling Smørgrav.El
32487f5f0ecSDag-Erling Smørgrav.Pp
325480565d5SRuslan ErmilovEvery operation on a red-black tree is bounded as
326480565d5SRuslan Ermilov.Fn O "lg n" .
327480565d5SRuslan ErmilovThe maximum height of a red-black tree is
328480565d5SRuslan Ermilov.Fn 2lg "n + 1" .
32987f5f0ecSDag-Erling Smørgrav.Pp
33087f5f0ecSDag-Erling SmørgravA red-black tree is headed by a structure defined by the
33187f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD
33287f5f0ecSDag-Erling Smørgravmacro.
33387f5f0ecSDag-Erling SmørgravA
33487f5f0ecSDag-Erling Smørgravstructure is declared as follows:
335480565d5SRuslan Ermilov.Bd -ragged -offset indent
336480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
337480565d5SRuslan Ermilov.Va head ;
33887f5f0ecSDag-Erling Smørgrav.Ed
33987f5f0ecSDag-Erling Smørgrav.Pp
34087f5f0ecSDag-Erling Smørgravwhere
34187f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
34287f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
34387f5f0ecSDag-Erling Smørgrav.Fa TYPE
34487f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
34587f5f0ecSDag-Erling Smørgrav.Pp
34687f5f0ecSDag-Erling SmørgravThe
34787f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY
34887f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
34987f5f0ecSDag-Erling Smørgrav.Pp
35087f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
35187f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
35287f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
353d72cd779SJason Evansor
354d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC
35587f5f0ecSDag-Erling Smørgravmacro,
35687f5f0ecSDag-Erling Smørgravwhere
35787f5f0ecSDag-Erling Smørgrav.Fa NAME
35887f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
35987f5f0ecSDag-Erling SmørgravThe
36087f5f0ecSDag-Erling Smørgrav.Fa TYPE
36187f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
36287f5f0ecSDag-Erling Smørgravby the tree.
36387f5f0ecSDag-Erling SmørgravThe
36487f5f0ecSDag-Erling Smørgrav.Fa FIELD
36587f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
36687f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY .
36787f5f0ecSDag-Erling Smørgrav.Pp
36887f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
36987f5f0ecSDag-Erling Smørgrav.Fn RB_GENERATE
370d72cd779SJason Evansor
371d72cd779SJason Evans.Fn RB_GENERATE_STATIC
372480565d5SRuslan Ermilovmacro.
373d72cd779SJason EvansThese macros take the same arguments as the
37487f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
375d72cd779SJason Evansand
376d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC
377d72cd779SJason Evansmacros, but should be used only once.
37887f5f0ecSDag-Erling Smørgrav.Pp
37987f5f0ecSDag-Erling SmørgravFinally,
38087f5f0ecSDag-Erling Smørgravthe
38187f5f0ecSDag-Erling Smørgrav.Fa CMP
38287f5f0ecSDag-Erling Smørgravargument is the name of a function used to compare tree noded
383480565d5SRuslan Ermilovwith each other.
384480565d5SRuslan ErmilovThe function takes two arguments of type
385480565d5SRuslan Ermilov.Vt "struct TYPE *" .
38687f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
387480565d5SRuslan Ermilovvalue smaller than zero.
388480565d5SRuslan ErmilovIf they are equal, the function returns zero.
389480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero.
390480565d5SRuslan ErmilovThe compare
39187f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
39287f5f0ecSDag-Erling Smørgrav.Pp
39387f5f0ecSDag-Erling SmørgravThe
39487f5f0ecSDag-Erling Smørgrav.Fn RB_INIT
39587f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
39687f5f0ecSDag-Erling Smørgrav.Fa head .
39787f5f0ecSDag-Erling Smørgrav.Pp
3983b96c71fSMike PritchardThe red-black tree can also be initialized statically by using the
39987f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER
40087f5f0ecSDag-Erling Smørgravmacro like this:
401480565d5SRuslan Ermilov.Bd -ragged -offset indent
402480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
403480565d5SRuslan Ermilov.Va head
404480565d5SRuslan Ermilov=
405480565d5SRuslan Ermilov.Fn RB_INITIALIZER &head ;
40687f5f0ecSDag-Erling Smørgrav.Ed
40787f5f0ecSDag-Erling Smørgrav.Pp
40887f5f0ecSDag-Erling SmørgravThe
40987f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
41087f5f0ecSDag-Erling Smørgravmacro inserts the new element
41187f5f0ecSDag-Erling Smørgrav.Fa elm
41287f5f0ecSDag-Erling Smørgravinto the tree.
41387f5f0ecSDag-Erling Smørgrav.Pp
41487f5f0ecSDag-Erling SmørgravThe
41587f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
41687f5f0ecSDag-Erling Smørgravmacro removes the element
41787f5f0ecSDag-Erling Smørgrav.Fa elm
41887f5f0ecSDag-Erling Smørgravfrom the tree pointed by
41987f5f0ecSDag-Erling Smørgrav.Fa head .
42087f5f0ecSDag-Erling Smørgrav.Pp
42187f5f0ecSDag-Erling SmørgravThe
42287f5f0ecSDag-Erling Smørgrav.Fn RB_FIND
42306115e08SJason Evansand
42406115e08SJason Evans.Fn RB_NFIND
42506115e08SJason Evansmacros can be used to find a particular element in the tree.
42687f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
42787f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
42887f5f0ecSDag-Erling Smørgravfind.key = 30;
42987f5f0ecSDag-Erling Smørgravres = RB_FIND(NAME, head, &find);
43087f5f0ecSDag-Erling Smørgrav.Ed
43187f5f0ecSDag-Erling Smørgrav.Pp
43287f5f0ecSDag-Erling SmørgravThe
43387f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT ,
43487f5f0ecSDag-Erling Smørgrav.Fn RB_MIN ,
43587f5f0ecSDag-Erling Smørgrav.Fn RB_MAX ,
43687f5f0ecSDag-Erling Smørgravand
43787f5f0ecSDag-Erling Smørgrav.Fn RB_NEXT
43887f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
439480565d5SRuslan Ermilov.Pp
440480565d5SRuslan Ermilov.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))"
44187f5f0ecSDag-Erling Smørgrav.Pp
44287f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
44387f5f0ecSDag-Erling Smørgrav.Fn RB_FOREACH
44487f5f0ecSDag-Erling Smørgravmacro:
445480565d5SRuslan Ermilov.Bd -ragged -offset indent
446480565d5SRuslan Ermilov.Fn RB_FOREACH np NAME head
44787f5f0ecSDag-Erling Smørgrav.Ed
44887f5f0ecSDag-Erling Smørgrav.Pp
44987f5f0ecSDag-Erling SmørgravThe
45087f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY
451309e4b9bSDag-Erling Smørgravmacro should be used to check whether a red-black tree is empty.
45287f5f0ecSDag-Erling Smørgrav.Sh NOTES
45387f5f0ecSDag-Erling SmørgravTrying to free a tree in the following way is a common error:
45487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
45587f5f0ecSDag-Erling SmørgravSPLAY_FOREACH(var, NAME, head) {
45687f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
45787f5f0ecSDag-Erling Smørgrav	free(var);
45887f5f0ecSDag-Erling Smørgrav}
45987f5f0ecSDag-Erling Smørgravfree(head);
46087f5f0ecSDag-Erling Smørgrav.Ed
46187f5f0ecSDag-Erling Smørgrav.Pp
46287f5f0ecSDag-Erling SmørgravSince
46387f5f0ecSDag-Erling Smørgrav.Va var
464480565d5SRuslan Ermilovis freed, the
46587f5f0ecSDag-Erling Smørgrav.Fn FOREACH
46687f5f0ecSDag-Erling Smørgravmacro refers to a pointer that may have been reallocated already.
46787f5f0ecSDag-Erling SmørgravProper code needs a second variable.
46887f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
46987f5f0ecSDag-Erling Smørgravfor (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
47087f5f0ecSDag-Erling Smørgrav	nxt = SPLAY_NEXT(NAME, head, var);
47187f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
47287f5f0ecSDag-Erling Smørgrav	free(var);
47387f5f0ecSDag-Erling Smørgrav}
47487f5f0ecSDag-Erling Smørgrav.Ed
47587f5f0ecSDag-Erling Smørgrav.Pp
47687f5f0ecSDag-Erling SmørgravBoth
47787f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
47887f5f0ecSDag-Erling Smørgravand
47987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
48087f5f0ecSDag-Erling Smørgravreturn
481480565d5SRuslan Ermilov.Dv NULL
48287f5f0ecSDag-Erling Smørgravif the element was inserted in the tree successfully, otherwise they
48387f5f0ecSDag-Erling Smørgravreturn a pointer to the element with the colliding key.
48487f5f0ecSDag-Erling Smørgrav.Pp
48587f5f0ecSDag-Erling SmørgravAccordingly,
48687f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
48787f5f0ecSDag-Erling Smørgravand
48887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
48987f5f0ecSDag-Erling Smørgravreturn the pointer to the removed element otherwise they return
490480565d5SRuslan Ermilov.Dv NULL
49187f5f0ecSDag-Erling Smørgravto indicate an error.
49287f5f0ecSDag-Erling Smørgrav.Sh AUTHORS
493480565d5SRuslan ErmilovThe author of the tree macros is
494480565d5SRuslan Ermilov.An Niels Provos .
495