xref: /freebsd/lib/libc/stdlib/tsearch.3 (revision e2afbc45258f2fa4bdcf126e959ac660e76fc802)
1.\" $NetBSD$
2.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may not be used to endorse or promote products
14.\"    derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
19.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26.\"
27.\"	OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp
28.\"
29.Dd June 4, 2017
30.Dt TSEARCH 3
31.Os
32.Sh NAME
33.Nm tsearch , tfind , tdelete , twalk
34.Nd manipulate binary search trees
35.Sh SYNOPSIS
36.In search.h
37.Ft void *
38.Fn tdelete "const void * restrict key" "posix_tnode ** restrict rootp" "int (*compar) (const void *, const void *)"
39.Fn tdestroy "posix_tnode *root" "(void (*node_free)(void *)"
40.Ft posix_tnode *
41.Fn tfind "const void *key" "posix_tnode * const *rootp" "int (*compar) (const void *, const void *)"
42.Ft posix_tnode *
43.Fn tsearch "const void *key" "posix_tnode **rootp" "int (*compar) (const void *, const void *)"
44.Ft void
45.Fn twalk "const posix_tnode *root" "void (*action) (const posix_tnode *, VISIT, int)"
46.Sh DESCRIPTION
47The
48.Fn tdelete ,
49.Fn tdestroy ,
50.Fn tfind ,
51.Fn tsearch ,
52and
53.Fn twalk
54functions manage binary search trees.
55This implementation uses a balanced AVL tree,
56which due to its strong theoretical limit on the height of the tree has
57the advantage of calling the comparison function relatively
58infrequently.
59.Pp
60The comparison function passed in by
61the user has the same style of return values as
62.Xr strcmp 3 .
63.Pp
64The
65.Fn tfind
66function
67searches for the datum matched by the argument
68.Fa key
69in the binary tree rooted at
70.Fa rootp ,
71returning a pointer to the datum if it is found and NULL
72if it is not.
73.Pp
74The
75.Fn tsearch
76function
77is identical to
78.Fn tfind
79except that if no match is found,
80.Fa key
81is inserted into the tree and a pointer to it is returned.
82If
83.Fa rootp
84points to a NULL value a new binary search tree is created.
85.Pp
86The
87.Fn tdelete
88function
89deletes a node from the specified binary search tree and returns
90a pointer to the parent of the node to be deleted.
91It takes the same arguments as
92.Fn tfind
93and
94.Fn tsearch .
95If the node to be deleted is the root of the binary search tree,
96.Fa rootp
97will be adjusted.
98.Pp
99The
100.Fn tdestroy
101function destroys the whole search tree, freeing all allocated nodes.
102If tree keys need special handling on free, the
103.Fa node_free
104function can be provided, which is called on each key.
105.Pp
106The
107.Fn twalk
108function
109walks the binary search tree rooted in
110.Fa root
111and calls the function
112.Fa action
113on each node.
114The
115.Fa action
116function
117is called with three arguments: a pointer to the current node,
118a value from the enum
119.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
120specifying the traversal type, and a node level (where level
121zero is the root of the tree).
122.Sh RETURN VALUES
123The
124.Fn tsearch
125function returns NULL if allocation of a new node fails (usually
126due to a lack of free memory).
127.Pp
128The
129.Fn tfind ,
130.Fn tsearch ,
131and
132.Fn tdelete
133functions
134return NULL if
135.Fa rootp
136is NULL or the datum cannot be found.
137.Pp
138The
139.Fn twalk
140and
141.Fn tdestroy
142functions return no value.
143.Sh EXAMPLES
144This example uses
145.Fn tsearch
146to search for four strings in
147.Dv root .
148Because the strings are not already present, they are added.
149.Fn tsearch
150is called twice on the fourth string to demonstrate that a string is not added when it is already present.
151.Fn tfind
152is used to find the single instance of the fourth string, and
153.Fn tdelete
154removes it.
155Finally,
156.Fn twalk
157is used to return and display the resulting binary search tree.
158.Bd -literal
159#include <stdio.h>
160#include <search.h>
161#include <string.h>
162
163int
164comp(const void *a, const void *b)
165{
166
167	return strcmp(a, b);
168}
169
170void
171printwalk(const posix_tnode * node, VISIT v, int __unused0)
172{
173
174	if (v == postorder || v == leaf) {
175		printf("node: %s\en", *(char **)node);
176	}
177}
178
179int
180main(void)
181{
182	posix_tnode *root = NULL;
183
184	char one[] = "blah1";
185	char two[] = "blah-2";
186	char three[] = "blah-3";
187	char four[] = "blah-4";
188
189	tsearch(one, &root, comp);
190	tsearch(two, &root, comp);
191	tsearch(three, &root, comp);
192	tsearch(four, &root, comp);
193	tsearch(four, &root, comp);
194	printf("four: %s\en", *(char **)tfind(four, &root, comp));
195	tdelete(four, &root, comp);
196
197	twalk(root, printwalk);
198	tdestroy(root, NULL);
199	return 0;
200}
201.Ed
202.Sh SEE ALSO
203.Xr bsearch 3 ,
204.Xr hsearch 3 ,
205.Xr lsearch 3
206.Sh STANDARDS
207These
208.Fn tdelete ,
209.Fn tfind ,
210.Fn tsearch ,
211and
212.Fn twalk
213functions conform to
214.St -p1003.1-2008 .
215The
216.Fn tdestroy
217function is the glibc extension.
218.Pp
219The
220.Fa posix_tnode
221type is not part of
222.St -p1003.1-2008 ,
223but is expected to be standardized by future versions of the standard.
224It is defined as
225.Fa void
226for source-level compatibility.
227Using
228.Fa posix_tnode
229makes distinguishing between nodes and keys easier.
230