1.\" $OpenBSD: tree.3,v 1.16 2008/05/12 17:54:02 millert 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.\" * 15.\" * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16.\" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17.\" * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18.\" * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19.\" * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20.\" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21.\" * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22.\" * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23.\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24.\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25.\" */ 26.Dd $Mdocdate: May 12 2008 $ 27.Dt TREE 3 28.Os 29.Sh NAME 30.Nm SPLAY_PROTOTYPE , 31.Nm SPLAY_GENERATE , 32.Nm SPLAY_ENTRY , 33.Nm SPLAY_HEAD , 34.Nm SPLAY_INITIALIZER , 35.Nm SPLAY_ROOT , 36.Nm SPLAY_EMPTY , 37.Nm SPLAY_NEXT , 38.Nm SPLAY_MIN , 39.Nm SPLAY_MAX , 40.Nm SPLAY_FIND , 41.Nm SPLAY_LEFT , 42.Nm SPLAY_RIGHT , 43.Nm SPLAY_FOREACH , 44.Nm SPLAY_INIT , 45.Nm SPLAY_INSERT , 46.Nm SPLAY_REMOVE , 47.Nm RB_PROTOTYPE , 48.Nm RB_PROTOTYPE_STATIC , 49.Nm RB_GENERATE , 50.Nm RB_GENERATE_STATIC , 51.Nm RB_ENTRY , 52.Nm RB_HEAD , 53.Nm RB_INITIALIZER , 54.Nm RB_ROOT , 55.Nm RB_EMPTY , 56.Nm RB_NEXT , 57.Nm RB_PREV , 58.Nm RB_MIN , 59.Nm RB_MAX , 60.Nm RB_FIND , 61.Nm RB_NFIND , 62.Nm RB_LEFT , 63.Nm RB_RIGHT , 64.Nm RB_PARENT , 65.Nm RB_FOREACH , 66.Nm RB_FOREACH_REVERSE , 67.Nm RB_INIT , 68.Nm RB_INSERT , 69.Nm RB_REMOVE 70.Nd "implementations of splay and red-black trees" 71.Sh SYNOPSIS 72.Fd #include <sys/tree.h> 73.Pp 74.Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP" 75.Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP" 76.Fn SPLAY_ENTRY "TYPE" 77.Fn SPLAY_HEAD "HEADNAME" "TYPE" 78.Ft "struct TYPE *" 79.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head" 80.Fn SPLAY_ROOT "SPLAY_HEAD *head" 81.Ft "int" 82.Fn SPLAY_EMPTY "SPLAY_HEAD *head" 83.Ft "struct TYPE *" 84.Fn SPLAY_NEXT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm" 85.Ft "struct TYPE *" 86.Fn SPLAY_MIN "NAME" "SPLAY_HEAD *head" 87.Ft "struct TYPE *" 88.Fn SPLAY_MAX "NAME" "SPLAY_HEAD *head" 89.Ft "struct TYPE *" 90.Fn SPLAY_FIND "NAME" "SPLAY_HEAD *head" "struct TYPE *elm" 91.Ft "struct TYPE *" 92.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME" 93.Ft "struct TYPE *" 94.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME" 95.Fn SPLAY_FOREACH "VARNAME" "NAME" "SPLAY_HEAD *head" 96.Ft void 97.Fn SPLAY_INIT "SPLAY_HEAD *head" 98.Ft "struct TYPE *" 99.Fn SPLAY_INSERT "NAME" "SPLAY_HEAD *head" "struct TYPE *elm" 100.Ft "struct TYPE *" 101.Fn SPLAY_REMOVE "NAME" "SPLAY_HEAD *head" "struct TYPE *elm" 102.Pp 103.Fn RB_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP" 104.Fn RB_PROTOTYPE_STATIC "NAME" "TYPE" "FIELD" "CMP" 105.Fn RB_GENERATE "NAME" "TYPE" "FIELD" "CMP" 106.Fn RB_GENERATE_STATIC "NAME" "TYPE" "FIELD" "CMP" 107.Fn RB_ENTRY "TYPE" 108.Fn RB_HEAD "HEADNAME" "TYPE" 109.Fn RB_INITIALIZER "RB_HEAD *head" 110.Ft "struct TYPE *" 111.Fn RB_ROOT "RB_HEAD *head" 112.Ft "int" 113.Fn RB_EMPTY "RB_HEAD *head" 114.Ft "struct TYPE *" 115.Fn RB_NEXT "NAME" "RB_HEAD *head" "struct TYPE *elm" 116.Ft "struct TYPE *" 117.Fn RB_PREV "NAME" "RB_HEAD *head" "struct TYPE *elm" 118.Ft "struct TYPE *" 119.Fn RB_MIN "NAME" "RB_HEAD *head" 120.Ft "struct TYPE *" 121.Fn RB_MAX "NAME" "RB_HEAD *head" 122.Ft "struct TYPE *" 123.Fn RB_FIND "NAME" "RB_HEAD *head" "struct TYPE *elm" 124.Ft "struct TYPE *" 125.Fn RB_NFIND "NAME" "RB_HEAD *head" "struct TYPE *elm" 126.Ft "struct TYPE *" 127.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME" 128.Ft "struct TYPE *" 129.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME" 130.Ft "struct TYPE *" 131.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME" 132.Fn RB_FOREACH "VARNAME" "NAME" "RB_HEAD *head" 133.Fn RB_FOREACH_REVERSE "VARNAME" "NAME" "RB_HEAD *head" 134.Ft void 135.Fn RB_INIT "RB_HEAD *head" 136.Ft "struct TYPE *" 137.Fn RB_INSERT "NAME" "RB_HEAD *head" "struct TYPE *elm" 138.Ft "struct TYPE *" 139.Fn RB_REMOVE "NAME" "RB_HEAD *head" "struct TYPE *elm" 140.Sh DESCRIPTION 141These macros define data structures for different types of trees: 142splay trees and red-black trees. 143.Pp 144In the macro definitions, 145.Fa TYPE 146is the name tag of a user defined structure that must contain a field of type 147.Li SPLAY_ENTRY , 148or 149.Li RB_ENTRY , 150named 151.Fa ENTRYNAME . 152The argument 153.Fa HEADNAME 154is the name tag of a user defined structure that must be declared 155using the macros 156.Fn SPLAY_HEAD 157or 158.Fn RB_HEAD . 159The argument 160.Fa NAME 161has to be a unique name prefix for every tree that is defined. 162.Pp 163The function prototypes are declared with 164.Li SPLAY_PROTOTYPE , 165.Li RB_PROTOTYPE , 166or 167.Li RB_PROTOTYPE_STATIC . 168The function bodies are generated with 169.Li SPLAY_GENERATE , 170.Li RB_GENERATE , 171or 172.Li RB_GENERATE_STATIC . 173See the examples below for further explanation of how these macros are used. 174.Sh SPLAY TREES 175A splay tree is a self-organizing data structure. 176Every operation on the tree causes a splay to happen. 177The splay moves the requested node to the root of the tree and partly 178rebalances it. 179.Pp 180This has the benefit that request locality causes faster lookups as 181the requested nodes move to the top of the tree. 182On the other hand, every lookup causes memory writes. 183.Pp 184The Balance Theorem bounds the total access time for m operations 185and n inserts on an initially empty tree as O((m + n)lg n). 186The amortized cost for a sequence of m accesses to a splay tree is O(lg n). 187.Pp 188A splay tree is headed by a structure defined by the 189.Fn SPLAY_HEAD 190macro. 191A 192.Fa SPLAY_HEAD 193structure is declared as follows: 194.Bd -literal -offset indent 195SPLAY_HEAD(HEADNAME, TYPE) head; 196.Ed 197.Pp 198where 199.Fa HEADNAME 200is the name of the structure to be defined, and struct 201.Fa TYPE 202is the type of the elements to be inserted into the tree. 203.Pp 204The 205.Fn SPLAY_ENTRY 206macro declares a structure that allows elements to be connected in the tree. 207.Pp 208In order to use the functions that manipulate the tree structure, 209their prototypes need to be declared with the 210.Fn SPLAY_PROTOTYPE 211macro, 212where 213.Fa NAME 214is a unique identifier for this particular tree. 215The 216.Fa TYPE 217argument is the type of the structure that is being managed 218by the tree. 219The 220.Fa FIELD 221argument is the name of the element defined by 222.Fn SPLAY_ENTRY . 223.Pp 224The function bodies are generated with the 225.Fn SPLAY_GENERATE 226macro. 227It takes the same arguments as the 228.Fn SPLAY_PROTOTYPE 229macro, but should be used only once. 230.Pp 231Finally, 232the 233.Fa CMP 234argument is the name of a function used to compare trees noded 235with each other. 236The function takes two arguments of type 237.Fa "struct TYPE *" . 238If the first argument is smaller than the second, the function returns a 239value smaller than zero. 240If they are equal, the function returns zero. 241Otherwise, it should return a value greater than zero. 242The compare function 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 -literal -offset indent 253SPLAY_HEAD(HEADNAME, TYPE) head = SPLAY_INITIALIZER(&head); 254.Ed 255.Pp 256The 257.Fn SPLAY_INSERT 258macro inserts the new element 259.Fa elm 260into the tree. 261.Pp 262The 263.Fn SPLAY_REMOVE 264macro removes the element 265.Fa elm 266from the tree pointed by 267.Fa head . 268.Pp 269The 270.Fn SPLAY_FIND 271macro can be used to find a particular element in the tree. 272.Bd -literal -offset indent 273struct TYPE find, *res; 274find.key = 30; 275res = SPLAY_FIND(NAME, &head, &find); 276.Ed 277.Pp 278The 279.Fn SPLAY_ROOT , 280.Fn SPLAY_MIN , 281.Fn SPLAY_MAX , 282and 283.Fn SPLAY_NEXT 284macros can be used to traverse the tree: 285.Bd -literal -offset indent 286for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np)) 287.Ed 288.Pp 289Or, for simplicity, one can use the 290.Fn SPLAY_FOREACH 291macro: 292.Bd -literal -offset indent 293SPLAY_FOREACH(np, NAME, &head) 294.Ed 295.Pp 296The 297.Fn SPLAY_EMPTY 298macro should be used to check whether a splay tree is empty. 299.Sh RED-BLACK TREES 300A red-black tree is a binary search tree with the node color as an 301extra attribute. 302It fulfills a set of conditions: 303.Pp 304.Bl -enum -compact -offset indent 305.It 306every search path from the root to a leaf consists of the same number of 307black nodes, 308.It 309each red node (except for the root) has a black parent, 310.It 311each leaf node is black. 312.El 313.Pp 314Every operation on a red-black tree is bounded as O(lg n). 315The maximum height of a red-black tree is 2lg (n+1). 316.Pp 317A red-black tree is headed by a structure defined by the 318.Fn RB_HEAD 319macro. 320A 321.Fa RB_HEAD 322structure is declared as follows: 323.Bd -literal -offset indent 324RB_HEAD(HEADNAME, TYPE) head; 325.Ed 326.Pp 327where 328.Fa HEADNAME 329is the name of the structure to be defined, and struct 330.Fa TYPE 331is the type of the elements to be inserted into the tree. 332.Pp 333The 334.Fn RB_ENTRY 335macro declares a structure that allows elements to be connected in the tree. 336.Pp 337In order to use the functions that manipulate the tree structure, 338their prototypes need to be declared with the 339.Fn RB_PROTOTYPE 340or 341.Fn RB_PROTOTYPE_STATIC 342macros, 343where 344.Fa NAME 345is a unique identifier for this particular tree. 346The 347.Fa TYPE 348argument is the type of the structure that is being managed 349by the tree. 350The 351.Fa FIELD 352argument is the name of the element defined by 353.Fn RB_ENTRY . 354.Pp 355The function bodies are generated with the 356.Fn RB_GENERATE 357or 358.Fn RB_GENERATE_STATIC 359macros. 360These macros take the same arguments as the 361.Fn RB_PROTOTYPE 362and 363.Fn RB_PROTOTYPE_STATIC 364macros, but should be used only once. 365.Pp 366Finally, 367the 368.Fa CMP 369argument is the name of a function used to compare trees noded 370with each other. 371The function takes two arguments of type 372.Fa "struct TYPE *" . 373If the first argument is smaller than the second, the function returns a 374value smaller than zero. 375If they are equal, the function returns zero. 376Otherwise, it should return a value greater than zero. 377The compare function defines the order of the tree elements. 378.Pp 379The 380.Fn RB_INIT 381macro initializes the tree referenced by 382.Fa head . 383.Pp 384The red-black tree can also be initialized statically by using the 385.Fn RB_INITIALIZER 386macro like this: 387.Bd -literal -offset indent 388RB_HEAD(HEADNAME, TYPE) head = RB_INITIALIZER(&head); 389.Ed 390.Pp 391The 392.Fn RB_INSERT 393macro inserts the new element 394.Fa elm 395into the tree. 396.Pp 397The 398.Fn RB_REMOVE 399macro removes the element 400.Fa elm 401from the tree pointed by 402.Fa head . 403.Pp 404The 405.Fn RB_FIND 406and 407.Fn RB_NFIND 408macros 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 , 419.Fn RB_NEXT , 420and 421.Fn RB_PREV 422macros can be used to traverse the tree: 423.Bd -literal -offset indent 424for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np)) 425.Ed 426.Pp 427Or, for simplicity, one can use the 428.Fn RB_FOREACH 429or 430.Fn RB_FOREACH_REVERSE 431macros: 432.Bd -literal -offset indent 433RB_FOREACH(np, NAME, &head) 434.Ed 435.Pp 436The 437.Fn RB_EMPTY 438macro should be used to check whether a red-black tree is empty. 439.Sh EXAMPLES 440The following example demonstrates how to declare a red-black tree 441holding integers. 442Values are inserted into it and the contents of the tree are printed 443in order. 444Lastly, the internal structure of the tree is printed. 445.Bd -literal -offset 3n 446#include <sys/tree.h> 447#include <err.h> 448#include <stdio.h> 449#include <stdlib.h> 450 451struct node { 452 RB_ENTRY(node) entry; 453 int i; 454}; 455 456int 457intcmp(struct node *e1, struct node *e2) 458{ 459 return (e1->i - e2->i); 460} 461 462RB_HEAD(inttree, node) head = RB_INITIALIZER(&head); 463RB_GENERATE(inttree, node, entry, intcmp) 464 465int testdata[] = { 466 20, 16, 17, 13, 3, 6, 1, 8, 2, 4, 10, 19, 5, 9, 12, 15, 18, 467 7, 11, 14 468}; 469 470void 471print_tree(struct node *n) 472{ 473 struct node *left, *right; 474 475 if (n == NULL) { 476 printf("nil"); 477 return; 478 } 479 left = RB_LEFT(n, entry); 480 right = RB_RIGHT(n, entry); 481 if (left == NULL && right == NULL) 482 printf("%d", n->i); 483 else { 484 printf("%d(", n->i); 485 print_tree(left); 486 printf(","); 487 print_tree(right); 488 printf(")"); 489 } 490} 491 492int 493main() 494{ 495 int i; 496 struct node *n; 497 498 for (i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) { 499 if ((n = malloc(sizeof(struct node))) == NULL) 500 err(1, NULL); 501 n->i = testdata[i]; 502 RB_INSERT(inttree, &head, n); 503 } 504 505 RB_FOREACH(n, inttree, &head) { 506 printf("%d\en", n->i); 507 } 508 print_tree(RB_ROOT(&head)); 509 printf("\en"); 510 return (0); 511} 512.Ed 513.Sh NOTES 514Trying to free a tree in the following way is a common error: 515.Bd -literal -offset indent 516SPLAY_FOREACH(var, NAME, &head) { 517 SPLAY_REMOVE(NAME, &head, var); 518 free(var); 519} 520free(head); 521.Ed 522.Pp 523Since 524.Va var 525is free'd, the 526.Fn FOREACH 527macro refers to a pointer that may have been reallocated already. 528Proper code needs a second variable. 529.Bd -literal -offset indent 530for (var = SPLAY_MIN(NAME, &head); var != NULL; var = nxt) { 531 nxt = SPLAY_NEXT(NAME, &head, var); 532 SPLAY_REMOVE(NAME, &head, var); 533 free(var); 534} 535.Ed 536.Pp 537Both 538.Fn RB_INSERT 539and 540.Fn SPLAY_INSERT 541return 542.Va NULL 543if the element was inserted in the tree successfully, otherwise they 544return a pointer to the element with the colliding key. 545.Pp 546Accordingly, 547.Fn RB_REMOVE 548and 549.Fn SPLAY_REMOVE 550return the pointer to the removed element, otherwise they return 551.Va NULL 552to indicate an error. 553.Sh AUTHORS 554The author of the tree macros is Niels Provos. 555