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