]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man3/tsearch.3
tsearch.3: SYNOPSIS: clarify that twalk_r() requires _GNU_SOURCE
[thirdparty/man-pages.git] / man3 / tsearch.3
CommitLineData
fea681da
MK
1.\" Copyright 1995 by Jim Van Zandt <jrv@vanzandt.mv.com>
2.\"
93015253 3.\" %%%LICENSE_START(VERBATIM)
fea681da
MK
4.\" Permission is granted to make and distribute verbatim copies of this
5.\" manual provided the copyright notice and this permission notice are
6.\" preserved on all copies.
7.\"
8.\" Permission is granted to copy and distribute modified versions of this
9.\" manual under the conditions for verbatim copying, provided that the
10.\" entire resulting derived work is distributed under the terms of a
11.\" permission notice identical to this one.
c13182ef 12.\"
fea681da
MK
13.\" Since the Linux kernel and libraries are constantly changing, this
14.\" manual page may be incorrect or out-of-date. The author(s) assume no
15.\" responsibility for errors or omissions, or for damages resulting from
16.\" the use of the information contained herein. The author(s) may not
17.\" have taken the same level of care in the production of this manual,
18.\" which is licensed free of charge, as they might when working
19.\" professionally.
c13182ef 20.\"
fea681da
MK
21.\" Formatted or processed versions of this manual, if unaccompanied by
22.\" the source, must acknowledge the copyright and authors of this work.
4b72fb64 23.\" %%%LICENSE_END
fea681da 24.\"
09b8afdc 25.TH TSEARCH 3 2018-04-30 "GNU" "Linux Programmer's Manual"
fea681da 26.SH NAME
f119ba87 27tsearch, tfind, tdelete, twalk, tdestroy \- manage a binary search tree
fea681da
MK
28.SH SYNOPSIS
29.nf
30.B #include <search.h>
68e4db0a 31.PP
e4d72064
MK
32.BI "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
33.PP
fea681da 34.BI "void *tsearch(const void *" key ", void **" rootp ,
b9f02710 35.BI " int (*" compar ")(const void *, const void *));"
68e4db0a 36.PP
da9a495e 37.BI "void *tfind(const void *" key ", void *const *" rootp ,
b9f02710 38.BI " int (*" compar ")(const void *, const void *));"
68e4db0a 39.PP
fea681da 40.BI "void *tdelete(const void *" key ", void **" rootp ,
b9f02710 41.BI " int (*" compar ")(const void *, const void *));"
68e4db0a 42.PP
b9f02710 43.BI "void twalk(const void *" root ", void (*" action ")(const void *" nodep ,
06eef09b 44.BI " VISIT " which ", int " depth "));"
7c520948 45.PP
9794feed
MK
46.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
47.B #include <search.h>
48.PP
7c520948
FW
49.BI "void twalk_r(const void *" root ", void (*" action ")(const void *" np ,
50.BI " VISIT " which ", void *" closure "),
fe1a03f9 51.BI " void *" closure );
68e4db0a 52.PP
b9f02710 53.BI "void tdestroy(void *" root ", void (*" free_node ")(void *" nodep ));
fea681da
MK
54.fi
55.SH DESCRIPTION
60a90ecd
MK
56.BR tsearch (),
57.BR tfind (),
58.BR twalk (),
59and
60.BR tdelete ()
61manage a
f119ba87 62binary search tree.
c13182ef 63They are generalized from Knuth (6.2.2) Algorithm T.
fea681da 64The first field in each node of the tree is a pointer to the
c13182ef
MK
65corresponding data item.
66(The calling program must store the actual data.)
d8a86e74 67.I compar
49b759ab 68points to a comparison routine, which takes
c13182ef
MK
69pointers to two items.
70It should return an integer which is negative,
fea681da
MK
71zero, or positive, depending on whether the first item is less than,
72equal to, or greater than the second.
73.PP
60a90ecd
MK
74.BR tsearch ()
75searches the tree for an item.
d8a86e74 76.I key
49b759ab 77points to the item to be searched for.
d8a86e74 78.I rootp
49b759ab 79points to a variable which points to the root of the tree.
c13182ef 80If the tree is empty,
49b759ab 81then the variable that
d8a86e74 82.I rootp
49b759ab 83points to should be set to NULL.
60a90ecd
MK
84If the item is found in the tree, then
85.BR tsearch ()
86returns a pointer
f119ba87
JH
87to the corresponding tree node.
88(In other words,
89.BR tsearch ()
90returns a pointer to a pointer to the data item.)
91If the item is not found, then
60a90ecd
MK
92.BR tsearch ()
93adds it, and returns a
f119ba87 94pointer to the corresponding tree node.
fea681da 95.PP
60a90ecd
MK
96.BR tfind ()
97is like
98.BR tsearch (),
99except that if the item is not
100found, then
101.BR tfind ()
102returns NULL.
fea681da 103.PP
60a90ecd
MK
104.BR tdelete ()
105deletes an item from the tree.
106Its arguments are the same as for
107.BR tsearch ().
fea681da 108.PP
60a90ecd
MK
109.BR twalk ()
110performs depth-first, left-to-right traversal of a binary
be7fff26 111tree.
d8a86e74 112.I root
49b759ab 113points to the starting node for the traversal.
c13182ef 114If that node is not the root, then only part of the tree will be visited.
60a90ecd 115.BR twalk ()
49b759ab 116calls the user function
d8a86e74 117.I action
49b759ab 118each time a node is
fea681da 119visited (that is, three times for an internal node, and once for a
be7fff26 120leaf).
49b759ab
MK
121.IR action ,
122in turn, takes three arguments.
88c76440
MK
123The first argument is a pointer to the node being visited.
124The structure of the node is unspecified,
125but it is possible to cast the pointer to a pointer-to-pointer-to-element
126in order to access the element stored within the node.
127The application must not modify the structure pointed to by this argument.
128The second argument is an integer which
49b759ab
MK
129takes one of the values
130.BR preorder ,
131.BR postorder ,
132or
d8a86e74 133.B endorder
49b759ab 134depending on whether this is the first, second, or
8cbac64a 135third visit to the internal node,
49b759ab 136or the value
d8a86e74 137.B leaf
49b759ab
MK
138if this is the single visit to a leaf node.
139(These symbols are defined in
140.IR <search.h> .)
8cbac64a
MK
141The third argument is the depth of the node;
142the root node has depth zero.
fea681da 143.PP
49b759ab
MK
144(More commonly,
145.BR preorder ,
146.BR postorder ,
147and
d8a86e74 148.B endorder
49b759ab
MK
149are known as
150.BR preorder ,
151.BR inorder ,
152and
153.BR postorder :
fea681da 154before visiting the children, after the first and before the second,
c13182ef 155and after visiting the children.
49b759ab 156Thus, the choice of name
d8a86e74 157.B post\%order
fea681da
MK
158is rather confusing.)
159.PP
7c520948
FW
160.BR twalk_r ()
161is similar to
162.BR twalk (),
fe1a03f9
MK
163but instead of the
164.I depth
165argument, the
7c520948
FW
166.I closure
167argument pointer is passed to each invocation of the action callback,
fe1a03f9
MK
168unchanged.
169This pointer can be used to pass information to and from
170the callback function in a thread-safe fashion, without resorting
7c520948
FW
171to global variables.
172.PP
60a90ecd 173.BR tdestroy ()
49b759ab
MK
174removes the whole tree pointed to by
175.IR root ,
60a90ecd
MK
176freeing all resources allocated by the
177.BR tsearch ()
178function.
49b759ab 179For the data in each tree node the function
d8a86e74 180.I free_node
49b759ab 181is called.
c13182ef 182The pointer to the data is passed as the argument to the function.
49b759ab 183If no such work is necessary,
d8a86e74 184.I free_node
49b759ab 185must point to a function
fea681da 186doing nothing.
47297adb 187.SH RETURN VALUE
60a90ecd 188.BR tsearch ()
f119ba87
JH
189returns a pointer to a matching node in the tree, or to
190the newly added node, or NULL if there was insufficient memory
988db661 191to add the item.
60a90ecd 192.BR tfind ()
f119ba87 193returns a pointer to the node, or
c13182ef 194NULL if no match is found.
f119ba87
JH
195If there are multiple items that match the key,
196the item whose node is returned is unspecified.
fea681da 197.PP
60a90ecd 198.BR tdelete ()
f119ba87 199returns a pointer to the parent of the node deleted, or
35e21ba7 200NULL if the item was not found.
f23ba9ce
JH
201If the deleted node was the root node,
202.BR tdelete ()
203returns a dangling pointer that must not be accessed.
fea681da 204.PP
60a90ecd
MK
205.BR tsearch (),
206.BR tfind (),
207and
208.BR tdelete ()
209also
49b759ab 210return NULL if
d8a86e74 211.I rootp
49b759ab 212was NULL on entry.
7c520948
FW
213.SH VERSIONS
214.BR twalk_r ()
fe1a03f9 215is available in glibc since version 2.30.
216fd9ad
MS
216.SH ATTRIBUTES
217For an explanation of the terms used in this section, see
218.BR attributes (7).
219.TS
220allbox;
221lb lb lb
222l l l.
223Interface Attribute Value
224T{
225.BR tsearch (),
226.BR tfind (),
227.br
228.BR tdelete ()
229T} Thread safety MT-Safe race:rootp
230T{
231.BR twalk ()
232T} Thread safety MT-Safe race:root
233T{
7c520948
FW
234.BR twalk_r ()
235T} Thread safety MT-Safe race:root
236T{
216fd9ad
MS
237.BR tdestroy ()
238T} Thread safety MT-Safe
239.TE
47297adb 240.SH CONFORMING TO
270ac951 241POSIX.1-2001, POSIX.1-2008, SVr4.
7c520948 242The functions
2b2581ee 243.BR tdestroy ()
7c520948
FW
244and
245.BR twalk_r ()
246are GNU extensions.
9ba9cb64 247.SH NOTES
60a90ecd
MK
248.BR twalk ()
249takes a pointer to the root, while the other functions
fea681da
MK
250take a pointer to a variable which points to the root.
251.PP
60a90ecd
MK
252.BR tdelete ()
253frees the memory required for the node in the tree.
fea681da
MK
254The user is responsible for freeing the memory for the corresponding
255data.
256.PP
60a90ecd
MK
257The example program depends on the fact that
258.BR twalk ()
259makes no
fea681da 260further reference to a node after calling the user function with
c13182ef
MK
261argument "endorder" or "leaf".
262This works with the GNU library
44c95a09 263implementation, but is not in the System V documentation.
fea681da
MK
264.SH EXAMPLE
265The following program inserts twelve random numbers into a binary
266tree, where duplicate numbers are collapsed, then prints the numbers
267in order.
bdd915e2
MK
268.PP
269.EX
2390bfe8 270#define _GNU_SOURCE /* Expose declaration of tdestroy() */
b9f02710
MK
271#include <search.h>
272#include <stdlib.h>
273#include <stdio.h>
274#include <time.h>
c13182ef 275
0d89715e 276static void *root = NULL;
c13182ef 277
0d89715e 278static void *
c13182ef 279xmalloc(unsigned n)
b9f02710
MK
280{
281 void *p;
282 p = malloc(n);
c13182ef 283 if (p)
b9f02710 284 return p;
d1a71985 285 fprintf(stderr, "insufficient memory\en");
4c44ffe5 286 exit(EXIT_FAILURE);
b9f02710 287}
c13182ef 288
0d89715e 289static int
c13182ef 290compare(const void *pa, const void *pb)
cf0a9ace 291{
c13182ef 292 if (*(int *) pa < *(int *) pb)
b9f02710
MK
293 return \-1;
294 if (*(int *) pa > *(int *) pb)
295 return 1;
296 return 0;
297}
c13182ef 298
0d89715e 299static void
06eef09b 300action(const void *nodep, VISIT which, int depth)
cf0a9ace 301{
b9f02710 302 int *datap;
c13182ef 303
d4949190 304 switch (which) {
b9f02710
MK
305 case preorder:
306 break;
307 case postorder:
0c535394 308 datap = *(int **) nodep;
d1a71985 309 printf("%6d\en", *datap);
b9f02710
MK
310 break;
311 case endorder:
312 break;
313 case leaf:
314 datap = *(int **) nodep;
d1a71985 315 printf("%6d\en", *datap);
b9f02710 316 break;
fea681da 317 }
b9f02710 318}
c13182ef
MK
319
320int
321main(void)
cf0a9ace 322{
b9f02710
MK
323 int i, *ptr;
324 void *val;
fea681da 325
c13182ef 326 srand(time(NULL));
b9f02710 327 for (i = 0; i < 12; i++) {
13f78d96 328 ptr = xmalloc(sizeof(int));
b9f02710
MK
329 *ptr = rand() & 0xff;
330 val = tsearch((void *) ptr, &root, compare);
c13182ef 331 if (val == NULL)
4c44ffe5 332 exit(EXIT_FAILURE);
3fe44d51 333 else if ((*(int **) val) != ptr)
6fa5dff6 334 free(ptr);
fea681da 335 }
b9f02710 336 twalk(root, action);
6fa5dff6 337 tdestroy(root, free);
5bc8c34c 338 exit(EXIT_SUCCESS);
b9f02710 339}
bdd915e2 340.EE
47297adb 341.SH SEE ALSO
fea681da
MK
342.BR bsearch (3),
343.BR hsearch (3),
344.BR lsearch (3),
0a4f8b7b 345.BR qsort (3)