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