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