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