1 /* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 /* Tree search generalized from Knuth (6.2.2) Algorithm T just like
20 the AT&T man page says.
22 The node_t structure is for internal use only, lint doesn't grok it.
24 Written by reading the System V Interface Definition, not the code.
26 Totally public domain. */
32 /* This routine is not very bad. It makes many assumptions about
33 the compiler. It assumes that the first field in the node must be
34 the "key" field, which points to the datum. It is very tricky
45 /* Prototype fpr local function. */
46 static void trecurse
__P ((const void *vroot
, __action_fn_t action
, int level
));
49 /* find or insert datum into search tree.
50 char *key; key to be located
51 node **rootp; address of tree root
52 int (*compar)(); ordering function
55 __tsearch (key
, vrootp
, compar
)
61 node
**rootp
= (node
**) vrootp
;
66 while (*rootp
!= NULL
) /* Knuth's T1: */
70 r
= (*compar
) (key
, (*rootp
)->key
);
72 return *rootp
; /* we found it! */
74 ? &(*rootp
)->left
/* T3: follow left branch */
75 : &(*rootp
)->right
; /* T4: follow right branch */
78 q
= (node
*) malloc (sizeof (node
)); /* T5: key not found */
79 if (q
!= NULL
) /* make new node */
81 *rootp
= q
; /* link new node to old */
82 q
->key
= key
; /* initialize new node */
83 q
->left
= q
->right
= NULL
;
88 weak_alias (__tsearch
, tsearch
)
92 __tfind (key
, vrootp
, compar
)
97 node
**rootp
= (node
**) vrootp
;
102 while (*rootp
!= NULL
) /* Knuth's T1: */
106 r
= (*compar
)(key
, (*rootp
)->key
);
107 if (r
== 0) /* T2: */
108 return *rootp
; /* we found it! */
111 ? &(*rootp
)->left
/* T3: follow left branch */
112 : &(*rootp
)->right
; /* T4: follow right branch */
116 weak_alias (__tfind
, tfind
)
119 /* delete node with given key
120 char *key; key to be deleted
121 node **rootp; address of the root of tree
122 int (*compar)(); comparison function
125 __tdelete (key
, vrootp
, compar
)
128 __compar_fn_t compar
;
134 node
**rootp
= (node
**) vrootp
;
136 if (rootp
== NULL
|| (p
= *rootp
) == NULL
)
139 while ((cmp
= (*compar
) (key
, (*rootp
)->key
)) != 0)
143 ? &(*rootp
)->left
/* follow left branch */
144 : &(*rootp
)->right
; /* follow right branch */
146 return NULL
; /* key not found */
149 r
= (*rootp
)->right
; /* D1: */
151 if (q
== NULL
) /* Left NULL? */
153 else if (r
!= NULL
) /* Right link is NULL? */
155 if (r
->left
== NULL
) /* D2: Find successor */
161 { /* D3: Find (struct node_t *)0 link */
162 for (q
= r
->left
; q
->left
!= NULL
; q
= r
->left
)
165 q
->left
= (*rootp
)->left
;
166 q
->right
= (*rootp
)->right
;
169 free ((struct node_t
*) *rootp
); /* D4: Free node */
170 *rootp
= q
; /* link parent to new node */
173 weak_alias (__tdelete
, tdelete
)
176 /* Walk the nodes of a tree
177 node *root; Root of the tree to be walked
178 void (*action)(); Function to be called at each node
182 trecurse (vroot
, action
, level
)
184 __action_fn_t action
;
187 node
*root
= (node
*) vroot
;
189 if (root
->left
== NULL
&& root
->right
== NULL
)
190 (*action
) (root
, leaf
, level
);
193 (*action
) (root
, preorder
, level
);
194 if (root
->left
!= NULL
)
195 trecurse (root
->left
, action
, level
+ 1);
196 (*action
) (root
, postorder
, level
);
197 if (root
->right
!= NULL
)
198 trecurse (root
->right
, action
, level
+ 1);
199 (*action
) (root
, endorder
, level
);
204 /* void twalk(root, action) Walk the nodes of a tree
205 node *root; Root of the tree to be walked
206 void (*action)(); Function to be called at each node
210 __twalk (vroot
, action
)
212 __action_fn_t action
;
214 const node
*root
= (node
*) vroot
;
216 if (root
!= NULL
&& action
!= NULL
)
217 trecurse (root
, action
, 0);
219 weak_alias (__twalk
, twalk
)