xref: /freebsd/share/man/man3/tree.3 (revision 87f5f0ecf917bea90486c43307da3302de502f19)
187f5f0ecSDag-Erling Smørgrav.\"	$OpenBSD: tree.3,v 1.7 2002/06/12 01:09:20 provos Exp $
287f5f0ecSDag-Erling Smørgrav.\"/*
387f5f0ecSDag-Erling Smørgrav.\" * Copyright 2002 Niels Provos <provos@citi.umich.edu>
487f5f0ecSDag-Erling Smørgrav.\" * All rights reserved.
587f5f0ecSDag-Erling Smørgrav.\" *
687f5f0ecSDag-Erling Smørgrav.\" * Redistribution and use in source and binary forms, with or without
787f5f0ecSDag-Erling Smørgrav.\" * modification, are permitted provided that the following conditions
887f5f0ecSDag-Erling Smørgrav.\" * are met:
987f5f0ecSDag-Erling Smørgrav.\" * 1. Redistributions of source code must retain the above copyright
1087f5f0ecSDag-Erling Smørgrav.\" *    notice, this list of conditions and the following disclaimer.
1187f5f0ecSDag-Erling Smørgrav.\" * 2. Redistributions in binary form must reproduce the above copyright
1287f5f0ecSDag-Erling Smørgrav.\" *    notice, this list of conditions and the following disclaimer in the
1387f5f0ecSDag-Erling Smørgrav.\" *    documentation and/or other materials provided with the distribution.
1487f5f0ecSDag-Erling Smørgrav.\" * 3. All advertising materials mentioning features or use of this software
1587f5f0ecSDag-Erling Smørgrav.\" *    must display the following acknowledgement:
1687f5f0ecSDag-Erling Smørgrav.\" *      This product includes software developed by Niels Provos.
1787f5f0ecSDag-Erling Smørgrav.\" * 4. The name of the author may not be used to endorse or promote products
1887f5f0ecSDag-Erling Smørgrav.\" *    derived from this software without specific prior written permission.
1987f5f0ecSDag-Erling Smørgrav.\" *
2087f5f0ecSDag-Erling Smørgrav.\" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2187f5f0ecSDag-Erling Smørgrav.\" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2287f5f0ecSDag-Erling Smørgrav.\" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2387f5f0ecSDag-Erling Smørgrav.\" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2487f5f0ecSDag-Erling Smørgrav.\" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2587f5f0ecSDag-Erling Smørgrav.\" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2687f5f0ecSDag-Erling Smørgrav.\" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2787f5f0ecSDag-Erling Smørgrav.\" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2887f5f0ecSDag-Erling Smørgrav.\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2987f5f0ecSDag-Erling Smørgrav.\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3087f5f0ecSDag-Erling Smørgrav.\" */
3187f5f0ecSDag-Erling Smørgrav.Dd February 24, 2002
3287f5f0ecSDag-Erling Smørgrav.Dt TREE 3
3387f5f0ecSDag-Erling Smørgrav.Os
3487f5f0ecSDag-Erling Smørgrav.Sh NAME
3587f5f0ecSDag-Erling Smørgrav.Nm SPLAY_PROTOTYPE,
3687f5f0ecSDag-Erling Smørgrav.Nm SPLAY_GENERATE,
3787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ENTRY ,
3887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_HEAD ,
3987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INITIALIZER ,
4087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_ROOT ,
4187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_EMPTY ,
4287f5f0ecSDag-Erling Smørgrav.Nm SPLAY_NEXT ,
4387f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MIN ,
4487f5f0ecSDag-Erling Smørgrav.Nm SPLAY_MAX ,
4587f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FIND ,
4687f5f0ecSDag-Erling Smørgrav.Nm SPLAY_LEFT ,
4787f5f0ecSDag-Erling Smørgrav.Nm SPLAY_RIGHT ,
4887f5f0ecSDag-Erling Smørgrav.Nm SPLAY_FOREACH ,
4987f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INIT ,
5087f5f0ecSDag-Erling Smørgrav.Nm SPLAY_INSERT ,
5187f5f0ecSDag-Erling Smørgrav.Nm SPLAY_REMOVE ,
5287f5f0ecSDag-Erling Smørgrav.Nm RB_PROTOTYPE,
5387f5f0ecSDag-Erling Smørgrav.Nm RB_GENERATE,
5487f5f0ecSDag-Erling Smørgrav.Nm RB_ENTRY ,
5587f5f0ecSDag-Erling Smørgrav.Nm RB_HEAD ,
5687f5f0ecSDag-Erling Smørgrav.Nm RB_INITIALIZER ,
5787f5f0ecSDag-Erling Smørgrav.Nm RB_ROOT ,
5887f5f0ecSDag-Erling Smørgrav.Nm RB_EMPTY ,
5987f5f0ecSDag-Erling Smørgrav.Nm RB_NEXT ,
6087f5f0ecSDag-Erling Smørgrav.Nm RB_MIN ,
6187f5f0ecSDag-Erling Smørgrav.Nm RB_MAX ,
6287f5f0ecSDag-Erling Smørgrav.Nm RB_FIND ,
6387f5f0ecSDag-Erling Smørgrav.Nm RB_LEFT ,
6487f5f0ecSDag-Erling Smørgrav.Nm RB_RIGHT ,
6587f5f0ecSDag-Erling Smørgrav.Nm RB_PARENT ,
6687f5f0ecSDag-Erling Smørgrav.Nm RB_FOREACH ,
6787f5f0ecSDag-Erling Smørgrav.Nm RB_INIT ,
6887f5f0ecSDag-Erling Smørgrav.Nm RB_INSERT ,
6987f5f0ecSDag-Erling Smørgrav.Nm RB_REMOVE
7087f5f0ecSDag-Erling Smørgrav.Nd "implementations of splay and red-black trees"
7187f5f0ecSDag-Erling Smørgrav.Sh SYNOPSIS
7287f5f0ecSDag-Erling Smørgrav.Fd #include <sys/tree.h>
7387f5f0ecSDag-Erling Smørgrav.Pp
7487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
7587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP"
7687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY "TYPE"
7787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD "HEADNAME" "TYPE"
7887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
7987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
8087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT "SPLAY_HEAD *head"
8187f5f0ecSDag-Erling Smørgrav.Ft "bool"
8287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
8387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
8487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_NEXT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
8587f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
8687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MIN "NAME" "SPLAY_HEAD *head"
8787f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
8887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MAX "NAME" "SPLAY_HEAD *head"
8987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FIND "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
9187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
9387f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
9587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FOREACH "VARNAME" "NAME" "SPLAY_HEAD *head"
9687f5f0ecSDag-Erling Smørgrav.Ft void
9787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT "SPLAY_HEAD *head"
9887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
9987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
10087f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
10187f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE "NAME" "SPLAY_HEAD *head" "struct TYPE *elm"
10287f5f0ecSDag-Erling Smørgrav.Pp
10387f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP"
10487f5f0ecSDag-Erling Smørgrav.Fn RB_GENERATE "NAME" "TYPE" "FIELD" "CMP"
10587f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY "TYPE"
10687f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD "HEADNAME" "TYPE"
10787f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER "RB_HEAD *head"
10887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
10987f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT "RB_HEAD *head"
11087f5f0ecSDag-Erling Smørgrav.Ft "bool"
11187f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY "RB_HEAD *head"
11287f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
11387f5f0ecSDag-Erling Smørgrav.Fn RB_NEXT "NAME" "RB_HEAD *head" "struct TYPE *elm"
11487f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
11587f5f0ecSDag-Erling Smørgrav.Fn RB_MIN "NAME" "RB_HEAD *head"
11687f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
11787f5f0ecSDag-Erling Smørgrav.Fn RB_MAX "NAME" "RB_HEAD *head"
11887f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
11987f5f0ecSDag-Erling Smørgrav.Fn RB_FIND "NAME" "RB_HEAD *head" "struct TYPE *elm"
12087f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
12187f5f0ecSDag-Erling Smørgrav.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
12287f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
12387f5f0ecSDag-Erling Smørgrav.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
12487f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
12587f5f0ecSDag-Erling Smørgrav.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
12687f5f0ecSDag-Erling Smørgrav.Fn RB_FOREACH "VARNAME" "NAME" "RB_HEAD *head"
12787f5f0ecSDag-Erling Smørgrav.Ft void
12887f5f0ecSDag-Erling Smørgrav.Fn RB_INIT "RB_HEAD *head"
12987f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13087f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT "NAME" "RB_HEAD *head" "struct TYPE *elm"
13187f5f0ecSDag-Erling Smørgrav.Ft "struct TYPE *"
13287f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE "NAME" "RB_HEAD *head" "struct TYPE *elm"
13387f5f0ecSDag-Erling Smørgrav.Sh DESCRIPTION
13487f5f0ecSDag-Erling SmørgravThese macros defines data structures for different types of trees:
13587f5f0ecSDag-Erling Smørgravsplay trees and red-black trees.
13687f5f0ecSDag-Erling Smørgrav.Pp
13787f5f0ecSDag-Erling SmørgravIn the macro definitions,
13887f5f0ecSDag-Erling Smørgrav.Fa TYPE
13987f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must contain a field of type
14087f5f0ecSDag-Erling Smørgrav.Li SPLAY_ENTRY ,
14187f5f0ecSDag-Erling Smørgravor
14287f5f0ecSDag-Erling Smørgrav.Li RB_ENTRY ,
14387f5f0ecSDag-Erling Smørgravnamed
14487f5f0ecSDag-Erling Smørgrav.Fa ENTRYNAME .
14587f5f0ecSDag-Erling SmørgravThe argument
14687f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
14787f5f0ecSDag-Erling Smørgravis the name tag of a user defined structure that must be declared
14887f5f0ecSDag-Erling Smørgravusing the macros
14987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD ,
15087f5f0ecSDag-Erling Smørgravor
15187f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD .
15287f5f0ecSDag-Erling SmørgravThe argument
15387f5f0ecSDag-Erling Smørgrav.Fa NAME
15487f5f0ecSDag-Erling Smørgravhas to be a unique name prefix for every tree that is defined.
15587f5f0ecSDag-Erling Smørgrav.Pp
15687f5f0ecSDag-Erling SmørgravThe function prototypes are declared with either
15787f5f0ecSDag-Erling Smørgrav.Li SPLAY_PROTOTYPE,
15887f5f0ecSDag-Erling Smørgravor
15987f5f0ecSDag-Erling Smørgrav.Li RB_PROTOTYPE .
16087f5f0ecSDag-Erling SmørgravThe function bodies are generated with either
16187f5f0ecSDag-Erling Smørgrav.Li SPLAY_GENERATE,
16287f5f0ecSDag-Erling Smørgravor
16387f5f0ecSDag-Erling Smørgrav.Li RB_GENERATE .
16487f5f0ecSDag-Erling SmørgravSee the examples below for further explanation of how these macros are used.
16587f5f0ecSDag-Erling Smørgrav.Sh SPLAY TREES
16687f5f0ecSDag-Erling SmørgravA splay tree is a self-organizing data structure.  Every operation
16787f5f0ecSDag-Erling Smørgravon the tree causes a splay to happen.  The splay moves the requested
16887f5f0ecSDag-Erling Smørgravnode to the root of the tree and partly rebalances it.
16987f5f0ecSDag-Erling Smørgrav.Pp
17087f5f0ecSDag-Erling SmørgravThis has the benefit that request locality causes faster lookups as
17187f5f0ecSDag-Erling Smørgravthe requested nodes move to the top of the tree.  On the other hand,
17287f5f0ecSDag-Erling Smørgravevery lookup causes memory writes.
17387f5f0ecSDag-Erling Smørgrav.Pp
17487f5f0ecSDag-Erling SmørgravThe Balance Theorem bounds the total access time for m operations
17587f5f0ecSDag-Erling Smørgravand n inserts on an initially empty tree as O((m + n)lg n).  The
17687f5f0ecSDag-Erling Smørgravamortized cost for a sequence of m accesses to a splay tree is O(lg n);
17787f5f0ecSDag-Erling Smørgrav.Pp
17887f5f0ecSDag-Erling SmørgravA splay tree is headed by a structure defined by the
17987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_HEAD
18087f5f0ecSDag-Erling Smørgravmacro.
18187f5f0ecSDag-Erling SmørgravA
18287f5f0ecSDag-Erling Smørgrav.Fa SPLAY_HEAD
18387f5f0ecSDag-Erling Smørgravstructure is declared as follows:
18487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
18587f5f0ecSDag-Erling SmørgravSPLAY_HEAD(HEADNAME, TYPE) head;
18687f5f0ecSDag-Erling Smørgrav.Ed
18787f5f0ecSDag-Erling Smørgrav.Pp
18887f5f0ecSDag-Erling Smørgravwhere
18987f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
19087f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
19187f5f0ecSDag-Erling Smørgrav.Fa TYPE
19287f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
19387f5f0ecSDag-Erling Smørgrav.Pp
19487f5f0ecSDag-Erling SmørgravThe
19587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY
19687f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
19787f5f0ecSDag-Erling Smørgrav.Pp
19887f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
19987f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
20087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
20187f5f0ecSDag-Erling Smørgravmacro,
20287f5f0ecSDag-Erling Smørgravwhere
20387f5f0ecSDag-Erling Smørgrav.Fa NAME
20487f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
20587f5f0ecSDag-Erling SmørgravThe
20687f5f0ecSDag-Erling Smørgrav.Fa TYPE
20787f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
20887f5f0ecSDag-Erling Smørgravby the tree.
20987f5f0ecSDag-Erling SmørgravThe
21087f5f0ecSDag-Erling Smørgrav.Fa FIELD
21187f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
21287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ENTRY .
21387f5f0ecSDag-Erling Smørgrav.Pp
21487f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
21587f5f0ecSDag-Erling Smørgrav.Fn SPLAY_GENERATE
21687f5f0ecSDag-Erling Smørgravmacro. It takes the same arguments as the
21787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_PROTOTYPE
21887f5f0ecSDag-Erling Smørgravmacro, but should be used only once.
21987f5f0ecSDag-Erling Smørgrav.Pp
22087f5f0ecSDag-Erling SmørgravFinally,
22187f5f0ecSDag-Erling Smørgravthe
22287f5f0ecSDag-Erling Smørgrav.Fa CMP
22387f5f0ecSDag-Erling Smørgravargument is the name of a function used to compare tree noded
22487f5f0ecSDag-Erling Smørgravwith each other.  The function takes two arguments of type
22587f5f0ecSDag-Erling Smørgrav.Fa "struct TYPE *" .
22687f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
22787f5f0ecSDag-Erling Smørgravvalue smaller than zero. If they are equal, the function returns zero.
22887f5f0ecSDag-Erling SmørgravOtherwise, it should return a value greater than zero.  The compare
22987f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
23087f5f0ecSDag-Erling Smørgrav.Pp
23187f5f0ecSDag-Erling SmørgravThe
23287f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INIT
23387f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
23487f5f0ecSDag-Erling Smørgrav.Fa head .
23587f5f0ecSDag-Erling Smørgrav.Pp
23687f5f0ecSDag-Erling SmørgravThe splay tree can also be initialized statically by using the
23787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INITIALIZER
23887f5f0ecSDag-Erling Smørgravmacro like this:
23987f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
24087f5f0ecSDag-Erling SmørgravSPLAY_HEAD(HEADNAME, TYPE) head = SPLAY_INITIALIZER(&head);
24187f5f0ecSDag-Erling Smørgrav.Ed
24287f5f0ecSDag-Erling Smørgrav.Pp
24387f5f0ecSDag-Erling SmørgravThe
24487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
24587f5f0ecSDag-Erling Smørgravmacro inserts the new element
24687f5f0ecSDag-Erling Smørgrav.Fa elm
24787f5f0ecSDag-Erling Smørgravinto the tree.
24887f5f0ecSDag-Erling Smørgrav.Pp
24987f5f0ecSDag-Erling SmørgravThe
25087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
25187f5f0ecSDag-Erling Smørgravmacro removes the element
25287f5f0ecSDag-Erling Smørgrav.Fa elm
25387f5f0ecSDag-Erling Smørgravfrom the tree pointed by
25487f5f0ecSDag-Erling Smørgrav.Fa head .
25587f5f0ecSDag-Erling Smørgrav.Pp
25687f5f0ecSDag-Erling SmørgravThe
25787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FIND
25887f5f0ecSDag-Erling Smørgravmacro can be used to find a particular element in the tree.
25987f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
26087f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
26187f5f0ecSDag-Erling Smørgravfind.key = 30;
26287f5f0ecSDag-Erling Smørgravres = SPLAY_FIND(NAME, head, &find);
26387f5f0ecSDag-Erling Smørgrav.Ed
26487f5f0ecSDag-Erling Smørgrav.Pp
26587f5f0ecSDag-Erling SmørgravThe
26687f5f0ecSDag-Erling Smørgrav.Fn SPLAY_ROOT ,
26787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MIN ,
26887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_MAX ,
26987f5f0ecSDag-Erling Smørgravand
27087f5f0ecSDag-Erling Smørgrav.Fn SPLAY_NEXT
27187f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
27287f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
27387f5f0ecSDag-Erling Smørgravfor (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
27487f5f0ecSDag-Erling Smørgrav.Ed
27587f5f0ecSDag-Erling Smørgrav.Pp
27687f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
27787f5f0ecSDag-Erling Smørgrav.Fn SPLAY_FOREACH
27887f5f0ecSDag-Erling Smørgravmacro:
27987f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
28087f5f0ecSDag-Erling SmørgravSPLAY_FOREACH(np, NAME, head)
28187f5f0ecSDag-Erling Smørgrav.Ed
28287f5f0ecSDag-Erling Smørgrav.Pp
28387f5f0ecSDag-Erling SmørgravThe
28487f5f0ecSDag-Erling Smørgrav.Fn SPLAY_EMPTY
28587f5f0ecSDag-Erling Smørgravmacro should be used to check whether a splay tree is empty.
28687f5f0ecSDag-Erling Smørgrav.Pp
28787f5f0ecSDag-Erling Smørgrav.Sh RED-BLACK TREES
28887f5f0ecSDag-Erling SmørgravA red-black tree is a binary search tree with the node color as an
28987f5f0ecSDag-Erling Smørgravextra attribute.  It fulfills a set of conditions:
29087f5f0ecSDag-Erling Smørgrav.Bl -enum -compact -offset indent
29187f5f0ecSDag-Erling Smørgrav.It
29287f5f0ecSDag-Erling Smørgravevery search path from the root to a leaf consists of the same number of
29387f5f0ecSDag-Erling Smørgravblack nodes,
29487f5f0ecSDag-Erling Smørgrav.It
29587f5f0ecSDag-Erling Smørgraveach red node (except for the root) has a black parent,
29687f5f0ecSDag-Erling Smørgrav.It
29787f5f0ecSDag-Erling Smørgraveach leaf node is black.
29887f5f0ecSDag-Erling Smørgrav.El
29987f5f0ecSDag-Erling Smørgrav.Pp
30087f5f0ecSDag-Erling SmørgravEvery operation on a red-black tree is bounded as O(lg n).
30187f5f0ecSDag-Erling SmørgravThe maximum height of a red-black tree is 2lg (n+1).
30287f5f0ecSDag-Erling Smørgrav.Pp
30387f5f0ecSDag-Erling SmørgravA red-black tree is headed by a structure defined by the
30487f5f0ecSDag-Erling Smørgrav.Fn RB_HEAD
30587f5f0ecSDag-Erling Smørgravmacro.
30687f5f0ecSDag-Erling SmørgravA
30787f5f0ecSDag-Erling Smørgrav.Fa RB_HEAD
30887f5f0ecSDag-Erling Smørgravstructure is declared as follows:
30987f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
31087f5f0ecSDag-Erling SmørgravRB_HEAD(HEADNAME, TYPE) head;
31187f5f0ecSDag-Erling Smørgrav.Ed
31287f5f0ecSDag-Erling Smørgrav.Pp
31387f5f0ecSDag-Erling Smørgravwhere
31487f5f0ecSDag-Erling Smørgrav.Fa HEADNAME
31587f5f0ecSDag-Erling Smørgravis the name of the structure to be defined, and struct
31687f5f0ecSDag-Erling Smørgrav.Fa TYPE
31787f5f0ecSDag-Erling Smørgravis the type of the elements to be inserted into the tree.
31887f5f0ecSDag-Erling Smørgrav.Pp
31987f5f0ecSDag-Erling SmørgravThe
32087f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY
32187f5f0ecSDag-Erling Smørgravmacro declares a structure that allows elements to be connected in the tree.
32287f5f0ecSDag-Erling Smørgrav.Pp
32387f5f0ecSDag-Erling SmørgravIn order to use the functions that manipulate the tree structure,
32487f5f0ecSDag-Erling Smørgravtheir prototypes need to be declared with the
32587f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
32687f5f0ecSDag-Erling Smørgravmacro,
32787f5f0ecSDag-Erling Smørgravwhere
32887f5f0ecSDag-Erling Smørgrav.Fa NAME
32987f5f0ecSDag-Erling Smørgravis a unique identifier for this particular tree.
33087f5f0ecSDag-Erling SmørgravThe
33187f5f0ecSDag-Erling Smørgrav.Fa TYPE
33287f5f0ecSDag-Erling Smørgravargument is the type of the structure that is being managed
33387f5f0ecSDag-Erling Smørgravby the tree.
33487f5f0ecSDag-Erling SmørgravThe
33587f5f0ecSDag-Erling Smørgrav.Fa FIELD
33687f5f0ecSDag-Erling Smørgravargument is the name of the element defined by
33787f5f0ecSDag-Erling Smørgrav.Fn RB_ENTRY .
33887f5f0ecSDag-Erling Smørgrav.Pp
33987f5f0ecSDag-Erling SmørgravThe function bodies are generated with the
34087f5f0ecSDag-Erling Smørgrav.Fn RB_GENERATE
34187f5f0ecSDag-Erling Smørgravmacro. It takes the same arguments as the
34287f5f0ecSDag-Erling Smørgrav.Fn RB_PROTOTYPE
34387f5f0ecSDag-Erling Smørgravmacro, but should be used only once.
34487f5f0ecSDag-Erling Smørgrav.Pp
34587f5f0ecSDag-Erling SmørgravFinally,
34687f5f0ecSDag-Erling Smørgravthe
34787f5f0ecSDag-Erling Smørgrav.Fa CMP
34887f5f0ecSDag-Erling Smørgravargument is the name of a function used to compare tree noded
34987f5f0ecSDag-Erling Smørgravwith each other.  The function takes two arguments of type
35087f5f0ecSDag-Erling Smørgrav.Fa "struct TYPE *" .
35187f5f0ecSDag-Erling SmørgravIf the first argument is smaller than the second, the function returns a
35287f5f0ecSDag-Erling Smørgravvalue smaller than zero. If they are equal, the function returns zero.
35387f5f0ecSDag-Erling SmørgravOtherwise, it should return a value greater than zero.  The compare
35487f5f0ecSDag-Erling Smørgravfunction defines the order of the tree elements.
35587f5f0ecSDag-Erling Smørgrav.Pp
35687f5f0ecSDag-Erling SmørgravThe
35787f5f0ecSDag-Erling Smørgrav.Fn RB_INIT
35887f5f0ecSDag-Erling Smørgravmacro initializes the tree referenced by
35987f5f0ecSDag-Erling Smørgrav.Fa head .
36087f5f0ecSDag-Erling Smørgrav.Pp
36187f5f0ecSDag-Erling SmørgravThe redblack tree can also be initialized statically by using the
36287f5f0ecSDag-Erling Smørgrav.Fn RB_INITIALIZER
36387f5f0ecSDag-Erling Smørgravmacro like this:
36487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
36587f5f0ecSDag-Erling SmørgravRB_HEAD(HEADNAME, TYPE) head = RB_INITIALIZER(&head);
36687f5f0ecSDag-Erling Smørgrav.Ed
36787f5f0ecSDag-Erling Smørgrav.Pp
36887f5f0ecSDag-Erling SmørgravThe
36987f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
37087f5f0ecSDag-Erling Smørgravmacro inserts the new element
37187f5f0ecSDag-Erling Smørgrav.Fa elm
37287f5f0ecSDag-Erling Smørgravinto the tree.
37387f5f0ecSDag-Erling Smørgrav.Pp
37487f5f0ecSDag-Erling SmørgravThe
37587f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
37687f5f0ecSDag-Erling Smørgravmacro removes the element
37787f5f0ecSDag-Erling Smørgrav.Fa elm
37887f5f0ecSDag-Erling Smørgravfrom the tree pointed by
37987f5f0ecSDag-Erling Smørgrav.Fa head .
38087f5f0ecSDag-Erling Smørgrav.Pp
38187f5f0ecSDag-Erling SmørgravThe
38287f5f0ecSDag-Erling Smørgrav.Fn RB_FIND
38387f5f0ecSDag-Erling Smørgravmacro can be used to find a particular element in the tree.
38487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
38587f5f0ecSDag-Erling Smørgravstruct TYPE find, *res;
38687f5f0ecSDag-Erling Smørgravfind.key = 30;
38787f5f0ecSDag-Erling Smørgravres = RB_FIND(NAME, head, &find);
38887f5f0ecSDag-Erling Smørgrav.Ed
38987f5f0ecSDag-Erling Smørgrav.Pp
39087f5f0ecSDag-Erling SmørgravThe
39187f5f0ecSDag-Erling Smørgrav.Fn RB_ROOT ,
39287f5f0ecSDag-Erling Smørgrav.Fn RB_MIN ,
39387f5f0ecSDag-Erling Smørgrav.Fn RB_MAX ,
39487f5f0ecSDag-Erling Smørgravand
39587f5f0ecSDag-Erling Smørgrav.Fn RB_NEXT
39687f5f0ecSDag-Erling Smørgravmacros can be used to traverse the tree:
39787f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
39887f5f0ecSDag-Erling Smørgravfor (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))
39987f5f0ecSDag-Erling Smørgrav.Ed
40087f5f0ecSDag-Erling Smørgrav.Pp
40187f5f0ecSDag-Erling SmørgravOr, for simplicity, one can use the
40287f5f0ecSDag-Erling Smørgrav.Fn RB_FOREACH
40387f5f0ecSDag-Erling Smørgravmacro:
40487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
40587f5f0ecSDag-Erling SmørgravRB_FOREACH(np, NAME, head)
40687f5f0ecSDag-Erling Smørgrav.Ed
40787f5f0ecSDag-Erling Smørgrav.Pp
40887f5f0ecSDag-Erling SmørgravThe
40987f5f0ecSDag-Erling Smørgrav.Fn RB_EMPTY
41087f5f0ecSDag-Erling Smørgravmacro should be used to check whether a splay tree is empty.
41187f5f0ecSDag-Erling Smørgrav.Pp
41287f5f0ecSDag-Erling Smørgrav.Sh NOTES
41387f5f0ecSDag-Erling SmørgravTrying to free a tree in the following way is a common error:
41487f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
41587f5f0ecSDag-Erling SmørgravSPLAY_FOREACH(var, NAME, head) {
41687f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
41787f5f0ecSDag-Erling Smørgrav	free(var);
41887f5f0ecSDag-Erling Smørgrav}
41987f5f0ecSDag-Erling Smørgravfree(head);
42087f5f0ecSDag-Erling Smørgrav.Ed
42187f5f0ecSDag-Erling Smørgrav.Pp
42287f5f0ecSDag-Erling SmørgravSince
42387f5f0ecSDag-Erling Smørgrav.Va var
42487f5f0ecSDag-Erling Smørgravis free'd, the
42587f5f0ecSDag-Erling Smørgrav.Fn FOREACH
42687f5f0ecSDag-Erling Smørgravmacro refers to a pointer that may have been reallocated already.
42787f5f0ecSDag-Erling SmørgravProper code needs a second variable.
42887f5f0ecSDag-Erling Smørgrav.Bd -literal -offset indent
42987f5f0ecSDag-Erling Smørgravfor (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
43087f5f0ecSDag-Erling Smørgrav	nxt = SPLAY_NEXT(NAME, head, var);
43187f5f0ecSDag-Erling Smørgrav	SPLAY_REMOVE(NAME, head, var);
43287f5f0ecSDag-Erling Smørgrav	free(var);
43387f5f0ecSDag-Erling Smørgrav}
43487f5f0ecSDag-Erling Smørgrav.Ed
43587f5f0ecSDag-Erling Smørgrav.Pp
43687f5f0ecSDag-Erling SmørgravBoth
43787f5f0ecSDag-Erling Smørgrav.Fn RB_INSERT
43887f5f0ecSDag-Erling Smørgravand
43987f5f0ecSDag-Erling Smørgrav.Fn SPLAY_INSERT
44087f5f0ecSDag-Erling Smørgravreturn
44187f5f0ecSDag-Erling Smørgrav.Va NULL
44287f5f0ecSDag-Erling Smørgravif the element was inserted in the tree successfully, otherwise they
44387f5f0ecSDag-Erling Smørgravreturn a pointer to the element with the colliding key.
44487f5f0ecSDag-Erling Smørgrav.Pp
44587f5f0ecSDag-Erling SmørgravAccordingly,
44687f5f0ecSDag-Erling Smørgrav.Fn RB_REMOVE
44787f5f0ecSDag-Erling Smørgravand
44887f5f0ecSDag-Erling Smørgrav.Fn SPLAY_REMOVE
44987f5f0ecSDag-Erling Smørgravreturn the pointer to the removed element otherwise they return
45087f5f0ecSDag-Erling Smørgrav.Va NULL
45187f5f0ecSDag-Erling Smørgravto indicate an error.
45287f5f0ecSDag-Erling Smørgrav.Sh AUTHORS
45387f5f0ecSDag-Erling SmørgravThe author of the tree macros is Niels Provos.
454