xref: /freebsd/share/man/man3/tree.3 (revision acd3428b7d3e94cef0e1881c868cb4b131d4ff41)
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 January 17, 2006
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_PROTOTYPE_STATIC ,
56.Nm RB_GENERATE ,
57.Nm RB_GENERATE_STATIC ,
58.Nm RB_ENTRY ,
59.Nm RB_HEAD ,
60.Nm RB_INITIALIZER ,
61.Nm RB_ROOT ,
62.Nm RB_EMPTY ,
63.Nm RB_NEXT ,
64.Nm RB_MIN ,
65.Nm RB_MAX ,
66.Nm RB_FIND ,
67.Nm RB_NFIND ,
68.Nm RB_LEFT ,
69.Nm RB_RIGHT ,
70.Nm RB_PARENT ,
71.Nm RB_FOREACH ,
72.Nm RB_INIT ,
73.Nm RB_INSERT ,
74.Nm RB_REMOVE
75.Nd "implementations of splay and red-black trees"
76.Sh SYNOPSIS
77.In sys/tree.h
78.Fn SPLAY_PROTOTYPE NAME TYPE FIELD CMP
79.Fn SPLAY_GENERATE NAME TYPE FIELD CMP
80.Fn SPLAY_ENTRY TYPE
81.Fn SPLAY_HEAD HEADNAME TYPE
82.Ft "struct TYPE *"
83.Fn SPLAY_INITIALIZER "SPLAY_HEAD *head"
84.Fn SPLAY_ROOT "SPLAY_HEAD *head"
85.Ft bool
86.Fn SPLAY_EMPTY "SPLAY_HEAD *head"
87.Ft "struct TYPE *"
88.Fn SPLAY_NEXT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
89.Ft "struct TYPE *"
90.Fn SPLAY_MIN NAME "SPLAY_HEAD *head"
91.Ft "struct TYPE *"
92.Fn SPLAY_MAX NAME "SPLAY_HEAD *head"
93.Ft "struct TYPE *"
94.Fn SPLAY_FIND NAME "SPLAY_HEAD *head" "struct TYPE *elm"
95.Ft "struct TYPE *"
96.Fn SPLAY_LEFT "struct TYPE *elm" "SPLAY_ENTRY NAME"
97.Ft "struct TYPE *"
98.Fn SPLAY_RIGHT "struct TYPE *elm" "SPLAY_ENTRY NAME"
99.Fn SPLAY_FOREACH VARNAME NAME "SPLAY_HEAD *head"
100.Ft void
101.Fn SPLAY_INIT "SPLAY_HEAD *head"
102.Ft "struct TYPE *"
103.Fn SPLAY_INSERT NAME "SPLAY_HEAD *head" "struct TYPE *elm"
104.Ft "struct TYPE *"
105.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
106.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
107.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
108.Fn RB_GENERATE NAME TYPE FIELD CMP
109.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
110.Fn RB_ENTRY TYPE
111.Fn RB_HEAD HEADNAME TYPE
112.Fn RB_INITIALIZER "RB_HEAD *head"
113.Ft "struct TYPE *"
114.Fn RB_ROOT "RB_HEAD *head"
115.Ft "bool"
116.Fn RB_EMPTY "RB_HEAD *head"
117.Ft "struct TYPE *"
118.Fn RB_NEXT NAME "RB_HEAD *head" "struct TYPE *elm"
119.Ft "struct TYPE *"
120.Fn RB_MIN NAME "RB_HEAD *head"
121.Ft "struct TYPE *"
122.Fn RB_MAX NAME "RB_HEAD *head"
123.Ft "struct TYPE *"
124.Fn RB_FIND NAME "RB_HEAD *head" "struct TYPE *elm"
125.Ft "struct TYPE *"
126.Fn RB_NFIND NAME "RB_HEAD *head" "struct TYPE *elm"
127.Ft "struct TYPE *"
128.Fn RB_LEFT "struct TYPE *elm" "RB_ENTRY NAME"
129.Ft "struct TYPE *"
130.Fn RB_RIGHT "struct TYPE *elm" "RB_ENTRY NAME"
131.Ft "struct TYPE *"
132.Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME"
133.Fn RB_FOREACH 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.Vt SPLAY_ENTRY ,
148or
149.Vt 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.Fn SPLAY_PROTOTYPE ,
165.Fn RB_PROTOTYPE ,
166or
167.Fn RB_PROTOTYPE_STATIC .
168The function bodies are generated with
169.Fn SPLAY_GENERATE ,
170.Fn RB_GENERATE ,
171or
172.Fn 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
178node to the root of the tree and partly rebalances 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
185.Ar m
186operations and
187.Ar n
188inserts on an initially empty tree as
189.Fn O "\*[lp]m + n\*[rp]lg n" .
190The
191amortized cost for a sequence of
192.Ar m
193accesses to a splay tree is
194.Fn O "lg n" .
195.Pp
196A splay tree is headed by a structure defined by the
197.Fn SPLAY_HEAD
198macro.
199A
200structure is declared as follows:
201.Bd -ragged -offset indent
202.Fn SPLAY_HEAD HEADNAME TYPE
203.Va head ;
204.Ed
205.Pp
206where
207.Fa HEADNAME
208is the name of the structure to be defined, and struct
209.Fa TYPE
210is the type of the elements to be inserted into the tree.
211.Pp
212The
213.Fn SPLAY_ENTRY
214macro declares a structure that allows elements to be connected in the tree.
215.Pp
216In order to use the functions that manipulate the tree structure,
217their prototypes need to be declared with the
218.Fn SPLAY_PROTOTYPE
219macro,
220where
221.Fa NAME
222is a unique identifier for this particular tree.
223The
224.Fa TYPE
225argument is the type of the structure that is being managed
226by the tree.
227The
228.Fa FIELD
229argument is the name of the element defined by
230.Fn SPLAY_ENTRY .
231.Pp
232The function bodies are generated with the
233.Fn SPLAY_GENERATE
234macro.
235It takes the same arguments as the
236.Fn SPLAY_PROTOTYPE
237macro, but should be used only once.
238.Pp
239Finally,
240the
241.Fa CMP
242argument is the name of a function used to compare tree nodes
243with each other.
244The function takes two arguments of type
245.Vt "struct TYPE *" .
246If the first argument is smaller than the second, the function returns a
247value smaller than zero.
248If they are equal, the function returns zero.
249Otherwise, it should return a value greater than zero.
250The compare
251function defines the order of the tree elements.
252.Pp
253The
254.Fn SPLAY_INIT
255macro initializes the tree referenced by
256.Fa head .
257.Pp
258The splay tree can also be initialized statically by using the
259.Fn SPLAY_INITIALIZER
260macro like this:
261.Bd -ragged -offset indent
262.Fn SPLAY_HEAD HEADNAME TYPE
263.Va head
264=
265.Fn SPLAY_INITIALIZER &head ;
266.Ed
267.Pp
268The
269.Fn SPLAY_INSERT
270macro inserts the new element
271.Fa elm
272into the tree.
273.Pp
274The
275.Fn SPLAY_REMOVE
276macro removes the element
277.Fa elm
278from the tree pointed by
279.Fa head .
280.Pp
281The
282.Fn SPLAY_FIND
283macro can be used to find a particular element in the tree.
284.Bd -literal -offset indent
285struct TYPE find, *res;
286find.key = 30;
287res = SPLAY_FIND(NAME, head, &find);
288.Ed
289.Pp
290The
291.Fn SPLAY_ROOT ,
292.Fn SPLAY_MIN ,
293.Fn SPLAY_MAX ,
294and
295.Fn SPLAY_NEXT
296macros can be used to traverse the tree:
297.Bd -literal -offset indent
298for (np = SPLAY_MIN(NAME, &head); np != NULL; np = SPLAY_NEXT(NAME, &head, np))
299.Ed
300.Pp
301Or, for simplicity, one can use the
302.Fn SPLAY_FOREACH
303macro:
304.Bd -ragged -offset indent
305.Fn SPLAY_FOREACH np NAME head
306.Ed
307.Pp
308The
309.Fn SPLAY_EMPTY
310macro should be used to check whether a splay tree is empty.
311.Sh RED-BLACK TREES
312A red-black tree is a binary search tree with the node color as an
313extra attribute.
314It fulfills a set of conditions:
315.Bl -enum -offset indent
316.It
317Every search path from the root to a leaf consists of the same number of
318black nodes.
319.It
320Each red node (except for the root) has a black parent.
321.It
322Each leaf node is black.
323.El
324.Pp
325Every operation on a red-black tree is bounded as
326.Fn O "lg n" .
327The maximum height of a red-black tree is
328.Fn 2lg "n + 1" .
329.Pp
330A red-black tree is headed by a structure defined by the
331.Fn RB_HEAD
332macro.
333A
334structure is declared as follows:
335.Bd -ragged -offset indent
336.Fn RB_HEAD HEADNAME TYPE
337.Va head ;
338.Ed
339.Pp
340where
341.Fa HEADNAME
342is the name of the structure to be defined, and struct
343.Fa TYPE
344is the type of the elements to be inserted into the tree.
345.Pp
346The
347.Fn RB_ENTRY
348macro declares a structure that allows elements to be connected in the tree.
349.Pp
350In order to use the functions that manipulate the tree structure,
351their prototypes need to be declared with the
352.Fn RB_PROTOTYPE
353or
354.Fn RB_PROTOTYPE_STATIC
355macro,
356where
357.Fa NAME
358is a unique identifier for this particular tree.
359The
360.Fa TYPE
361argument is the type of the structure that is being managed
362by the tree.
363The
364.Fa FIELD
365argument is the name of the element defined by
366.Fn RB_ENTRY .
367.Pp
368The function bodies are generated with the
369.Fn RB_GENERATE
370or
371.Fn RB_GENERATE_STATIC
372macro.
373These macros take the same arguments as the
374.Fn RB_PROTOTYPE
375and
376.Fn RB_PROTOTYPE_STATIC
377macros, but should be used only once.
378.Pp
379Finally,
380the
381.Fa CMP
382argument is the name of a function used to compare tree noded
383with each other.
384The function takes two arguments of type
385.Vt "struct TYPE *" .
386If the first argument is smaller than the second, the function returns a
387value smaller than zero.
388If they are equal, the function returns zero.
389Otherwise, it should return a value greater than zero.
390The compare
391function defines the order of the tree elements.
392.Pp
393The
394.Fn RB_INIT
395macro initializes the tree referenced by
396.Fa head .
397.Pp
398The red-black tree can also be initialized statically by using the
399.Fn RB_INITIALIZER
400macro like this:
401.Bd -ragged -offset indent
402.Fn RB_HEAD HEADNAME TYPE
403.Va head
404=
405.Fn RB_INITIALIZER &head ;
406.Ed
407.Pp
408The
409.Fn RB_INSERT
410macro inserts the new element
411.Fa elm
412into the tree.
413.Pp
414The
415.Fn RB_REMOVE
416macro removes the element
417.Fa elm
418from the tree pointed by
419.Fa head .
420.Pp
421The
422.Fn RB_FIND
423and
424.Fn RB_NFIND
425macros can be used to find a particular element in the tree.
426.Bd -literal -offset indent
427struct TYPE find, *res;
428find.key = 30;
429res = RB_FIND(NAME, head, &find);
430.Ed
431.Pp
432The
433.Fn RB_ROOT ,
434.Fn RB_MIN ,
435.Fn RB_MAX ,
436and
437.Fn RB_NEXT
438macros can be used to traverse the tree:
439.Pp
440.Dl "for (np = RB_MIN(NAME, &head); np != NULL; np = RB_NEXT(NAME, &head, np))"
441.Pp
442Or, for simplicity, one can use the
443.Fn RB_FOREACH
444macro:
445.Bd -ragged -offset indent
446.Fn RB_FOREACH np NAME head
447.Ed
448.Pp
449The
450.Fn RB_EMPTY
451macro should be used to check whether a red-black tree is empty.
452.Sh NOTES
453Trying to free a tree in the following way is a common error:
454.Bd -literal -offset indent
455SPLAY_FOREACH(var, NAME, head) {
456	SPLAY_REMOVE(NAME, head, var);
457	free(var);
458}
459free(head);
460.Ed
461.Pp
462Since
463.Va var
464is freed, the
465.Fn FOREACH
466macro refers to a pointer that may have been reallocated already.
467Proper code needs a second variable.
468.Bd -literal -offset indent
469for (var = SPLAY_MIN(NAME, head); var != NULL; var = nxt) {
470	nxt = SPLAY_NEXT(NAME, head, var);
471	SPLAY_REMOVE(NAME, head, var);
472	free(var);
473}
474.Ed
475.Pp
476Both
477.Fn RB_INSERT
478and
479.Fn SPLAY_INSERT
480return
481.Dv NULL
482if the element was inserted in the tree successfully, otherwise they
483return a pointer to the element with the colliding key.
484.Pp
485Accordingly,
486.Fn RB_REMOVE
487and
488.Fn SPLAY_REMOVE
489return the pointer to the removed element otherwise they return
490.Dv NULL
491to indicate an error.
492.Sh AUTHORS
493The author of the tree macros is
494.An Niels Provos .
495