xref: /openbsd-src/share/man/man3/tree.3 (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
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