1TDELETE(3P)                POSIX Programmer's Manual               TDELETE(3P)
2
3
4

PROLOG

6       This  manual  page is part of the POSIX Programmer's Manual.  The Linux
7       implementation of this interface may differ (consult the  corresponding
8       Linux  manual page for details of Linux behavior), or the interface may
9       not be implemented on Linux.
10

NAME

12       tdelete, tfind, tsearch, twalk — manage a binary search tree
13

SYNOPSIS

15       #include <search.h>
16
17       void *tdelete(const void *restrict key, void **restrict rootp,
18           int(*compar)(const void *, const void *));
19       void *tfind(const void *key, void *const *rootp,
20           int(*compar)(const void *, const void *));
21       void *tsearch(const void *key, void **rootp,
22           int (*compar)(const void *, const void *));
23       void twalk(const void *root,
24           void (*action)(const void *, VISIT, int));
25

DESCRIPTION

27       The tdelete(), tfind(), tsearch(),  and  twalk()  functions  manipulate
28       binary search trees. Comparisons are made with a user-supplied routine,
29       the address of which is passed as the compar argument. This routine  is
30       called with two arguments, which are the pointers to the elements being
31       compared. The application shall ensure that the  user-supplied  routine
32       returns an integer less than, equal to, or greater than 0, according to
33       whether the first argument is to be considered less than, equal to,  or
34       greater  than  the  second  argument.  The comparison function need not
35       compare every byte, so arbitrary data may be contained in the  elements
36       in addition to the values being compared.
37
38       The  tsearch()  function shall build and access the tree. The key argu‐
39       ment is a pointer to an element to be accessed or stored. If there is a
40       node in the tree whose element is equal to the value pointed to by key,
41       a pointer to this found node shall be returned.  Otherwise,  the  value
42       pointed to by key shall be inserted (that is, a new node is created and
43       the value of key is copied to this node), and a pointer  to  this  node
44       returned.  Only  pointers  are  copied, so the application shall ensure
45       that the calling routine stores the data. The rootp argument points  to
46       a  variable  that  points  to the root node of the tree. A null pointer
47       value for the variable pointed to by rootp denotes an  empty  tree;  in
48       this  case,  the variable shall be set to point to the node which shall
49       be at the root of the new tree.
50
51       Like tsearch(), tfind() shall search for a node in the tree,  returning
52       a  pointer  to it if found.  However, if it is not found, tfind() shall
53       return a null pointer. The arguments for tfind() are the  same  as  for
54       tsearch().
55
56       The  tdelete()  function shall delete a node from a binary search tree.
57       The arguments are the same as for tsearch().  The variable  pointed  to
58       by rootp shall be changed if the deleted node was the root of the tree.
59       If the deleted node was the root of the tree and had no  children,  the
60       variable  pointed  to  by  rootp  shall  be  set to a null pointer. The
61       tdelete() function shall return a pointer to the parent of the  deleted
62       node,  or  an  unspecified non-null pointer if the deleted node was the
63       root node, or a null pointer if the node is not found.
64
65       If tsearch() adds an element  to  a  tree,  or  tdelete()  successfully
66       deletes  an  element  from  a  tree, the concurrent use of that tree in
67       another thread, or use of pointers  produced  by  a  previous  call  to
68       tfind() or tsearch(), produces undefined results.
69
70       The  twalk()  function  shall  traverse  a binary search tree. The root
71       argument is a pointer to the root node of the  tree  to  be  traversed.
72       (Any  node  in  a  tree  may  be used as the root for a walk below that
73       node.) The argument action is the name of a routine to  be  invoked  at
74       each  node.  This routine is, in turn, called with three arguments. The
75       first argument shall be the address of  the  node  being  visited.  The
76       structure  pointed  to by this argument is unspecified and shall not be
77       modified by the application,  but  it  shall  be  possible  to  cast  a
78       pointer-to-node into a pointer-to-pointer-to-element to access the ele‐
79       ment stored in the node.  The second argument shall be a value from  an
80       enumeration data type:
81
82
83           typedef enum { preorder, postorder, endorder, leaf } VISIT;
84
85       (defined  in  <search.h>), depending on whether this is the first, sec‐
86       ond, or third time that the node  is  visited  (during  a  depth-first,
87       left-to-right  traversal  of  the tree), or whether the node is a leaf.
88       The third argument shall be the level of the node in the tree, with the
89       root being level 0.
90
91       If  the  calling function alters the pointer to the root, the result is
92       undefined.
93
94       If the functions pointed to by action  or  compar  (for  any  of  these
95       binary search functions) change the tree, the results are undefined.
96
97       These functions are thread-safe only as long as multiple threads do not
98       access the same tree.
99

RETURN VALUE

101       If the node is found, both tsearch() and tfind() shall return a pointer
102       to it. If not, tfind() shall return a null pointer, and tsearch() shall
103       return a pointer to the inserted item.
104
105       A null pointer shall be returned by tsearch() if there  is  not  enough
106       space available to create a new node.
107
108       A  null  pointer shall be returned by tdelete(), tfind(), and tsearch()
109       if rootp is a null pointer on entry.
110
111       The tdelete() function shall return a pointer  to  the  parent  of  the
112       deleted  node,  or  an unspecified non-null pointer if the deleted node
113       was the root node, or a null pointer if the node is not found.
114
115       The twalk() function shall not return a value.
116

