This file contains (part of) the code from "Algorithms in C, Third Edition, Parts 1-4," by Robert Sedgewick, and is covered under the copyright and warranty notices in that book. Permission is granted for this code to be used for educational purposes in association with the text, and for other uses not covered by copyright laws, provided that the following notice is included with the code: "This code is from "Algorithms in C, Third Edition," by Robert Sedgewick, Addison Wesley Longman, 1998." Commercial uses of this code require the explicit written permission of the publisher. Send your request for permission, stating clearly what code you would like to use, and in what specific way, to: aw.cse@aw.com CHAPTER 12. Symbol Tables and BSTs ----- void STinit(int); int STcount(); void STinsert(Item); Item STsearch(Key); void STdelete(Item); Item STselect(int); void STsort(void (*visit)(Item)); ----- #include #include #include "Item.h" #include "ST.h" void main(int argc, char *argv[]) { int N, maxN = atoi(argv[1]), sw = atoi(argv[2]); Key v; Item item; STinit(maxN); for (N = 0; N < maxN; N++) { if (sw) v = ITEMrand(); else if (ITEMscan(&v) == EOF) break; if (STsearch(v) != NULLitem) continue; key(item) = v; STinsert(item); } STsort(ITEMshow); printf("\n"); printf("%d keys ", N); printf("%d distinct keys\n", STcount()); } ----- static Item *st; static int M = maxKey; void STinit(int maxN) { int i; st = malloc((M+1)*sizeof(Item)); for (i = 0; i <= M; i++) st[i] = NULLitem; } int STcount() { int i, N = 0; for (i = 0; i < M; i++) if (st[i] != NULLitem) N++; return N; } void STinsert(Item item) { st[key(item)] = item; } Item STsearch(Key v) { return st[v]; } void STdelete(Item item) { st[key(item)] = NULLitem; } Item STselect(int k) { int i; for (i = 0; i < M; i++) if (st[i] != NULLitem) if (k-- == 0) return st[i]; } void STsort(void (*visit)(Item)) { int i; for (i = 0; i < M; i++) if (st[i] != NULLitem) visit(st[i]); } ----- static Item *st; static int N; void STinit(int maxN) { st = malloc((maxN)*sizeof(Item)); N = 0; } int STcount() { return N; } void STinsert(Item item) { int j = N++; Key v = key(item); while (j>0 && less(v, key(st[j-1]))) { st[j] = st[j-1]; j--; } st[j] = item; } Item STsearch(Key v) { int j; for (j = 0; j < N; j++) { if (eq(v, key(st[j]))) return st[j]; if (less(v, key(st[j]))) break; } return NULLitem; } Item STselect(int k) { return st[k]; } void STsort(void (*visit)(Item)) { int i; for (i = 0; i < N; i++) visit(st[i]); } ----- typedef struct STnode* link; struct STnode { Item item; link next; }; static link head, z; static int N; static link NEW(Item item, link next) { link x = malloc(sizeof *x); x->item = item; x->next = next; return x; } void STinit(int max) { N = 0; head = (z = NEW(NULLitem, NULL)); } int STcount() { return N; } Item searchR(link t, Key v) { if (t == z) return NULLitem; if (eq(key(t->item), v)) return t->item; return searchR(t->next, v); } Item STsearch(Key v) { return searchR(head, v); } void STinsert(Item item) { head = NEW(item, head); N++; } ----- Item search(int l, int r, Key v) { int m = (l+r)/2; if (l > r) return NULLitem; if eq(v, key(st[m])) return st[m]; if (l == r) return NULLitem; if less(v, key(st[m])) return search(l, m-1, v); else return search(m+1, r, v); } Item STsearch(Key v) { return search(0, N-1, v); } ----- #include #include "Item.h" typedef struct STnode* link; struct STnode { Item item; link l, r; int N }; static link head, z; link NEW(Item item, link l, link r, int N) { link x = malloc(sizeof *x); x->item = item; x->l = l; x->r = r; x->N = N; return x; } void STinit() { head = (z = NEW(NULLitem, 0, 0, 0)); } int STcount() { return head->N; } Item searchR(link h, Key v) { Key t = key(h->item); if (h == z) return NULLitem; if eq(v, t) return h->item; if less(v, t) return searchR(h->l, v); else return searchR(h->r, v); } Item STsearch(Key v) { return searchR(head, v); } link insertR(link h, Item item) { Key v = key(item), t = key(h->item); if (h == z) return NEW(item, z, z, 1); if less(v, t) h->l = insertR(h->l, item); else h->r = insertR(h->r, item); (h->N)++; return h; } void STinsert(Item item) { head = insertR(head, item); } ----- void sortR(link h, void (*visit)(Item)) { if (h == z) return; sortR(h->l, visit); visit(h->item); sortR(h->r, visit); } void STsort(void (*visit)(Item)) { sortR(head, visit); } ----- void STinsert(Item item) { Key v = key(item); link p = head, x = p; if (head == NULL) { head = NEW(item, NULL, NULL, 1); return; } while (x != NULL) { p = x; x->N++; x = less(v, key(x->item)) ? x->l : x->r; } x = NEW(item, NULL, NULL, 1); if (less(v, key(p->item))) p->l = x; else p->r = x; } ----- #define null(A) (eq(key(A), key(NULLitem))) static char text[maxN]; main(int argc, char *argv[]) { int i, t, N = 0; char query[maxQ]; char *v; FILE *corpus = fopen(*++argv, "r"); while ((t = getc(corpus)) != EOF) if (N < maxN) text[N++] = t; else break; text[N] = '\0'; STinit(maxN); for (i = 0; i < N; i++) STinsert(&text[i]); while (gets(query) != NULL) if (!null(v = STsearch(query))) printf("%11d %s\n", v-text, query); else printf("(not found) %s\n", query); } ----- link rotR(link h) { link x = h->l; h->l = x->r; x->r = h; return x; } link rotL(link h) { link x = h->r; h->r = x->l; x->l = h; return x; } ----- link insertT(link h, Item item) { Key v = key(item); if (h == z) return NEW(item, z, z, 1); if (less(v, key(h->item))) { h->l = insertT(h->l, item); h = rotR(h); } else { h->r = insertT(h->r, item); h = rotL(h); } return h; } void STinsert(Item item) { head = insertT(head, item); } ----- Item selectR(link h, int k) { int t = h->l->N; if (h == z) return NULLitem; if (t > k) return selectR(h->l, k); if (t < k) return selectR(h->r, k-t-1); return h->item; } Item STselect(int k) { return selectR(head, k); } ----- link partR(link h, int k) { int t = h->l->N; if (t > k ) { h->l = partR(h->l, k); h = rotR(h); } if (t < k ) { h->r = partR(h->r, k-t-1); h = rotL(h); } return h; } ----- link joinLR(link a, link b) { if (b == z) return a; b = partR(b, 0); b->l = a; return b; } link deleteR(link h, Key v) { link x; Key t = key(h->item); if (h == z) return z; if (less(v, t)) h->l = deleteR(h->l, v); if (less(t, v)) h->r = deleteR(h->r, v); if (eq(v, t)) { x = h; h = joinLR(h->l, h->r); free(x); } return h; } void STdelete(Key v) { head = deleteR(head, v); } ----- link STjoin(link a, link b) { if (b == z) return a; if (a == z) return b; b = STinsert(b, a->item); b->l = STjoin(a->l, b->l); b->r = STjoin(a->r, b->r); free(a); return b; } ----- ----------