1.\" $OpenBSD: tree.3,v 1.20 2009/01/28 12:22:48 stsp 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: January 28 2009 $ 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 named 147.Fa FIELD , 148of type 149.Li SPLAY_ENTRY 150or 151.Li RB_ENTRY . 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' nodes 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' nodes 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. 396Upon success, 397.Va NULL 398is returned. 399If a matching element already exists in the tree, the insertion is 400aborted, and a pointer to the existing element is returned. 401.Pp 402The 403.Fn RB_REMOVE 404macro removes the element 405.Fa elm 406from the tree pointed by 407.Fa head . 408.Pp 409The 410.Fn RB_FIND 411and 412.Fn RB_NFIND 413macros can be used to find a particular element in the tree. 414.Fn RB_FIND 415finds the node with the same key as 416.Fa elm . 417.Fn RB_NFIND 418finds the first node greater than or equal to the search key. 419.Bd -literal -offset indent 420struct TYPE find, *res; 421find.key = 30; 422res = RB_FIND(NAME, &head, &find); 423.Ed 424.Pp 425The 426.Fn RB_ROOT , 427.Fn RB_MIN , 428.Fn RB_MAX , 429.Fn RB_NEXT , 430and 431.Fn RB_PREV 432macros can be used to traverse the tree: 433.Bd -literal -offset indent 434for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np)) 435.Ed 436.Pp 437Or, for simplicity, one can use the 438.Fn RB_FOREACH 439or 440.Fn RB_FOREACH_REVERSE 441macros: 442.Bd -literal -offset indent 443RB_FOREACH(np, NAME, &head) 444.Ed 445.Pp 446The 447.Fn RB_EMPTY 448macro should be used to check whether a red-black tree is empty. 449.Sh EXAMPLES 450The following example demonstrates how to declare a red-black tree 451holding integers. 452Values are inserted into it and the contents of the tree are printed 453in order. 454Lastly, the internal structure of the tree is printed. 455.Bd -literal -offset 3n 456#include <sys/tree.h> 457#include <err.h> 458#include <stdio.h> 459#include <stdlib.h> 460 461struct node { 462 RB_ENTRY(node) entry; 463 int i; 464}; 465 466int 467intcmp(struct node *e1, struct node *e2) 468{ 469 return (e1->i < e2->i ? -1 : e1->i > e2->i); 470} 471 472RB_HEAD(inttree, node) head = RB_INITIALIZER(&head); 473RB_GENERATE(inttree, node, entry, intcmp) 474 475int testdata[] = { 476 20, 16, 17, 13, 3, 6, 1, 8, 2, 4, 10, 19, 5, 9, 12, 15, 18, 477 7, 11, 14 478}; 479 480void 481print_tree(struct node *n) 482{ 483 struct node *left, *right; 484 485 if (n == NULL) { 486 printf("nil"); 487 return; 488 } 489 left = RB_LEFT(n, entry); 490 right = RB_RIGHT(n, entry); 491 if (left == NULL && right == NULL) 492 printf("%d", n->i); 493 else { 494 printf("%d(", n->i); 495 print_tree(left); 496 printf(","); 497 print_tree(right); 498 printf(")"); 499 } 500} 501 502int 503main() 504{ 505 int i; 506 struct node *n; 507 508 for (i = 0; i < sizeof(testdata) / sizeof(testdata[0]); i++) { 509 if ((n = malloc(sizeof(struct node))) == NULL) 510 err(1, NULL); 511 n->i = testdata[i]; 512 RB_INSERT(inttree, &head, n); 513 } 514 515 RB_FOREACH(n, inttree, &head) { 516 printf("%d\en", n->i); 517 } 518 print_tree(RB_ROOT(&head)); 519 printf("\en"); 520 return (0); 521} 522.Ed 523.Sh NOTES 524Trying to free a tree in the following way is a common error: 525.Bd -literal -offset indent 526SPLAY_FOREACH(var, NAME, &head) { 527 SPLAY_REMOVE(NAME, &head, var); 528 free(var); 529} 530free(head); 531.Ed 532.Pp 533Since 534.Va var 535is free'd, the 536.Fn FOREACH 537macro refers to a pointer that may have been reallocated already. 538Proper code needs a second variable. 539.Bd -literal -offset indent 540for (var = SPLAY_MIN(NAME, &head); var != NULL; var = nxt) { 541 nxt = SPLAY_NEXT(NAME, &head, var); 542 SPLAY_REMOVE(NAME, &head, var); 543 free(var); 544} 545.Ed 546.Pp 547Both 548.Fn RB_INSERT 549and 550.Fn SPLAY_INSERT 551return 552.Va NULL 553if the element was inserted in the tree successfully, otherwise they 554return a pointer to the element with the colliding key. 555.Pp 556Accordingly, 557.Fn RB_REMOVE 558and 559.Fn SPLAY_REMOVE 560return the pointer to the removed element, otherwise they return 561.Va NULL 562to indicate an error. 563.Sh AUTHORS 564The author of the tree macros is Niels Provos. 565