xref: /freebsd/share/man/man3/tree.3 (revision 639bf7bd71cc5ec28494a8896cfaa9235fca8e98)
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.\"
33bff27689SBruce M Simpson.Dd November 10, 2013
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 ,
648e4fd0a1SJason Evans.Nm RB_PREV ,
6587f5f0ecSDag-Erling Smørgrav.Nm RB_MIN ,
6687f5f0ecSDag-Erling Smørgrav.Nm RB_MAX ,
6787f5f0ecSDag-Erling Smørgrav.Nm RB_FIND ,
6806115e08SJason Evans.Nm RB_NFIND ,
6987f5f0ecSDag-Erling Smørgrav.Nm RB_LEFT ,
7087f5f0ecSDag-Erling Smørgrav.Nm RB_RIGHT ,
7187f5f0ecSDag-Erling Smørgrav.Nm RB_PARENT ,
7287f5f0ecSDag-Erling Smørgrav.Nm RB_FOREACH ,
73bff27689SBruce M Simpson.Nm RB_FOREACH_FROM ,
749dbae282SGleb Smirnoff.Nm RB_FOREACH_SAFE ,
758e4fd0a1SJason Evans.Nm RB_FOREACH_REVERSE ,
76bff27689SBruce M Simpson.Nm RB_FOREACH_REVERSE_FROM ,
779dbae282SGleb Smirnoff.Nm RB_FOREACH_REVERSE_SAFE ,
7887f5f0ecSDag-Erling Smørgrav.Nm RB_INIT ,
7987f5f0ecSDag-Erling Smørgrav.Nm RB_INSERT ,
8087f5f0ecSDag-Erling Smørgrav.Nm RB_REMOVE
8187f5f0ecSDag-Erling Smørgrav.Nd "implementations of splay and red-black trees"
8287f5f0ecSDag-Erling Smørgrav.Sh SYNOPSIS
83480565d5SRuslan Ermilov.In sys/tree.h
84480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP
85480565d5SRuslan Ermilov.Fn SPLAY_GENERATE NAME TYPE FIELD CMP
86480565d5SRuslan Ermilov.Fn SPLAY_ENTRY TYPE
87480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
8887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
8987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
9087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT "SPLAY_HEAD *head"
91480565d5SRuslan Ermilov.Ft bool
9287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
9387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
94480565d5SRuslan Ermilov.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
9587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
96480565d5SRuslan Ermilov.Fn SPLAY_MIN NAME "SPLAY_HEAD *head"
9787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
98480565d5SRuslan Ermilov.Fn SPLAY_MAX NAME "SPLAY_HEAD *head"
9987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
100480565d5SRuslan Ermilov.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm"
10187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
10287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
10387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
10487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
105480565d5SRuslan Ermilov.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head"
10687f5f0ecSDag-Erling Smørgrav.Ft void
10787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT "SPLAY_HEAD *head"
10887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
109480565d5SRuslan Ermilov.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
11087f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
111480565d5SRuslan Ermilov.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
112480565d5SRuslan Ermilov.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
113d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
114480565d5SRuslan Ermilov.Fn RB_GENERATE NAME TYPE FIELD CMP
115d72cd779SJason Evans.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
116480565d5SRuslan Ermilov.Fn RB_ENTRY TYPE
117480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
11887f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER "RB_HEAD *head"
11987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
12087f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT "RB_HEAD *head"
12187f5f0ecSDag-Erling Smørgrav.Ft "bool"
12287f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY "RB_HEAD *head"
12387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
124480565d5SRuslan Ermilov.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm"
12587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
1268e4fd0a1SJason Evans.Fn RB_PREV NAME "RB_HEAD *head" "struct TYPE *elm"
1278e4fd0a1SJason Evans.Ft "struct TYPE *"
128480565d5SRuslan Ermilov.Fn RB_MIN NAME "RB_HEAD *head"
12987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
130480565d5SRuslan Ermilov.Fn RB_MAX NAME "RB_HEAD *head"
13187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
132480565d5SRuslan Ermilov.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm"
13387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13406115e08SJason Evans.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm"
13506115e08SJason Evans.Ft "struct TYPE *"
13687f5f0ecSDag-Erling Smørgrav.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
13787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13887f5f0ecSDag-Erling Smørgrav.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
13987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
14087f5f0ecSDag-Erling Smørgrav.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
141480565d5SRuslan Ermilov.Fn RB_FOREACH VARNAME NAME "RB_HEAD *head"
142*639bf7bdSBruce M Simpson.Fn RB_FOREACH_FROM "VARNAME" "NAME" "POS_VARNAME"
1439dbae282SGleb Smirnoff.Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
1448e4fd0a1SJason Evans.Fn RB_FOREACH_REVERSE VARNAME NAME "RB_HEAD *head"
145*639bf7bdSBruce M Simpson.Fn RB_FOREACH_REVERSE_FROM "VARNAME" "NAME" "POS_VARNAME"
1469dbae282SGleb Smirnoff.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME"
14787f5f0ecSDag-Erling Smørgrav.Ft void
14887f5f0ecSDag-Erling Smørgrav.Fn RB_INIT "RB_HEAD *head"
14987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
150480565d5SRuslan Ermilov.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm"
15187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
152480565d5SRuslan Ermilov.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm"
15387f5f0ecSDag-Erling Smørgrav.Sh DESCRIPTION
154480565d5SRuslan ErmilovThese macros define data structures for different types of trees:
15587f5f0ecSDag-Erling Smørgravsplay trees and red-black trees.
15687f5f0ecSDag-Erling Smørgrav.Pp
15787f5f0ecSDag-Erling SmørgravIn the macro definitions,
15887f5f0ecSDag-Erling Smørgrav.Fa TYPE
15987f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must contain a field of type
160480565d5SRuslan Ermilov.Vt SPLAY_ENTRY ,
16187f5f0ecSDag-Erling Smørgravor
162480565d5SRuslan Ermilov.Vt RB_ENTRY ,
16387f5f0ecSDag-Erling Smørgravnamed
16487f5f0ecSDag-Erling Smørgrav.Fa ENTRYNAME .
16587f5f0ecSDag-Erling SmørgravThe argument
16687f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
16787f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must be declared
16887f5f0ecSDag-Erling Smørgravusing the macros
16987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD ,
17087f5f0ecSDag-Erling Smørgravor
17187f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD .
17287f5f0ecSDag-Erling SmørgravThe argument
17387f5f0ecSDag-Erling Smørgrav.Fa NAME
17487f5f0ecSDag-Erling Smørgravhas to be a unique name prefix for every tree that is defined.
17587f5f0ecSDag-Erling Smørgrav.Pp
176d72cd779SJason EvansThe function prototypes are declared with
177480565d5SRuslan Ermilov.Fn SPLAY_PROTOTYPE ,
178d72cd779SJason Evans.Fn RB_PROTOTYPE ,
17987f5f0ecSDag-Erling Smørgravor
180d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC .
181d72cd779SJason EvansThe function bodies are generated with
182480565d5SRuslan Ermilov.Fn SPLAY_GENERATE ,
183d72cd779SJason Evans.Fn RB_GENERATE ,
18487f5f0ecSDag-Erling Smørgravor
185d72cd779SJason Evans.Fn RB_GENERATE_STATIC .
18687f5f0ecSDag-Erling SmørgravSee the examples below for further explanation of how these macros are used.
18787f5f0ecSDag-Erling Smørgrav.Sh SPLAY TREES
188480565d5SRuslan ErmilovA splay tree is a self-organizing data structure.
189480565d5SRuslan ErmilovEvery operation on the tree causes a splay to happen.
190480565d5SRuslan ErmilovThe splay moves the requested
19187f5f0ecSDag-Erling Smørgravnode to the root of the tree and partly rebalances it.
19287f5f0ecSDag-Erling Smørgrav.Pp
19387f5f0ecSDag-Erling SmørgravThis has the benefit that request locality causes faster lookups as
194480565d5SRuslan Ermilovthe requested nodes move to the top of the tree.
195480565d5SRuslan ErmilovOn the other hand, every lookup causes memory writes.
19687f5f0ecSDag-Erling Smørgrav.Pp
197480565d5SRuslan ErmilovThe Balance Theorem bounds the total access time for
198480565d5SRuslan Ermilov.Ar m
199480565d5SRuslan Ermilovoperations and
200480565d5SRuslan Ermilov.Ar n
201480565d5SRuslan Ermilovinserts on an initially empty tree as
202480565d5SRuslan Ermilov.Fn O "\*[lp]m + n\*[rp]lg n" .
203480565d5SRuslan ErmilovThe
204480565d5SRuslan Ermilovamortized cost for a sequence of
205480565d5SRuslan Ermilov.Ar m
206480565d5SRuslan Ermilovaccesses to a splay tree is
207480565d5SRuslan Ermilov.Fn O "lg n" .
20887f5f0ecSDag-Erling Smørgrav.Pp
20987f5f0ecSDag-Erling SmørgravA splay tree is headed by a structure defined by the
21087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD
21187f5f0ecSDag-Erling Smørgravmacro.
21287f5f0ecSDag-Erling SmørgravA
21387f5f0ecSDag-Erling Smørgravstructure is declared as follows:
214480565d5SRuslan Ermilov.Bd -ragged -offset indent
215480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
216480565d5SRuslan Ermilov.Va head ;
21787f5f0ecSDag-Erling Smørgrav.Ed
21887f5f0ecSDag-Erling Smørgrav.Pp
21987f5f0ecSDag-Erling Smørgravwhere
22087f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
22187f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
22287f5f0ecSDag-Erling Smørgrav.Fa TYPE
22387f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
22487f5f0ecSDag-Erling Smørgrav.Pp
22587f5f0ecSDag-Erling SmørgravThe
22687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY
22787f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
22887f5f0ecSDag-Erling Smørgrav.Pp
22987f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
23087f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
23187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
23287f5f0ecSDag-Erling Smørgravmacro,
23387f5f0ecSDag-Erling Smørgravwhere
23487f5f0ecSDag-Erling Smørgrav.Fa NAME
23587f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
23687f5f0ecSDag-Erling SmørgravThe
23787f5f0ecSDag-Erling Smørgrav.Fa TYPE
23887f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
23987f5f0ecSDag-Erling Smørgravby the tree.
24087f5f0ecSDag-Erling SmørgravThe
24187f5f0ecSDag-Erling Smørgrav.Fa FIELD
24287f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
24387f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY .
24487f5f0ecSDag-Erling Smørgrav.Pp
24587f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
24687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_GENERATE
247480565d5SRuslan Ermilovmacro.
248480565d5SRuslan ErmilovIt takes the same arguments as the
24987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
25087f5f0ecSDag-Erling Smørgravmacro, but should be used only once.
25187f5f0ecSDag-Erling Smørgrav.Pp
25287f5f0ecSDag-Erling SmørgravFinally,
25387f5f0ecSDag-Erling Smørgravthe
25487f5f0ecSDag-Erling Smørgrav.Fa CMP
255480565d5SRuslan Ermilovargument is the name of a function used to compare tree nodes
256480565d5SRuslan Ermilovwith each other.
257480565d5SRuslan ErmilovThe function takes two arguments of type
258480565d5SRuslan Ermilov.Vt "struct TYPE *" .
25987f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
260480565d5SRuslan Ermilovvalue smaller than zero.
261480565d5SRuslan ErmilovIf they are equal, the function returns zero.
262480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero.
263480565d5SRuslan ErmilovThe compare
26487f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
26587f5f0ecSDag-Erling Smørgrav.Pp
26687f5f0ecSDag-Erling SmørgravThe
26787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT
26887f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
26987f5f0ecSDag-Erling Smørgrav.Fa head .
27087f5f0ecSDag-Erling Smørgrav.Pp
27187f5f0ecSDag-Erling SmørgravThe splay tree can also be initialized statically by using the
27287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER
27387f5f0ecSDag-Erling Smørgravmacro like this:
274480565d5SRuslan Ermilov.Bd -ragged -offset indent
275480565d5SRuslan Ermilov.Fn SPLAY_HEAD HEADNAME TYPE
276480565d5SRuslan Ermilov.Va head
277480565d5SRuslan Ermilov=
278480565d5SRuslan Ermilov.Fn SPLAY_INITIALIZER &head ;
27987f5f0ecSDag-Erling Smørgrav.Ed
28087f5f0ecSDag-Erling Smørgrav.Pp
28187f5f0ecSDag-Erling SmørgravThe
28287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
28387f5f0ecSDag-Erling Smørgravmacro inserts the new element
28487f5f0ecSDag-Erling Smørgrav.Fa elm
28587f5f0ecSDag-Erling Smørgravinto the tree.
28687f5f0ecSDag-Erling Smørgrav.Pp
28787f5f0ecSDag-Erling SmørgravThe
28887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
28987f5f0ecSDag-Erling Smørgravmacro removes the element
29087f5f0ecSDag-Erling Smørgrav.Fa elm
29187f5f0ecSDag-Erling Smørgravfrom the tree pointed by
29287f5f0ecSDag-Erling Smørgrav.Fa head .
29387f5f0ecSDag-Erling Smørgrav.Pp
29487f5f0ecSDag-Erling SmørgravThe
29587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FIND
29687f5f0ecSDag-Erling Smørgravmacro can be used to find a particular element in the tree.
29787f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
29887f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
29987f5f0ecSDag-Erling Smørgravfind.key = 30;
30087f5f0ecSDag-Erling Smørgravres = SPLAY_FIND(NAME, head, &find);
30187f5f0ecSDag-Erling Smørgrav.Ed
30287f5f0ecSDag-Erling Smørgrav.Pp
30387f5f0ecSDag-Erling SmørgravThe
30487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT ,
30587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MIN ,
30687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MAX ,
30787f5f0ecSDag-Erling Smørgravand
30887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_NEXT
30987f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
31087f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
31187f5f0ecSDag-Erling Smørgravfor (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
31287f5f0ecSDag-Erling Smørgrav.Ed
31387f5f0ecSDag-Erling Smørgrav.Pp
31487f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
31587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FOREACH
31687f5f0ecSDag-Erling Smørgravmacro:
317480565d5SRuslan Ermilov.Bd -ragged -offset indent
318480565d5SRuslan Ermilov.Fn SPLAY_FOREACH np NAME head
31987f5f0ecSDag-Erling Smørgrav.Ed
32087f5f0ecSDag-Erling Smørgrav.Pp
32187f5f0ecSDag-Erling SmørgravThe
32287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY
32387f5f0ecSDag-Erling Smørgravmacro should be used to check whether a splay tree is empty.
32487f5f0ecSDag-Erling Smørgrav.Sh RED-BLACK TREES
32587f5f0ecSDag-Erling SmørgravA red-black tree is a binary search tree with the node color as an
326480565d5SRuslan Ermilovextra attribute.
327480565d5SRuslan ErmilovIt fulfills a set of conditions:
328480565d5SRuslan Ermilov.Bl -enum -offset indent
32987f5f0ecSDag-Erling Smørgrav.It
330480565d5SRuslan ErmilovEvery search path from the root to a leaf consists of the same number of
331480565d5SRuslan Ermilovblack nodes.
33287f5f0ecSDag-Erling Smørgrav.It
333480565d5SRuslan ErmilovEach red node (except for the root) has a black parent.
33487f5f0ecSDag-Erling Smørgrav.It
335480565d5SRuslan ErmilovEach leaf node is black.
33687f5f0ecSDag-Erling Smørgrav.El
33787f5f0ecSDag-Erling Smørgrav.Pp
338480565d5SRuslan ErmilovEvery operation on a red-black tree is bounded as
339480565d5SRuslan Ermilov.Fn O "lg n" .
340480565d5SRuslan ErmilovThe maximum height of a red-black tree is
341480565d5SRuslan Ermilov.Fn 2lg "n + 1" .
34287f5f0ecSDag-Erling Smørgrav.Pp
34387f5f0ecSDag-Erling SmørgravA red-black tree is headed by a structure defined by the
34487f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD
34587f5f0ecSDag-Erling Smørgravmacro.
34687f5f0ecSDag-Erling SmørgravA
34787f5f0ecSDag-Erling Smørgravstructure is declared as follows:
348480565d5SRuslan Ermilov.Bd -ragged -offset indent
349480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
350480565d5SRuslan Ermilov.Va head ;
35187f5f0ecSDag-Erling Smørgrav.Ed
35287f5f0ecSDag-Erling Smørgrav.Pp
35387f5f0ecSDag-Erling Smørgravwhere
35487f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
35587f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
35687f5f0ecSDag-Erling Smørgrav.Fa TYPE
35787f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
35887f5f0ecSDag-Erling Smørgrav.Pp
35987f5f0ecSDag-Erling SmørgravThe
36087f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY
36187f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
36287f5f0ecSDag-Erling Smørgrav.Pp
36387f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
36487f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
36587f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
366d72cd779SJason Evansor
367d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC
36887f5f0ecSDag-Erling Smørgravmacro,
36987f5f0ecSDag-Erling Smørgravwhere
37087f5f0ecSDag-Erling Smørgrav.Fa NAME
37187f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
37287f5f0ecSDag-Erling SmørgravThe
37387f5f0ecSDag-Erling Smørgrav.Fa TYPE
37487f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
37587f5f0ecSDag-Erling Smørgravby the tree.
37687f5f0ecSDag-Erling SmørgravThe
37787f5f0ecSDag-Erling Smørgrav.Fa FIELD
37887f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
37987f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY .
38087f5f0ecSDag-Erling Smørgrav.Pp
38187f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
38287f5f0ecSDag-Erling Smørgrav.Fn RB_GENERATE
383d72cd779SJason Evansor
384d72cd779SJason Evans.Fn RB_GENERATE_STATIC
385480565d5SRuslan Ermilovmacro.
386d72cd779SJason EvansThese macros take the same arguments as the
38787f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
388d72cd779SJason Evansand
389d72cd779SJason Evans.Fn RB_PROTOTYPE_STATIC
390d72cd779SJason Evansmacros, but should be used only once.
39187f5f0ecSDag-Erling Smørgrav.Pp
39287f5f0ecSDag-Erling SmørgravFinally,
39387f5f0ecSDag-Erling Smørgravthe
39487f5f0ecSDag-Erling Smørgrav.Fa CMP
3959d44cd42SBenno Riceargument is the name of a function used to compare tree nodes
396480565d5SRuslan Ermilovwith each other.
397480565d5SRuslan ErmilovThe function takes two arguments of type
398480565d5SRuslan Ermilov.Vt "struct TYPE *" .
39987f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
400480565d5SRuslan Ermilovvalue smaller than zero.
401480565d5SRuslan ErmilovIf they are equal, the function returns zero.
402480565d5SRuslan ErmilovOtherwise, it should return a value greater than zero.
403480565d5SRuslan ErmilovThe compare
40487f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
40587f5f0ecSDag-Erling Smørgrav.Pp
40687f5f0ecSDag-Erling SmørgravThe
40787f5f0ecSDag-Erling Smørgrav.Fn RB_INIT
40887f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
40987f5f0ecSDag-Erling Smørgrav.Fa head .
41087f5f0ecSDag-Erling Smørgrav.Pp
4113b96c71fSMike PritchardThe red-black tree can also be initialized statically by using the
41287f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER
41387f5f0ecSDag-Erling Smørgravmacro like this:
414480565d5SRuslan Ermilov.Bd -ragged -offset indent
415480565d5SRuslan Ermilov.Fn RB_HEAD HEADNAME TYPE
416480565d5SRuslan Ermilov.Va head
417480565d5SRuslan Ermilov=
418480565d5SRuslan Ermilov.Fn RB_INITIALIZER &head ;
41987f5f0ecSDag-Erling Smørgrav.Ed
42087f5f0ecSDag-Erling Smørgrav.Pp
42187f5f0ecSDag-Erling SmørgravThe
42287f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
42387f5f0ecSDag-Erling Smørgravmacro inserts the new element
42487f5f0ecSDag-Erling Smørgrav.Fa elm
42587f5f0ecSDag-Erling Smørgravinto the tree.
42687f5f0ecSDag-Erling Smørgrav.Pp
42787f5f0ecSDag-Erling SmørgravThe
42887f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
42987f5f0ecSDag-Erling Smørgravmacro removes the element
43087f5f0ecSDag-Erling Smørgrav.Fa elm
43187f5f0ecSDag-Erling Smørgravfrom the tree pointed by
43287f5f0ecSDag-Erling Smørgrav.Fa head .
43387f5f0ecSDag-Erling Smørgrav.Pp
43487f5f0ecSDag-Erling SmørgravThe
43587f5f0ecSDag-Erling Smørgrav.Fn RB_FIND
43606115e08SJason Evansand
43706115e08SJason Evans.Fn RB_NFIND
43806115e08SJason Evansmacros can be used to find a particular element in the tree.
43987f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
44087f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
44187f5f0ecSDag-Erling Smørgravfind.key = 30;
44287f5f0ecSDag-Erling Smørgravres = RB_FIND(NAME, head, &find);
44387f5f0ecSDag-Erling Smørgrav.Ed
44487f5f0ecSDag-Erling Smørgrav.Pp
44587f5f0ecSDag-Erling SmørgravThe
44687f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT ,
44787f5f0ecSDag-Erling Smørgrav.Fn RB_MIN ,
44887f5f0ecSDag-Erling Smørgrav.Fn RB_MAX ,
4498e4fd0a1SJason Evans.Fn RB_NEXT ,
45087f5f0ecSDag-Erling Smørgravand
4518e4fd0a1SJason Evans.Fn RB_PREV
45287f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
453480565d5SRuslan Ermilov.Pp
454480565d5SRuslan Ermilov.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))"
45587f5f0ecSDag-Erling Smørgrav.Pp
45687f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
45787f5f0ecSDag-Erling Smørgrav.Fn RB_FOREACH
4588e4fd0a1SJason Evansor
4598e4fd0a1SJason Evans.Fn RB_FOREACH_REVERSE
46087f5f0ecSDag-Erling Smørgravmacro:
461480565d5SRuslan Ermilov.Bd -ragged -offset indent
462480565d5SRuslan Ermilov.Fn RB_FOREACH np NAME head
46387f5f0ecSDag-Erling Smørgrav.Ed
46487f5f0ecSDag-Erling Smørgrav.Pp
4659dbae282SGleb SmirnoffThe macros
4669dbae282SGleb Smirnoff.Fn RB_FOREACH_SAFE
4679dbae282SGleb Smirnoffand
4689dbae282SGleb Smirnoff.Fn RB_FOREACH_REVERSE_SAFE
4699dbae282SGleb Smirnofftraverse the tree referenced by head
4709dbae282SGleb Smirnoffin a forward or reverse direction respectively,
4719dbae282SGleb Smirnoffassigning each element in turn to np.
4729dbae282SGleb SmirnoffHowever, unlike their unsafe counterparts,
4739dbae282SGleb Smirnoffthey permit both the removal of np
4749dbae282SGleb Smirnoffas well as freeing it from within the loop safely
4759dbae282SGleb Smirnoffwithout interfering with the traversal.
4769dbae282SGleb Smirnoff.Pp
477bff27689SBruce M SimpsonBoth
478bff27689SBruce M Simpson.Fn RB_FOREACH_FROM
479bff27689SBruce M Simpsonand
480bff27689SBruce M Simpson.Fn RB_FOREACH_REVERSE_FROM
481bff27689SBruce M Simpsonmay be used to continue an interrupted traversal
482bff27689SBruce M Simpsonin a forward or reverse direction respectively.
483*639bf7bdSBruce M SimpsonThe head pointer is not required.
484*639bf7bdSBruce M SimpsonThe pointer to the node from where to resume the traversal
485*639bf7bdSBruce M Simpsonshould be passed as their last argument,
486bff27689SBruce M Simpsonand will be overwritten to provide safe traversal.
487bff27689SBruce M Simpson.Pp
48887f5f0ecSDag-Erling SmørgravThe
48987f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY
490309e4b9bSDag-Erling Smørgravmacro should be used to check whether a red-black tree is empty.
49187f5f0ecSDag-Erling Smørgrav.Sh NOTES
49287f5f0ecSDag-Erling SmørgravTrying to free a tree in the following way is a common error:
49387f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
49487f5f0ecSDag-Erling SmørgravSPLAY_FOREACH(var, NAME, head) {
49587f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
49687f5f0ecSDag-Erling Smørgrav	free(var);
49787f5f0ecSDag-Erling Smørgrav}
49887f5f0ecSDag-Erling Smørgravfree(head);
49987f5f0ecSDag-Erling Smørgrav.Ed
50087f5f0ecSDag-Erling Smørgrav.Pp
50187f5f0ecSDag-Erling SmørgravSince
50287f5f0ecSDag-Erling Smørgrav.Va var
503480565d5SRuslan Ermilovis freed, the
50487f5f0ecSDag-Erling Smørgrav.Fn FOREACH
50587f5f0ecSDag-Erling Smørgravmacro refers to a pointer that may have been reallocated already.
50687f5f0ecSDag-Erling SmørgravProper code needs a second variable.
50787f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
50887f5f0ecSDag-Erling Smørgravfor (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
50987f5f0ecSDag-Erling Smørgrav	nxt = SPLAY_NEXT(NAME, head, var);
51087f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
51187f5f0ecSDag-Erling Smørgrav	free(var);
51287f5f0ecSDag-Erling Smørgrav}
51387f5f0ecSDag-Erling Smørgrav.Ed
51487f5f0ecSDag-Erling Smørgrav.Pp
51587f5f0ecSDag-Erling SmørgravBoth
51687f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
51787f5f0ecSDag-Erling Smørgravand
51887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
51987f5f0ecSDag-Erling Smørgravreturn
520480565d5SRuslan Ermilov.Dv NULL
52187f5f0ecSDag-Erling Smørgravif the element was inserted in the tree successfully, otherwise they
52287f5f0ecSDag-Erling Smørgravreturn a pointer to the element with the colliding key.
52387f5f0ecSDag-Erling Smørgrav.Pp
52487f5f0ecSDag-Erling SmørgravAccordingly,
52587f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
52687f5f0ecSDag-Erling Smørgravand
52787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
52887f5f0ecSDag-Erling Smørgravreturn the pointer to the removed element otherwise they return
529480565d5SRuslan Ermilov.Dv NULL
53087f5f0ecSDag-Erling Smørgravto indicate an error.
531b9ec8f3bSSimon L. B. Nielsen.Sh SEE ALSO
532b9ec8f3bSSimon L. B. Nielsen.Xr queue 3
53387f5f0ecSDag-Erling Smørgrav.Sh AUTHORS
534480565d5SRuslan ErmilovThe author of the tree macros is
535480565d5SRuslan Ermilov.An Niels Provos .
536