1:
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14:
15: #include <search.h>
16: #include <stdlib.h>
17:
18: typedef struct node_t {
19: char *key;
20: struct node_t *left, *right;
21: } node;
22:
23:
24: void *
25: tsearch(const void *vkey, void **vrootp,
26: int (*compar)(const void *, const void *))
27: {
28: node *q;
29: char *key = (char *)vkey;
30: node **rootp = (node **)vrootp;
31:
32: if (rootp == (struct node_t **)0)
33: return ((void *)0);
34: while (*rootp != (struct node_t *)0) {
35: int r;
36:
37: if ((r = (*compar)(key, (*rootp)->key)) == 0)
38: return ((void *)*rootp);
39: rootp = (r < 0) ?
40: &(*rootp)->left :
41: &(*rootp)->right;
42: }
43: q = (node *) malloc(sizeof(node));
44: if (q != (struct node_t *)0) {
45: *rootp = q;
46: q->key = key;
47: q->left = q->right = (struct node_t *)0;
48: }
49: return ((void *)q);
50: }
51:
52:
53: void *
54: tdelete(const void *vkey, void **vrootp,
55: int (*compar)(const void *, const void *))
56: {
57: node **rootp = (node **)vrootp;
58: char *key = (char *)vkey;
59: node *p = (node *)1;
60: node *q;
61: node *r;
62: int cmp;
63:
64: if (rootp == (struct node_t **)0 || *rootp == (struct node_t *)0)
65: return ((struct node_t *)0);
66: while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
67: p = *rootp;
68: rootp = (cmp < 0) ?
69: &(*rootp)->left :
70: &(*rootp)->right;
71: if (*rootp == (struct node_t *)0)
72: return ((void *)0);
73: }
74: r = (*rootp)->right;
75: if ((q = (*rootp)->left) == (struct node_t *)0)
76: q = r;
77: else if (r != (struct node_t *)0) {
78: if (r->left == (struct node_t *)0) {
79: r->left = q;
80: q = r;
81: } else {
82: for (q = r->left; q->left != (struct node_t *)0; q = r->left)
83: r = q;
84: r->left = q->right;
85: q->left = (*rootp)->left;
86: q->right = (*rootp)->right;
87: }
88: }
89: free((struct node_t *) *rootp);
90: *rootp = q;
91: return(p);
92: }
93:
94:
95: static void
96: trecurse(node *root, void (*action)(const void *, VISIT, int), int level)
97: {
98: if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
99: (*action)(root, leaf, level);
100: else {
101: (*action)(root, preorder, level);
102: if (root->left != (struct node_t *)0)
103: trecurse(root->left, action, level + 1);
104: (*action)(root, postorder, level);
105: if (root->right != (struct node_t *)0)
106: trecurse(root->right, action, level + 1);
107: (*action)(root, endorder, level);
108: }
109: }
110:
111:
112: void
113: twalk(const void *vroot, void (*action)(const void *, VISIT, int))
114: {
115: node *root = (node *)vroot;
116:
117: if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
118: trecurse(root, action, 0);
119: }