summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/tsearch.c
diff options
context:
space:
mode:
authorderaadt <>1997-06-13 23:41:37 +0000
committerderaadt <>1997-06-13 23:41:37 +0000
commit737b5724f4dd92147b79a987347fe5278fbfa6ac (patch)
treebccfd6d24168ffe9910ba192aaf5e1928cc5ac7f /src/lib/libc/stdlib/tsearch.c
parentdd2713d24981403d92672e7e2709bd887b9ad7c6 (diff)
downloadopenbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.tar.gz
openbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.tar.bz2
openbsd-737b5724f4dd92147b79a987347fe5278fbfa6ac.zip
PD tsearch as reqd by xpg; by esr
Diffstat (limited to 'src/lib/libc/stdlib/tsearch.c')
-rw-r--r--src/lib/libc/stdlib/tsearch.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..defa8a3006
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,125 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12
13#include <search.h>
14
15typedef struct node_t {
16 char *key;
17 struct node_t *left, *right;
18} node;
19
20/* find or insert datum into search tree */
21void *
22tsearch(vkey, vrootp, compar)
23 const void *vkey; /* key to be located */
24 void **vrootp; /* address of tree root */
25 int (*compar) __P((const void *, const void *));
26{
27 register node *q;
28 char *key = (char *)vkey;
29 node **rootp = (node **)vrootp;
30
31 if (rootp == (struct node_t **)0)
32 return ((void *)0);
33 while (*rootp != (struct node_t *)0) { /* Knuth's T1: */
34 int r;
35
36 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
37 return ((void *)*rootp); /* we found it! */
38 rootp = (r < 0) ?
39 &(*rootp)->left : /* T3: follow left branch */
40 &(*rootp)->right; /* T4: follow right branch */
41 }
42 q = (node *) malloc(sizeof(node)); /* T5: key not found */
43 if (q != (struct node_t *)0) { /* make new node */
44 *rootp = q; /* link new node to old */
45 q->key = key; /* initialize new node */
46 q->left = q->right = (struct node_t *)0;
47 }
48 return ((void *)q);
49}
50
51/* delete node with given key */
52void *
53tdelete(vkey, vrootp, compar)
54 const void *vkey; /* key to be deleted */
55 void **vrootp; /* address of the root of tree */
56 int (*compar) __P((const void *, const void *));
57{
58 node **rootp = (node **)vrootp;
59 char *key = (char *)vkey;
60 node *p;
61 register node *q;
62 register node *r;
63 int cmp;
64
65 if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
66 return ((struct node_t *)0);
67 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
68 p = *rootp;
69 rootp = (cmp < 0) ?
70 &(*rootp)->left : /* follow left branch */
71 &(*rootp)->right; /* follow right branch */
72 if (*rootp == (struct node_t *)0)
73 return ((void *)0); /* key not found */
74 }
75 r = (*rootp)->right; /* D1: */
76 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
77 q = r;
78 else if (r != (struct node_t *)0) { /* Right link is null? */
79 if (r->left == (struct node_t *)0) { /* D2: Find successor */
80 r->left = q;
81 q = r;
82 } else { /* D3: Find (struct node_t *)0 link */
83 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
84 r = q;
85 r->left = q->right;
86 q->left = (*rootp)->left;
87 q->right = (*rootp)->right;
88 }
89 }
90 free((struct node_t *) *rootp); /* D4: Free node */
91 *rootp = q; /* link parent to new node */
92 return(p);
93}
94
95/* Walk the nodes of a tree */
96static void
97trecurse(root, action, level)
98 register node *root; /* Root of the tree to be walked */
99 register void (*action)(); /* Function to be called at each node */
100 register int level;
101{
102 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
103 (*action)(root, leaf, level);
104 else {
105 (*action)(root, preorder, level);
106 if (root->left != (struct node_t *)0)
107 trecurse(root->left, action, level + 1);
108 (*action)(root, postorder, level);
109 if (root->right != (struct node_t *)0)
110 trecurse(root->right, action, level + 1);
111 (*action)(root, endorder, level);
112 }
113}
114
115/* Walk the nodes of a tree */
116void
117twalk(vroot, action)
118 const void *vroot; /* Root of the tree to be walked */
119 void (*action) __P((const void *, VISIT, int));
120{
121 node *root = (node *)vroot;
122
123 if (root != (node *)0 && action != (void(*)())0)
124 trecurse(root, action, 0);
125}