ERRORS

118       No errors are defined.
119
120       The following sections are informative.
121

EXAMPLES

123       The following code reads in strings and stores structures containing  a
124       pointer  to  each  string  and a count of its length. It then walks the
125       tree, printing out the stored strings and their lengths in alphabetical
126       order.
127
128
129           #include <limits.h>
130           #include <search.h>
131           #include <stdlib.h>
132           #include <string.h>
133           #include <stdio.h>
134
135           struct element {      /* Pointers to these are stored in the tree. */
136               int     count;
137               char    string[];
138           };
139
140           void  *root = NULL;          /* This points to the root. */
141
142           int main(void)
143           {
144               char   str[_POSIX2_LINE_MAX+1];
145               int    length = 0;
146               struct element *elementptr;
147               void   *node;
148               void   print_node(const void *, VISIT, int);
149               int    node_compare(const void *, const void *),
150                      delete_root(const void *, const void *);
151
152               while (fgets(str, sizeof(str), stdin))  {
153                   /* Set element. */
154                   length = strlen(str);
155                   if (str[length-1] == '\n')
156                       str[--length] = '\0';
157                   elementptr = malloc(sizeof(struct element) + length + 1);
158                   strcpy(elementptr->string, str);
159                   elementptr->count = 1;
160                   /* Put element into the tree. */
161                   node = tsearch((void *)elementptr, &root, node_compare);
162                   if (node == NULL) {
163                       fprintf(stderr,
164                               "tsearch: Not enough space available\n");
165                       exit(EXIT_FAILURE);
166                   }
167                   else if (*(struct element **)node != elementptr) {
168                       /* A node containing the element already exists */
169                       (*(struct element **)node)->count++;
170                       free(elementptr);
171                   }
172               }
173               twalk(root, print_node);
174
175               /* Delete all nodes in the tree */
176               while (root != NULL) {
177                   elementptr = *(struct element **)root;
178                   printf("deleting node: string = %s,  count = %d\n",
179                          elementptr->string,
180                          elementptr->count);
181                   tdelete((void *)elementptr, &root, delete_root);
182                   free(elementptr);
183               }
184
185               return 0;
186           }
187
188           /*
189            *  This routine compares two nodes, based on an
190            *  alphabetical ordering of the string field.
191            */
192           int
193           node_compare(const void *node1, const void *node2)
194           {
195               return strcmp(((const struct element *) node1)->string,
196                   ((const struct element *) node2)->string);
197           }
198
199           /*
200            *  This comparison routine can be used with tdelete()
201            *  when explicitly deleting a root node, as no comparison
202            *  is necessary.
203            */
204           int
205           delete_root(const void *node1, const void *node2)
206           {
207               return 0;
208           }
209
210           /*
211            *  This routine prints out a node, the second time
212            *  twalk encounters it or if it is a leaf.
213            */
214           void
215           print_node(const void *ptr, VISIT order, int level)
216           {
217               const struct element *p = *(const struct element **) ptr;
218
219               if (order == postorder || order == leaf)  {
220                   (void) printf("string = %s,  count = %d\n",
221                       p->string, p->count);
222               }
223           }
224

APPLICATION USAGE

226       The  root argument to twalk() is one level of indirection less than the
227       rootp arguments to tdelete() and tsearch().
228
229       There are two nomenclatures used to refer to the order  in  which  tree
230       nodes  are  visited. The twalk() function uses preorder, postorder, and
231       endorder to refer respectively to visiting a node  before  any  of  its
232       children, after its left child and before its right, and after both its
233       children. The alternative nomenclature uses preorder, inorder, and pos‐
234       torder  to  refer to the same visits, which could result in some confu‐
235       sion over the meaning of postorder.
236
237       Since the return value of tdelete() is an unspecified non-null  pointer
238       in  the  case  that the root of the tree has been deleted, applications
239       should only use the return value of tdelete() as indication of  success
240       or failure and should not assume it can be dereferenced. Some implemen‐
241       tations in this case will return a pointer to the new root of the  tree
242       (or  to an empty tree if the deleted root node was the only node in the
243       tree); other implementations return arbitrary non-null pointers.
244

RATIONALE

246       None.
247

FUTURE DIRECTIONS

249       None.
250

SEE ALSO

252       hcreate(), lsearch()
253
254       The Base Definitions volume of POSIX.1‐2017, <search.h>
255
257       Portions of this text are reprinted and reproduced in  electronic  form
258       from  IEEE Std 1003.1-2017, Standard for Information Technology -- Por‐
259       table Operating System Interface (POSIX), The Open Group Base  Specifi‐
260       cations  Issue  7, 2018 Edition, Copyright (C) 2018 by the Institute of
261       Electrical and Electronics Engineers, Inc and The Open Group.   In  the
262       event of any discrepancy between this version and the original IEEE and
263       The Open Group Standard, the original IEEE and The Open Group  Standard
264       is  the  referee document. The original Standard can be obtained online
265       at http://www.opengroup.org/unix/online.html .
266
267       Any typographical or formatting errors that appear  in  this  page  are
268       most likely to have been introduced during the conversion of the source
269       files to man page format. To report such errors,  see  https://www.ker
270       nel.org/doc/man-pages/reporting_bugs.html .
271
272
273
274IEEE/The Open Group                  2017                          TDELETE(3P)
Impressum