---------- CHAPTER 1. Introduction ----- #include static const int N = 10000; int main() { int i, p, q, id[N]; for (i = 0; i < N; i++) id[i] = i; while (cin >> p >> q) { int t = id[p]; if (t == id[q]) continue; for (i = 0; i < N; i++) if (id[i] == t) id[i] = id[q]; cout << " " << p << " " << q << endl; } } ----- for (i = p; i != id[i]; i = id[i]) ; for (j = q; j != id[j]; j = id[j]) ; if (i == j) continue; id[i] = j; cout << " " << p << " " << q << endl; ----- #include static const int N = 10000; int main() { int i, j, p, q, id[N], sz[N]; for (i = 0; i < N; i++) { id[i] = i; sz[i] = 1; } while (cin >> p >> q) { for (i = p; i != id[i]; i = id[i]) ; for (j = q; j != id[j]; j = id[j]) ; if (i == j) continue; if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; } else { id[j] = i; sz[i] += sz[j]; } cout << " " << p << " " << q << endl; } } ----- for (i = p; i != id[i]; i = id[i]) id[i] = id[id[i]]; for (j = q; j != id[j]; j = id[j]) id[j] = id[id[j]]; ---------- CHAPTER 2. Principles of Algorithm Analysis ----- int search(int a[], int v, int l, int r) { for (int i = l; i <= r; i++) if (v == a[i]) return i; return -1; } ----- int search(int a[], int v, int l, int r) { while (r >= l) { int m = (l+r)/2; if (v == a[m]) return m; if (v < a[m]) r = m-1; else l = m+1; } return -1; } ---------- CHAPTER 3. Elementary Data Structures ----- #include int lg(int); int main() { for (int N = 1000; N <= 1000000000; N *= 10) cout << lg(N) << " " << N << endl; } int lg(int N) { for (int i = 0; N > 0; i++, N /= 2) ; return i; } ----- #include #include #include typedef int Number; Number randNum() { return rand(); } int main(int argc, char *argv[]) { int N = atoi(argv[1]); float m1 = 0.0, m2 = 0.0; for (int i = 0; i < N; i++) { Number x = randNum(); m1 += ((float) x)/N; m2 += ((float) x*x)/N; } cout << " Avg.: " << m1 << endl; cout << "Std. dev.: " << sqrt(m2-m1*m1) << endl; } ----- struct point { float x; float y; }; float distance(point, point); ----- #include #include "Point.h" float distance(point a, point b) { float dx = a.x - b.x, dy = a.y - b.y; return sqrt(dx*dx + dy*dy); } ----- #include static const int N = 1000; int main() { int i, a[N]; for (i = 2; i < N; i++) a[i] = 1; for (i = 2; i < N; i++) if (a[i]) for (int j = i; j*i < N; j++) a[i*j] = 0; for (i = 2; i < N; i++) if (a[i]) cout << " " << i; cout << endl; } ----- int main(int argc, char *argv[]) { int i, N = atoi(argv[1]); int *a = new int[N]; if (a == 0) { cout << "out of memory" << endl; return 0; } ... ----- #include #include int heads() { return rand() < RAND_MAX/2; } int main(int argc, char *argv[]) { int i, j, cnt; int N = atoi(argv[1]), M = atoi(argv[2]); int *f = new int[N+1]; for (j = 0; j <= N; j++) f[j] = 0; for (i = 0; i < M; i++, f[cnt]++) for (cnt = 0, j = 0; j <= N; j++) if (heads()) cnt++; for (j = 0; j <= N; j++) { if (f[j] == 0) cout << "."; for (i = 0; i < f[j]; i+=10) cout << "*"; cout << endl; } } ----- #include #include #include #include "Point.h" float randFloat() { return 1.0*rand()/RAND_MAX; } int main(int argc, char *argv[]) { float d = atof(argv[2]); int i, cnt = 0, N = atoi(argv[1]); point *a = new point[N]; for (i = 0; i < N; i++) { a[i].x = randFloat(); a[i].y = randFloat(); } for (i = 0; i < N; i++) for (int j = i+1; j < N; j++) if (distance(a[i], a[j]) < d) cnt++; cout << cnt << " pairs within " << d << endl; } ----- #include #include struct node { int item; node* next; node(int x, node* t) { item = x; next = t; } }; typedef node *link; int main(int argc, char *argv[]) { int i, N = atoi(argv[1]), M = atoi(argv[2]); link t = new node(1, 0); t->next = t; link x = t; for (i = 2; i <= N; i++) x = (x->next = new node(i, t)); while (x != x->next) { for (i = 1; i < M; i++) x = x->next; x->next = x->next->next; } cout << x->item << endl; } ----- link reverse(link x) { link t, y = x, r = 0; while (y != 0) { t = y->next; y->next = r; r = y; y = t; } return r; } ----- node heada(0, 0); link a = &heada, t = a; for (int i = 0; i < N; i++) t = (t->next = new node(rand() % 1000, 0)); node headb(0, 0); link u, x, b = &headb; for (t = a->next; t != 0; t = u) { u = t->next; for (x = b; x->next != 0; x = x->next) if (x->next->item > t->item) break; t->next = x->next; x->next = t; } ----- typedef int Item; struct node { Item item; node *next; }; typedef node *link; typedef link Node; void construct(int); Node newNode(int); void deleteNode(Node); void insert(Node, Node); Node remove(Node); Node next(Node); Item item(Node); ----- #include #include #include "list.h" int main(int argc, char *argv[]) { int i, N = atoi(argv[1]), M = atoi(argv[2]); Node t, x; construct(N); for (i = 2, x = newNode(1); i <= N; i++) { t = newNode(i); insert(x, t); x = t; } while (x != next(x)) { for (i = 1; i < M; i++) x = next(x); deleteNode(remove(x)); } cout << item(x) << endl; return 0; } ----- #include #include "list.h" link freelist; void construct(int N) { freelist = new node[N+1]; for (int i = 0; i < N; i++) freelist[i].next = &freelist[i+1]; freelist[N].next = 0; } link newNode(int i) { link x = remove(freelist); x->item = i; x->next = x; return x; } void deleteNode(link x) { insert(freelist, x); } void insert(link x, link t) { t->next = x->next; x->next = t; } link remove(link x) { link t = x->next; x->next = t->next; return t; } link next(link x) { return x->next; } Item item(link x) { return x->item; } ----- #include #include static const int N = 10000; int main(int argc, char *argv[]) { int i; char t; char a[N], *p = argv[1]; for (i = 0; i < N-1; a[i] = t, i++) if (!cin.get(t)) break; a[i] = 0; for (i = 0; a[i] != 0; i++) { int j; for (j = 0; p[j] != 0; j++) if (a[i+j] != p[j]) break; if (p[j] == 0) cout << i << " "; } cout << endl; } ----- int **malloc2d(int r, int c) { int **t = new int*[r]; for (int i = 0; i < r; i++) t[i] = new int[c]; return t; } ----- #include #include #include int compare(const void *i, const void *j) { return strcmp(*(char **)i, *(char **)j); } int main() { const int Nmax = 1000; const int Mmax = 10000; char* a[Nmax]; int N; char buf[Mmax]; int M = 0; for (N = 0; N < Nmax; N++) { a[N] = &buf[M]; if (!(cin >> a[N])) break; M += strlen(a[N])+1; } qsort(a, N, sizeof(char*), compare); for (int i = 0; i < N; i++) cout << a[i] << endl; } ----- #include int main() { int i, j, adj[V][V]; for (i = 0; i < V; i++) for (j = 0; j < V; j++) adj[i][j] = 0; for (i = 0; i < V; i++) adj[i][i] = 1; while (cin >> i >> j) { adj[i][j] = 1; adj[j][i] = 1; } } ----- #include struct node { int v; node* next; node(int x, node* t) { v = x; next = t; } }; typedef node *link; int main() { int i, j; link adj[V]; for (i = 0; i < V; i++) adj[i] = 0; while (cin >> i >> j) { adj[j] = new node(i, adj[j]); adj[i] = new node(j, adj[i]); } } ----- #include #include #include #include "Point.h" struct node { point p; node *next; node(point pt, node* t) { p = pt; next = t; } }; typedef node *link; static link **grid; static int G, cnt = 0; static float d; void gridinsert(float x, float y) { int X = x*G+1; int Y = y*G+1; point p; p.x = x; p.y = y; link s, t = new node(p, grid[X][Y]); for (int i = X-1; i <= X+1; i++) for (int j = Y-1; j <= Y+1; j++) for (s = grid[i][j]; s != 0; s = s->next) if (distance(s->p, t->p) < d) cnt++; grid[X][Y] = t; } int main(int argc, char *argv[]) { int i, N = atoi(argv[1]); d = atof(argv[2]); G = 1/d; grid = malloc2d(G+2, G+2); for (i = 0; i < G+2; i++) for (int j = 0; j < G+2; j++) grid[i][j] = 0; for (i = 0; i < N; i++) gridinsert(randFloat(), randFloat()); cout << cnt << " pairs within " << d << endl; } ----- ---------- CHAPTER 4. Abstract Data Types ----- #include class POINT { private: float x, y; public: POINT() { x = 1.0*rand()/RAND_MAX; y = 1.0*rand()/RAND_MAX; } float distance(POINT a) { float dx = x-a.x, dy = y-a.y; return sqrt(dx*dx + dy*dy); } }; ----- #include #include #include "POINT.cxx" int main(int argc, char *argv[]) { float d = atof(argv[2]); int i, cnt = 0, N = atoi(argv[1]); POINT *a = new POINT[N]; for (i = 0; i < N; i++) for (int j = i+1; j < N; j++) if (a[i].distance(a[j]) < d) cnt++; cout << cnt << " pairs within " << d << endl; } ----- class POINT { private: // Implementation-dependent code public: POINT(); float distance(POINT) const; }; ----- template class STACK { private: // Implementation-dependent code public: STACK(int); int empty() const; void push(Item item); Item pop(); }; ----- #include #include #include "STACK.cxx" int main(int argc, char *argv[]) { char *a = argv[1]; int N = strlen(a); STACK save(N); for (int i = 0; i < N; i++) { if (a[i] == '+') save.push(save.pop() + save.pop()); if (a[i] == '*') save.push(save.pop() * save.pop()); if ((a[i] >= '0') && (a[i] <= '9')) save.push(0); while ((a[i] >= '0') && (a[i] <= '9')) save.push(10*save.pop() + (a[i++]-'0')); } cout << save.pop() << endl; } ----- #include #include #include "STACK.cxx" int main(int argc, char *argv[]) { char *a = argv[1]; int N = strlen(a); STACK ops(N); for (int i = 0; i < N; i++) { if (a[i] == ')') cout << ops.pop() << " "; if ((a[i] == '+') || (a[i] == '*')) ops.push(a[i]); if ((a[i] >= '0') && (a[i] <= '9')) cout << a[i] << " "; } cout << endl; } ----- template class STACK { private: Item *s; int N; public: STACK(int maxN) { s = new Item[maxN]; N = 0; } int empty() const { return N == 0; } void push(Item item) { s[N++] = item; } Item pop() { return s[--N]; } }; ----- template class STACK { private: struct node { Item item; node* next; node(Item x, node* t) { item = x; next = t; } }; typedef node *link; link head; public: STACK(int) { head = 0; } int empty() const { return head == 0; } void push(Item x) { head = new node(x, head); } Item pop() { Item v = head->item; link t = head->next; delete head; head = t; return v; } }; ----- class UF { private: // Implementation-dependent code public: UF(int); int find(int, int); void unite(int, int); }; ----- #include #include #include "UF.cxx" int main(int argc, char *argv[]) { int p, q, N = atoi(argv[1]); UF info(N); while (cin >> p >> q) if (!info.find(p, q)) { info.unite(p, q); cout << " " << p << " " << q << endl; } } ----- class UF { private: int *id, *sz; int find(int x) { while (x != id[x]) x = id[x]; return x; } public: UF(int N) { id = new int[N]; sz = new int[N]; for (int i = 0; i < N; i++) { id[i] = i; sz[i] = 1; } } int find(int p, int q) { return (find(p) == find(q)); } void unite(int p, int q) { int i = find(p), j = find(q); if (i == j) return; if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; } else { id[j] = i; sz[i] += sz[j]; } } }; ----- class uf { public: virtual uf(int) = 0; virtual int find(int, int) = 0; virtual void unite(int, int) = 0; }; ----- template class QUEUE { private: // Implementation-dependent code public: QUEUE(int); int empty(); void put(Item); Item get(); }; ----- template class QUEUE { private: struct node { Item item; node* next; node(Item x) { item = x; next = 0; } }; typedef node *link; link head, tail; public: QUEUE(int) { head = 0; } int empty() const { return head == 0; } void put(Item x) { link t = tail; tail = new node(x); if (head == 0) head = tail; else t->next = tail; } Item get() { Item v = head->item; link t = head->next; delete head; head = t; return v; } }; ----- template class QUEUE { private: Item *q; int N, head, tail; public: QUEUE(int maxN) { q = new Item[maxN+1]; N = maxN+1; head = N; tail = 0; } int empty() const { return head % N == tail; } void put(Item item) { q[tail++] = item; tail = tail % N; } Item get() { head = head % N; return q[head++]; } }; ----- template class STACK { private: Item *s, *t; int N; public: STACK(int maxN) { s = new Item[maxN]; N = 0; t = new Item[maxN]; for (int i = 0; i < maxN; i++) t[i] = 0; } int empty() const { return N == 0; } void push(Item item) { if (t[item] == 1) return; s[N++] = item; t[item] = 1; } Item pop() { t[s[--N]] = 0; return s[N]; } }; ----- #include #include #include #include "COMPLEX.cxx" int main(int argc, char *argv[]) { int N = atoi(argv[1]); cout << N << " complex roots of unity" << endl; for (int k = 0; k < N; k++) { float theta = 2.0*3.14159*k/N; Complex t(cos(theta), sin(theta)), x = t; cout << k << ": " << t << " "; for (int j = 0; j < N-1; j++) x *= t; cout << x << endl; } } ----- class Complex { private: // Implementation-dependent code public: Complex(float, float); float Re() const; float Im() const; Complex& operator*=(Complex&); }; ----- #include class Complex { private: float re, im; public: Complex(float x, float y) { re = x; im = y; } float Re() const { return re; } float Im() const { return im; } Complex& operator*=(const Complex& rhs) { float t = Re(); re = Re()*rhs.Re() - Im()*rhs.Im(); im = t*rhs.Im() + Im()*rhs.Re(); return *this; } }; ostream& operator<<(ostream& t, const Complex& c) { t << c.Re() << " " << c.Im(); return t; } ----- #include #include #include "QUEUE.cxx" static const int M = 4; int main(int argc, char *argv[]) { int N = atoi(argv[1]); QUEUE queues[M]; for (int i = 0; i < N; i++, cout << endl) { int in = rand() % M, out = rand() % M; queues[in].put(i); cout << i << " in "; if (!queues[out].empty()) cout << queues[out].get() << " out"; cout << endl; for (int k = 0; k < M; k++, cout << endl) { QUEUE q = queues[k]; cout << k << ": "; while (!q.empty()) cout << q.get() << " "; } } } ----- template class QUEUE { private: // Implementation-dependent code public: QUEUE(int); QUEUE(const QUEUE&); QUEUE& operator=(const QUEUE&); ~QUEUE(); int empty() const; void put(Item); Item get(); }; ----- private: void deletelist() { for (link t = head; t != 0; head = t) { t = head->next; delete head; } } public: QUEUE(const QUEUE& rhs) { head = 0; *this = rhs; } QUEUE& operator=(const QUEUE& rhs) { if (this == &rhs) return *this; deletelist(); link t = rhs.head; while (t != 0) { put(t->item); t = t->next; } return *this; } ~QUEUE() { deletelist(); } ----- #include #include #include "POLY.cxx" int main(int argc, char *argv[]) { int N = atoi(argv[1]); float p = atof(argv[2]); cout << "Binomial coefficients" << endl; POLY x(1,1), one(1,0), t = x + one, y = t; for (int i = 0; i < N; i++) { y = y*t; cout << y << endl; } cout << y.eval(p) << endl; } ----- template class POLY { private: // Implementation-dependent code public: POLY(Number, int); float eval(float) const; friend POLY operator+(POLY &, POLY &); friend POLY operator*(POLY &, POLY &); }; ----- template class POLY { private: int n; Number *a; public: POLY(Number c, int N) { a = new Number[N+1]; n = N+1; a[N] = c; for (int i = 0; i < N; i++) a[i] = 0; } float eval(float x) const { double t = 0.0; for (int i = n-1; i >= 0; i--) t = t*x + a[i]; return t; } friend POLY operator+(POLY &p, POLY &q) { POLY t(0, p.n>q.n ? p.n-1 : q.n-1); for (int i = 0; i < p.n; i++) t.a[i] += p.a[i]; for (int j = 0; j < q.n; j++) t.a[j] += q.a[j]; return t; } friend POLY operator*(POLY &p, POLY &q) { POLY t(0, (p.n-1)+(q.n-1)); for (int i = 0; i < p.n; i++) for (int j = 0; j < q.n; j++) t.a[i+j] += p.a[i]*q.a[j]; return t; } }; ---------- CHAPTER 5. Recursion and Trees ----- int factorial(int N) { if (N == 0) return 1; return N*factorial(N-1); } ----- int puzzle(int N) { if (N == 1) return 1; if (N % 2 == 0) return puzzle(N/2); else return puzzle(3*N+1); } ----- int gcd(int m, int n) { if (n == 0) return m; return gcd(n, m % n); } ----- char *a; int i; int eval() { int x = 0; while (a[i] == ' ') i++; if (a[i] == '+') { i++; return eval() + eval(); } if (a[i] == '*') { i++; return eval() * eval(); } while ((a[i] >= '0') && (a[i] <= '9')) x = 10*x + (a[i++]-'0'); return x; } ----- int count(link x) { if (x == 0) return 0; return 1 + count(x->next); } void traverse(link h, void visit(link)) { if (h == 0) return; visit(h); traverse(h->next, visit); } void traverseR(link h, void visit(link)) { if (h == 0) return; traverseR(h->next, visit); visit(h); } void remove(link& x, Item v) { while (x != 0 && x->item == v) { link t = x; x = x->next; delete t; } if (x != 0) remove(x->next, v); } ----- Item max(Item a[], int l, int r) { if (l == r) return a[l]; int m = (l+r)/2; Item u = max(a, l, m); Item v = max(a, m+1, r); if (u > v) return u; else return v; } ----- void hanoi(int N, int d) { if (N == 0) return; hanoi(N-1, -d); shift(N, d); hanoi(N-1, -d); } ----- void rule(int l, int r, int h) { int m = (l+r)/2; if (h > 0) { rule(l, m, h-1); mark(m, h); rule(m, r, h-1); } } ----- void rule(int l, int r, int h) { for (int t = 1, j = 1; t <= h; j += j, t++) for (int i = 0; l+j+i <= r; i += j+j) mark(l+j+i, t); } ----- int F(int i) { if (i < 1) return 0; if (i == 1) return 1; return F(i-1) + F(i-2); } ----- int F(int i) { static int knownF[maxN]; if (knownF[i] != 0) return knownF[i]; int t = i; if (i < 0) return 0; if (i > 1) t = F(i-1) + F(i-2); return knownF[i] = t; } ----- int knap(int cap) { int i, space, max, t; for (i = 0, max = 0; i < N; i++) if ((space = cap-items[i].size) >= 0) if ((t = knap(space) + items[i].val) > max) max = t; return max; } ----- int knap(int M) { int i, space, max, maxi = 0, t; if (maxKnown[M] != unknown) return maxKnown[M]; for (i = 0, max = 0; i < N; i++) if ((space = M-items[i].size) >= 0) if ((t = knap(space) + items[i].val) > max) { max = t; maxi = i; } maxKnown[M] = max; itemKnown[M] = items[maxi]; return max; } ----- void traverse(link h, void visit(link)) { if (h == 0) return; visit(h); traverse(h->l, visit); traverse(h->r, visit); } ----- void traverse(link h, void visit(link)) { STACK s(max); s.push(h); while (!s.empty()) { visit(h = s.pop()); if (h->r != 0) s.push(h->r); if (h->l != 0) s.push(h->l); } } ----- void traverse(link h, void visit(link)) { QUEUE q(max); q.put(h); while (!q.empty()) { visit(h = q.get()); if (h->l != 0) q.put(h->l); if (h->r != 0) q.put(h->r); } } ----- int count(link h) { if (h == 0) return 0; return count(h->l) + count(h->r) + 1; } int height(link h) { if (h == 0) return -1; int u = height(h->l), v = height(h->r); if (u > v) return u+1; else return v+1; } ----- void printnode(Item x, int h) { for (int i = 0; i < h; i++) cout << " "; cout << x << endl; } void show(link t, int h) { if (t == 0) { printnode('*', h); return; } show(t->r, h+1); printnode(t->item, h); show(t->l, h+1); } ----- struct node { Item item; node *l, *r; node(Item x) { item = x; l = 0; r = 0; } }; typedef node* link; link max(Item a[], int l, int r) { int m = (l+r)/2; link x = new node(a[m]); if (l == r) return x; x->l = max(a, l, m); x->r = max(a, m+1, r); Item u = x->l->item, v = x->r->item; if (u > v) x->item = u; else x->item = v; return x; } ----- char *a; int i; struct node { Item item; node *l, *r; node(Item x) { item = x; l = 0; r = 0; } }; typedef node* link; link parse() { char t = a[i++]; link x = new node(t); if ((t == '+') || (t == '*')) { x->l = parse(); x->r = parse(); } return x; } ----- void traverse(int k, void visit(int)) { visit(k); visited[k] = 1; for (link t = adj[k]; t != 0; t = t->next) if (!visited[t->v]) traverse(t->v, visit); } ----- void traverse(int k, void visit(int)) { QUEUE q(V*V); q.put(k); while (!q.empty()) if (visited[k = q.get()] == 0) { visit(k); visited[k] = 1; for (link t = adj[k]; t != 0; t = t->next) if (visited[t->v] == 0) q.put(t->v); } } ----- ---------- CHAPTER 6. Elementary Sorting Methods ----- #include #include template void exch(Item &A, Item &B) { Item t = A; A = B; B = t; } template void compexch(Item &A, Item &B) { if (B < A) exch(A, B); } template void sort(Item a[], int l, int r) { for (int i = l+1; i <= r; i++) for (int j = i; j > l; j--) compexch(a[j-1], a[j]); } int main(int argc, char *argv[]) { int i, N = atoi(argv[1]), sw = atoi(argv[2]); int *a = new int[N]; if (sw) for (i = 0; i < N; i++) a[i] = 1000*(1.0*rand()/RAND_MAX); else { N = 0; while (cin >> a[N]) N++; } sort(a, 0, N-1); for (i = 0; i < N; i++) cout << a[i] << " "; cout << endl; } ----- template void selection(Item a[], int l, int r) { for (int i = l; i < r; i++) { int min = i; for (int j = i+1; j <= r; j++) if (a[j] < a[min]) min = j; exch(a[i], a[min]); } } ----- template void insertion(Item a[], int l, int r) { int i; for (i = r; i > l; i--) compexch(a[i-1], a[i]); for (i = l+2; i <= r; i++) { int j = i; Item v = a[i]; while (v < a[j-1]) { a[j] = a[j-1]; j--; } a[j] = v; } } ----- template void bubble(Item a[], int l, int r) { for (int i = l; i < r; i++) for (int j = r; j > i; j--) compexch(a[j-1], a[j]); } ----- template void shellsort(Item a[], int l, int r) { int h; for (h = 1; h <= (r-l)/9; h = 3*h+1) ; for ( ; h > 0; h /= 3) for (int i = l+h; i <= r; i++) { int j = i; Item v = a[i]; while (j >= l+h && v < a[j-h]) { a[j] = a[j-h]; j -= h; } a[j] = v; } } ----- #include #include "Item.h" #include "exch.h" #include "Array.h" main(int argc, char *argv[]) { int N = atoi(argv[1]), sw = atoi(argv[2]); Item *a = new Item[N]; if (sw) rand(a, N); else scan(a, N); sort(a, 0, N-1); show(a, 0, N-1); } ----- template void rand(Item a[], int N); template void scan(Item a[], int &N); template void show(Item a[], int l, int r); template void sort(Item a[], int l, int r); ----- #include #include #include "Array.h" template void rand(Item a[], int N) { for (int i = 0; i < N; i++) rand(a[i]); } template void scan(Item a[], int &N) { for (int i = 0; i < N; i++) if (!scan(a[i])) break; N = i; } template void show(Item a[], int l, int r) { for (int i = l; i <=r; i++) show(a[i]); cout << endl; } ----- typedef struct record { int key; float info; } Item; int operator<(const Item&, const Item&); int scan(Item&); void rand(Item&); void show(const Item&); ----- #include #include #include "Item.h" int operator<(const Item& A, const Item& B) { return A.key < B.key; } int scan(Item& x) { return (cin >> x.key >> x.info) != 0; } void rand(Item& x) { x.key = 1000*(1.0*rand()/RAND_MAX); x.info = 1.0*rand()/RAND_MAX; } void show(const Item& x) { cout << x.key << " " << x.info << endl; } ----- #include #include #include #include "Item.h" static char buf[100000]; static int cnt = 0; int operator<(const Item& a, const Item& b) { return strcmp(a.str, b.str) < 0; } void show(const Item& x) { cout << x.str << " "; } int scan(Item& x) { int flag = (cin >> (x.str = &buf[cnt])) != 0; cnt += strlen(x.str)+1; return flag; } ----- struct record { char name[30]; int num; }; typedef struct { record *r; } Item; int operator<(const Item&, const Item&); void rand(Item&); void show(const Item&); int scan(Item&); ----- static record data[maxN]; static int cnt = 0; void show(const Item& x) { cout << x.r->name << " " << x.r->num << endl; } int scan(Item& x) { x.r = &data[cnt++]; return (cin >> x.r->name >> x.r->num) != 0; } ----- template void insitu(Item data[], Index a[], int N) { for (int i = 0; i < N; i++) { Item v = data[i]; int j, k; for (k = i; a[k] != i; k = a[j], a[j] = j) { j = k; data[k] = data[a[k]]; } data[k] = v; a[k] = k; } } ----- struct node { Item item; node* next; node(Item x) { item = x; next = 0; } }; typedef node *link; link randlist(int); link scanlist(int&); void showlist(link); link sortlist(link); ----- link listselection(link h) { node dummy(0); link head = &dummy, out = 0; head->next = h; while (head->next != 0) { link max = findmax(head), t = max->next; max->next = t->next; t->next = out; out = t; } return out; } ----- void distcount(int a[], int l, int r) { int i, j, cnt[M]; static int b[maxN]; for (j = 0; j < M; j++) cnt[j] = 0; for (i = l; i <= r; i++) cnt[a[i]+1]++; for (j = 1; j < M; j++) cnt[j] += cnt[j-1]; for (i = l; i <= r; i++) b[cnt[a[i]]++] = a[i]; for (i = l; i <= r; i++) a[i] = b[i-l]; } ---------- CHAPTER 7. Quicksort ----- template void quicksort(Item a[], int l, int r) { if (r <= l) return; int i = partition(a, l, r); quicksort(a, l, i-1); quicksort(a, i+1, r); } ----- template int partition(Item a[], int l, int r) { int i = l-1, j = r; Item v = a[r]; for (;;) { while (a[++i] < v) ; while (v < a[--j]) if (j == l) break; if (i >= j) break; exch(a[i], a[j]); } exch(a[i], a[r]); return i; } ----- #include "STACK.cxx" inline void push2(STACK &s, int A, int B) { s.push(B); s.push(A); } template void quicksort(Item a[], int l, int r) { STACK s(50); push2(s, l, r); while (!s.empty()) { l = s.pop(); r = s.pop(); if (r <= l) continue; int i = partition(a, l, r); if (i-l > r-i) { push2(s, l, i-1); push2(s, i+1, r); } else { push2(s, i+1, r); push2(s, l, i-1); } } } ----- static const int M = 10; template void quicksort(Item a[], int l, int r) { if (r-l <= M) return; exch(a[(l+r)/2], a[r-1]); compexch(a[l], a[r-1]); compexch(a[l], a[r]); compexch(a[r-1], a[r]); int i = partition(a, l+1, r-1); quicksort(a, l, i-1); quicksort(a, i+1, r); } template void hybridsort(Item a[], int l, int r) { quicksort(a, l, r); insertion(a, l, r); } ----- template int operator==(const Item &A, const Item &B) { return !less(A, B) && !less(B, A); } template void quicksort(Item a[], int l, int r) { int k; Item v = a[r]; if (r <= l) return; int i = l-1, j = r, p = l-1, q = r; for (;;) { while (a[++i] < v) ; while (v < a[--j]) if (j == l) break; if (i >= j) break; exch(a[i],a[j]); if (a[i] == v) { p++; exch(a[p],a[i]); } if (v == a[j]) { q--; exch(a[q],a[j]); } } exch(a[i], a[r]); j = i-1; i = i+1; for (k = l ; k <= p; k++, j--) exch(a[k],a[j]); for (k = r-1; k >= q; k--, i++) exch(a[k],a[i]); quicksort(a, l, j); quicksort(a, i, r); } ----- template void select(Item a[], int l, int r, int k) { if (r <= l) return; int i = partition(a, l, r); if (i > k) select(a, l, i-1, k); if (i < k) select(a, i+1, r, k); } ----- template void select(Item a[], int l, int r, int k) { while (r > l) { int i = partition(a, l, r); if (i >= k) r = i-1; if (i <= k) l = i+1; } } ---------- CHAPTER 8. Mergesort ----- template void mergeAB(Item c[], Item a[], int N, Item b[], int M ) { for (int i = 0, j = 0, k = 0; k < N+M; k++) { if (i == N) { c[k] = b[j++]; continue; } if (j == M) { c[k] = a[i++]; continue; } c[k] = (a[i] < b[j]) ? a[i++] : b[j++]; } } ----- template void merge(Item a[], int l, int m, int r) { int i, j; static Item aux[maxN]; for (i = m+1; i > l; i--) aux[i-1] = a[i-1]; for (j = m; j < r; j++) aux[r+m-j] = a[j+1]; for (int k = l; k <= r; k++) if (aux[j] < aux[i]) a[k] = aux[j--]; else a[k] = aux[i++]; } ----- template void mergesort(Item a[], int l, int r) { if (r <= l) return; int m = (r+l)/2; mergesort(a, l, m); mergesort(a, m+1, r); merge(a, l, m, r); } ----- template void mergesortABr(Item a[], Item b[], int l, int r) { if (r-l <= 10) { insertion(a, l, r); return; } int m = (l+r)/2; mergesortABr(b, a, l, m); mergesortABr(b, a, m+1, r); mergeAB(a+l, b+l, m-l+1, b+m+1, r-m); } template void mergesortAB(Item a[], int l, int r) { static Item aux[maxN]; for (int i = l; i <= r; i++) aux[i] = a[i]; mergesortABr(a, aux, l, r); } ----- inline int min(int A, int B) { return (A < B) ? A : B; } template void mergesortBU(Item a[], int l, int r) { for (int m = 1; m <= r-l; m = m+m) for (int i = l; i <= r-m; i += m+m) merge(a, i, i+m-1, min(i+m+m-1, r)); } ----- link merge(link a, link b) { node dummy(0); link head = &dummy, c = head; while ((a != 0) && (b != 0)) if (a->item < b->item) { c->next = a; c = a; a = a->next; } else { c->next = b; c = b; b = b->next; } c->next = (a == 0) ? b : a; return head->next; } ----- link mergesort(link c) { if (c == 0 || c->next == 0) return c; link a = c, b = c->next; while ((b != 0) && (b->next != 0)) { c = c->next; b = b->next->next; } b = c->next; c->next = 0; return merge(mergesort(a), mergesort(b)); } ----- link mergesort(link t) { QUEUE Q(max); if (t == 0 || t->next == 0) return t; for (link u = 0; t != 0; t = u) { u = t->next; t->next = 0; Q.put(t); } t = Q.get(); while (!Q.empty()) { Q.put(t); t = merge(Q.get(), Q.get()); } return t; } ---------- CHAPTER 9. Priority Queues and Heapsort ----- template class PQ { private: // Implementation-dependent code public: PQ(int); int empty() const; void insert(Item); Item getmax(); }; ----- template class PQ { private: Item *pq; int N; public: PQ(int maxN) { pq = new Item[maxN]; N = 0; } int empty() const { return N == 0; } void insert(Item item) { pq[N++] = item; } Item getmax() { int max = 0; for (int j = 1; j < N; j++) if (pq[max] < pq[j]) max = j; exch(pq[max], pq[N-1]); return pq[--N]; } }; ----- template void fixUp(Item a[], int k) { while (k > 1 && a[k/2] < a[k]) { exch(a[k], a[k/2]); k = k/2; } } ----- template void fixDown(Item a[], int k, int N) { while (2*k <= N) { int j = 2*k; if (j < N && a[j] < a[j+1]) j++; if (!(a[k] < a[j])) break; exch(a[k], a[j]); k = j; } } ----- template class PQ { private: Item *pq; int N; public: PQ(int maxN) { pq = new Item[maxN+1]; N = 0; } int empty() const { return N == 0; } void insert(Item item) { pq[++N] = item; fixUp(pq, N); } Item getmax() { exch(pq[1], pq[N]); fixDown(pq, 1, N-1); return pq[N--]; } }; ----- #include "PQ.cxx" template void PQsort(Item a[], int l, int r) { int k; PQ pq(r-l+1); for (k = l; k <= r; k++) pq.insert(a[k]); for (k = r; k >= l; k--) a[k] = pq.getmax(); } ----- template void heapsort(Item a[], int l, int r) { int k, N = r-l+1; Item *pq = a+l-1; for (k = N/2; k >= 1; k--) fixDown(pq, k, N); while (N > 1) { exch(pq[1], pq[N]); fixDown(pq, 1, --N); } } ----- template class PQ { private: // Implementation-dependent code public: // Implementation-dependent handle definition PQ(int); int empty() const; handle insert(Item); Item getmax(); void change(handle, Item); void remove(handle); void join(PQ&); }; ----- template class PQ { private: struct node { Item item; node *prev, *next; node(Item v) { item = v; prev = 0; next = 0; } }; typedef node *link; link head, tail; public: typedef node* handle; PQ(int = 0) { head = new node(0); tail = new node(0); head->prev = tail; head->next = tail; tail->prev = head; tail->next = head; } int empty() const { return head->next->next == head; } handle insert(Item v) { handle t = new node(v); t->next = head->next; t->next->prev = t; t->prev = head; head->next = t; return t; } Item getmax(); void change(handle, Item); void remove(handle); void join(PQ&); }; ----- Item getmax() { Item max; link x = head->next; for (link t = x; t->next != head; t = t->next) if (x->item < t->item) x = t; max = x->item; remove(x); return max; } void change(handle x, Item v) { x->key = v; } void remove(handle x) { x->next->prev = x->prev; x->prev->next = x->next; delete x; } void join(PQ& p) { tail->prev->next = p.head->next; p.head->next->prev = tail->prev; head->prev = p.tail; p.tail->next = head; delete tail; delete p.head; tail = p.tail; } ----- template class PQ { private: // Implementation-dependent code public: PQ(int); int empty() const; void insert(Index); Index getmax(); void change(Index); void remove(Index); }; ----- template class PQ { private: int N; Index* pq; int* qp; void exch(Index i, Index j) { int t; t = qp[i]; qp[i] = qp[j]; qp[j] = t; pq[qp[i]] = i; pq[qp[j]] = j; } void fixUp(Index a[], int k); void fixDown(Index a[], int k, int N); public: PQ(int maxN) { pq = new Index[maxN+1]; qp = new int[maxN+1]; N = 0; } int empty() const { return N == 0; } void insert(Index v) { pq[++N] = v; qp[v] = N; fixUp(pq, N); } Index getmax() { exch(pq[1], pq[N]); fixDown(pq, 1, N-1); return pq[N--]; } void change(Index k) { fixUp(pq, qp[k]); fixDown(pq, qp[k], N); } }; ----- static link pair(link p, link q) { if (p->item < q->item) { p->r = q->l; q->l = p; return q; } else { q->r = p->l; p->l = q; return p; } } ----- handle insert(Item v) { link t = new node(v), c = t; for (int i = 0; i < maxBQsize; i++) { if (c == 0) break; if (bq[i] == 0) { bq[i] = c; break; } c = pair(c, bq[i]); bq[i] = 0; } return t; } ----- Item getmax() { int i, max; Item v = 0; link* temp = new link[maxBQsize]; for (i = 0, max = -1; i < maxBQsize; i++) if (bq[i] != 0) if ((max == -1) || (v < bq[i]->item)) { max = i; v = bq[max]->item; } link x = bq[max]->l; for (i = max; i < maxBQsize; i++) temp[i] = 0; for (i = max ; i > 0; i--) { temp[i-1] = x; x = x->r; temp[i-1]->r = 0; } delete bq[max]; bq[max] = 0; BQjoin(bq, temp); delete temp; return v; } ----- static inline int test(int C, int B, int A) { return 4*C + 2*B + 1*A; } static void BQjoin(link *a, link *b) { link c = 0; for (int i = 0; i < maxBQsize; i++) switch(test(c != 0, b[i] != 0, a[i] != 0)) { case 2: a[i] = b[i]; break; case 3: c = pair(a[i], b[i]); a[i] = 0; break; case 4: a[i] = c; c = 0; break; case 5: c = pair(c, a[i]); a[i] = 0; break; case 6: case 7: c = pair(c, b[i]); break; } } ---------- CHAPTER 10. Radix Sorting ----- template void quicksortB(Item a[], int l, int r, int d) { int i = l, j = r; if (r <= l || d > bitsword) return; while (j != i) { while (digit(a[i], d) == 0 && (i < j)) i++; while (digit(a[j], d) == 1 && (j > i)) j--; exch(a[i], a[j]); } if (digit(a[r], d) == 0) j++; quicksortB(a, l, j-1, d+1); quicksortB(a, j, r, d+1); } template void sort(Item a[], int l, int r) { quicksortB(a, l, r, 0); } ----- #define bin(A) l+count[A] template void radixMSD(Item a[], int l, int r, int d) { int i, j, count[R+1]; static Item aux[maxN]; if (d > bytesword) return; if (r-l <= M) { insertion(a, l, r); return; } for (j = 0; j < R; j++) count[j] = 0; for (i = l; i <= r; i++) count[digit(a[i], d) + 1]++; for (j = 1; j < R; j++) count[j] += count[j-1]; for (i = l; i <= r; i++) aux[count[digit(a[i], d)]++] = a[i]; for (i = l; i <= r; i++) a[i] = aux[i-l]; radixMSD(a, l, bin(0)-1, d+1); for (j = 0; j < R-1; j++) radixMSD(a, bin(j), bin(j+1)-1, d+1); } ----- #define ch(A) digit(A, d) template void quicksortX(Item a[], int l, int r, int d) { int i, j, k, p, q; int v; if (r-l <= M) { insertion(a, l, r); return; } v = ch(a[r]); i = l-1; j = r; p = l-1; q = r; while (i < j) { while (ch(a[++i]) < v) ; while (v < ch(a[--j])) if (j == l) break; if (i > j) break; exch(a[i], a[j]); if (ch(a[i])==v) { p++; exch(a[p], a[i]); } if (v==ch(a[j])) { q--; exch(a[j], a[q]); } } if (p == q) { if (v != '\0') quicksortX(a, l, r, d+1); return; } if (ch(a[i]) < v) i++; for (k = l; k <= p; k++, j--) exch(a[k], a[j]); for (k = r; k >= q; k--, i++) exch(a[k], a[i]); quicksortX(a, l, j, d); if ((i == r) && (ch(a[i]) == v)) i++; if (v != '\0') quicksortX(a, j+1, i-1, d+1); quicksortX(a, i, r, d); } ----- template void radixLSD(Item a[], int l, int r) { static Item aux[maxN]; for (int d = bytesword-1; d >= 0; d--) { int i, j, count[R+1]; for (j = 0; j < R; j++) count[j] = 0; for (i = l; i <= r; i++) count[digit(a[i], d) + 1]++; for (j = 1; j < R; j++) count[j] += count[j-1]; for (i = l; i <= r; i++) aux[count[digit(a[i], d)]++] = a[i]; for (i = l; i <= r; i++) a[i] = aux[i-l]; } } ---------- CHAPTER 11. Special-Purpose Sorts ----- template void shuffle(Item a[], int l, int r) { int i, j, m = (l+r)/2; static Item aux[maxN]; for (i = l, j = 0; i <= r; i+=2, j++) { aux[i] = a[l+j]; aux[i+1] = a[m+1+j]; } for (i = l; i <= r; i++) a[i] = aux[i]; } template void unshuffle(Item a[], int l, int r) { int i, j, m = (l+r)/2; static Item aux[maxN]; for (i = l, j = 0; i <= r; i+=2, j++) { aux[l+j] = a[i]; aux[m+1+j] = a[i+1]; } for (i = l; i <= r; i++) a[i] = aux[i]; } ----- template void merge(Item a[], int l, int m, int r) { if (r == l+1) compexch(a[l], a[r]); if (r < l+2) return; unshuffle(a, l, r); merge(a, l, (l+m)/2, m); merge(a, m+1, (m+1+r)/2, r); shuffle(a, l, r); for (int i = l+1; i < r; i+=2) compexch(a[i], a[i+1]); } ----- template void merge(Item a[], int l, int m, int r) { int N = r-l+1; // assuming N/2 is m-l+1 for (int k = N/2; k > 0; k /= 2) for (int j = k % (N/2); j+k < N; j += k+k) for (int i = 0; i < k; i++) compexch(a[l+j+i], a[l+j+i+k]); } ----- template void batchersort(Item a[], int l, int r) { int N = r-l+1; for (int p = 1; p < N; p += p) for (int k = p; k > 0; k /= 2) for (int j = k%p; j+k < N; j += (k+k)) for (int i = 0; i < N-j-k; i++) if ((j+i)/(p+p) == (j+i+k)/(p+p)) compexch(a[l+j+i], a[l+j+i+k]); } ----- ----- ---------- CHAPTER 12. Symbol Tables and BSTs ----- #include #include static int maxKey = 1000; typedef int Key; class Item { private: Key keyval; float info; public: Item() { keyval = maxKey; } Key key() { return keyval; } int null() { return keyval == maxKey; } void rand() { keyval = 1000*::rand()/RAND_MAX; info = 1.0*::rand()/RAND_MAX; } int scan(istream& is = cin) { return (is >> keyval >> info) != 0; } void show(ostream& os = cout) { os << keyval << " " << info << endl; } }; ostream& operator<<(ostream& os, Item& x) { x.show(os); return os; } ----- template class ST { private: // Implementation-dependent code public: ST(int); int count(); Item search(Key) ; void insert(Item); void remove(Item); Item select(int); void show(ostream&); }; ----- #include #include #include "Item.cxx" #include "ST.cxx" int main(int argc, char *argv[]) { int N, maxN = atoi(argv[1]), sw = atoi(argv[2]); ST st(maxN); for (N = 0; N < maxN; N++) { Item v; if (sw) v.rand(); else if (!v.scan()) break; if (!(st.search(v.key())).null()) continue; st.insert(v); } st.show(cout); cout << endl; cout << N << " keys" << endl; cout << st.count() << " distinct keys" << endl; } ----- template class ST { private: Item nullItem, *st; int M; public: ST(int maxN) { M = nullItem.key(); st = new Item[M]; } int count() { int N = 0; for (int i = 0; i < M; i++) if (!st[i].null()) N++; return N; } void insert(Item x) { st[x.key()] = x; } Item search(Key v) { return st[v]; } void remove(Item x) { st[x.key()] = nullItem; } Item select(int k) { for (int i = 0; i < M; i++) if (!st[i].null()) if (k-- == 0) return st[i]; return nullItem; } void show(ostream& os) { for (int i = 0; i < M; i++) if (!st[i].null()) st[i].show(os); } }; ----- template class ST { private: Item nullItem, *st; int N; public: ST(int maxN) { st = new Item[maxN+1]; N = 0; } int count() { return N; } void insert(Item x) { int i = N++; Key v = x.key(); while (i > 0 && v < st[i-1].key()) { st[i] = st[i-1]; i--; } st[i] = x; } Item search(Key v) { for (int i = 0; i < N; i++) if (!(st[i].key() < v)) break; if (v == st[i].key()) return st[i]; return nullItem; } Item select(int k) { return st[k]; } void show(ostream& os) { int i = 0; while (i < N) st[i++].show(os); } }; ----- #include template class ST { private: Item nullItem; struct node { Item item; node* next; node(Item x, node* t) { item = x; next = t; } }; typedef node *link; int N; link head; Item searchR(link t, Key v) { if (t == 0) return nullItem; if (t->item.key() == v) return t->item; return searchR(t->next, v); } public: ST(int maxN) { head = 0; N = 0; } int count() { return N; } Item search(Key v) { return searchR(head, v); } void insert(Item x) { head = new node(x, head); N++; } }; ----- private: Item searchR(int l, int r, Key v) { if (l > r) return nullItem; int m = (l+r)/2; if (v == st[m].key()) return st[m]; if (l == r) return nullItem; if (v < st[m].key()) return searchR(l, m-1, v); else return searchR(m+1, r, v); } public: Item search(Key v) { return searchR(0, N-1, v); } ----- template class ST { private: struct node { Item item; node *l, *r; node(Item x) { item = x; l = 0; r = 0; } }; typedef node *link; link head; Item nullItem; Item searchR(link h, Key v) { if (h == 0) return nullItem; Key t = h->item.key(); if (v == t) return h->item; if (v < t) return searchR(h->l, v); else return searchR(h->r, v); } void insertR(link& h, Item x) { if (h == 0) { h = new node(x); return; } if (x.key() < h->item.key()) insertR(h->l, x); else insertR(h->r, x); } public: ST(int maxN) { head = 0; } Item search(Key v) { return searchR(head, v); } void insert(Item x) { insertR(head, x); } }; ----- private: void showR(link h, ostream& os) { if (h == 0) return; showR(h->l, os); h->item.show(os); showR(h->r, os); } public: void show(ostream& os) { showR(head, os); } ----- void insert(Item x) { Key v = x.key(); if (head == 0) { head = new node(x); return; } link p = head; for (link q = p; q != 0; p = q ? q : p) q = (v < q->item.key()) ? q->l : q->r; if (v < p->item.key()) p->l = new node(x); else p->r = new node(x); } ----- #include #include #include "Item.cxx" #include "ST.cxx" static char text[maxN]; int main(int argc, char *argv[]) { int N = 0; char t; ifstream corpus; corpus.open(*++argv); while (N < maxN && corpus.get(t)) text[N++] = t; text[N] = 0; ST st(maxN); for (int i = 0; i < N; i++) st.insert(&text[i]); char query[maxQ]; Item x, v(query); while (cin.getline(query, maxQ)) if ((x = st.search(v.key())).null()) cout << "not found: " << query << endl; else cout << x-text << ": " << query << endl; } ----- void rotR(link& h) { link x = h->l; h->l = x->r; x->r = h; h = x; } void rotL(link& h) { link x = h->r; h->r = x->l; x->l = h; h = x; } ----- private: void insertT(link& h, Item x) { if (h == 0) { h = new node(x); return; } if (x.key() < h->item.key()) { insertT(h->l, x); rotR(h); } else { insertT(h->r, x); rotL(h); } } public: void insert(Item item) { insertT(head, item); } ----- private: Item selectR(link h, int k) { if (h == 0) return nullItem; int t = (h->l == 0) ? 0: h->l->N; if (t > k) return selectR(h->l, k); if (t < k) return selectR(h->r, k-t-1); return h->item; } public: Item select(int k) { return selectR(head, k); } ----- void partR(link& h, int k) { int t = (h->l == 0) ? 0: h->l->N; if (t > k ) { partR(h->l, k); rotR(h); } if (t < k ) { partR(h->r, k-t-1); rotL(h); } } ----- private: link joinLR(link a, link b) { if (b == 0) return a; partR(b, 0); b->l = a; return b; } void removeR(link& h, Key v) { if (h == 0) return; Key w = h->item.key(); if (v < w) removeR(h->l, v); if (w < v) removeR(h->r, v); if (v == w) { link t = h; h = joinLR(h->l, h->r); delete t; } } public: void remove(Item x) { removeR(head, x.key()); } ----- private: link joinR(link a, link b) { if (b == 0) return a; if (a == 0) return b; insertT(b, a->item); b->l = joinR(a->l, b->l); b->r = joinR(a->r, b->r); delete a; return b; } public: void join(ST& b) { head = joinR(head, b.head); } ---------- CHAPTER 13. Balanced Trees ----- void balanceR(link& h) { if ((h == 0) || (h->N == 1)) return; partR(h, h->N/2); balanceR(h->l); balanceR(h->r); } ----- private: void insertR(link& h, Item x) { if (h == 0) { h = new node(x); return; } if (rand() < RAND_MAX/(h->N+1)) { insertT(h, x); return; } if (x.key() < h->item.key()) insertR(h->l, x); else insertR(h->r, x); h->N++; } public: void insert(Item x) { insertR(head, x); } ----- private: link joinR(link a, link b) { if (a == 0) return b; if (b == 0) return a; insertR(b, a->item); b->l = joinR(a->l, b->l); b->r = joinR(a->r, b->r); delete a; fixN(b); return b; } public: void join(ST& b) { int N = head->N; if (rand()/(RAND_MAX/(N+b.head->N)+1) < N) head = joinR(head, b.head); else head = joinR(b.head, head); } ----- link joinLR(link a, link b) { if (a == 0) return b; if (b == 0) return a; if (rand()/(RAND_MAX/(a->N+b->N)+1) < a->N) { a->r = joinLR(a->r, b); return a; } else { b->l = joinLR(a, b->l); return b; } } ----- private: void splay(link& h, Item x) { if (h == 0) { h = new node(x, 0, 0, 1); return; } if (x.key() < h->item.key()) { link& hl = h->l; int N = h->N; if (hl == 0) { h = new node(x, 0, h, N+1); return; } if (x.key() < hl->item.key()) { splay(hl->l, x); rotR(h); } else { splay(hl->r, x); rotL(hl); } rotR(h); } else { link &hr = h->r; int N = h->N; if (hr == 0) { h = new node(x, h, 0, N+1); return; } if (hr->item.key() < x.key()) { splay(hr->r, x); rotL(h); } else { splay(hr->l, x); rotR(hr); } rotL(h); } } public: void insert(Item item) { splay(head, item); } ----- private: int red(link x) { if (x == 0) return 0; return x->red; } void RBinsert(link& h, Item x, int sw) { if (h == 0) { h = new node(x); return; } if (red(h->l) && red(h->r)) { h->red = 1; h->l->red = 0; h->r->red = 0; } if (x.key() < h->item.key()) { RBinsert(h->l, x, 0); if (red(h) && red(h->l) && sw) rotR(h); if (red(h->l) && red(h->l->l)) { rotR(h); h->red = 0; h->r->red = 1; } } else { RBinsert(h->r, x, 1); if (red(h) && red(h->r) && !sw) rotL(h); if (red(h->r) && red(h->r->r)) { rotL(h); h->red = 0; h->l->red = 1; } } } public: void insert(Item x) { RBinsert(head, x, 0); head->red = 0; } ----- private: Item searchR(link t, Key v, int k) { if (t == 0) return nullItem; if (v == t->item.key()) return t->item; link x = t->next[k]; if ((x == 0) || (v < x->item.key())) { if (k == 0) return nullItem; return searchR(t, v, k-1); } return searchR(x, v, k); } public: Item search(Key v) { return searchR(head, v, lgN); } ----- private: struct node { Item item; node **next; int sz; node(Item x, int k) { item = x; sz = k; next = new node*[k]; for (int i = 0; i < k; i++) next[i] = 0; } }; typedef node *link; link head; Item nullItem; int lgN; public: ST(int) { head = new node(nullItem, lgNmax); lgN = 0; } ----- private: int randX() { int i, j, t = rand(); for (i = 1, j = 2; i < lgNmax; i++, j += j) if (t > RAND_MAX/j) break; if (i > lgN) lgN = i; return i; } void insertR(link t, link x, int k) { Key v = x->item.key(); link tk = t->next[k]; if ((tk == 0) || (v < tk->item.key())) { if (k < x->sz) { x->next[k] = tk; t->next[k] = x; } if (k == 0) return; insertR(t, x, k-1); return; } insertR(tk, x, k); } public: void insert(Item v) { insertR(head, new node(v, randX()), lgN); } ----- private: void removeR(link t, Key v, int k) { link x = t->next[k]; if (!(x->item.key() < v)) { if (v == x->item.key()) { t->next[k] = x->next[k]; } if (k == 0) { delete x; return; } removeR(t, v, k-1); return; } removeR(t->next[k], v, k); } public: void remove(Item x) { removeR(head, x.key(), lgN); } ---------- CHAPTER 14. Hashing ----- int hash(char *v, int M) { int h = 0, a = 127; for (; *v != 0; v++) h = (a*h + *v) % M; return h; } ----- int hashU(char *v, int M) { int h, a = 31415, b = 27183; for (h = 0; *v != 0; v++, a = a*b % (M-1)) h = (a*h + *v) % M; return (h < 0) ? (h + M) : h; } ----- private: link* heads; int N, M; public: ST(int maxN) { N = 0; M = maxN/5; heads = new link[M]; for (int i = 0; i < M; i++) heads[i] = 0; } Item search(Key v) { return searchR(heads[hash(v, M)], v); } void insert(Item item) { int i = hash(item.key(), M); heads[i] = new node(item, heads[i]); N++; } ----- private: Item *st; int N, M; Item nullItem; public: ST(int maxN) { N = 0; M = 2*maxN; st = new Item[M]; for (int i = 0; i < M; i++) st[i] = nullItem; } int count() const { return N; } void insert(Item item) { int i = hash(item.key(), M); while (!st[i].null()) i = (i+1) % M; st[i] = item; N++; } Item search(Key v) { int i = hash(v, M); while (!st[i].null()) if (v == st[i].key()) return st[i]; else i = (i+1) % M; return nullItem; } ----- void remove(Item x) { int i = hash(x.key(), M), j; while (!st[i].null()) if (x.key() == st[i].key()) break; else i = (i+1) % M; if (st[i].null()) return; st[i] = nullItem; N--; for (j = i+1; !st[j].null(); j = (j+1) % M, N--) { Item v = st[j]; st[j] = nullItem; insert(v); } } ----- void insert(Item item) { Key v = item.key(); int i = hash(v, M), k = hashtwo(v, M); while (!st[i].null()) i = (i+k) % M; st[i] = item; N++; } Item search(Key v) { int i = hash(v, M), k = hashtwo(v, M); while (!st[i].null()) if (v == st[i].key()) return st[i]; else i = (i+k) % M; return nullItem; } ----- private: void expand() { Item *t = st; init(M+M); for (int i = 0; i < M/2; i++) if (!t[i].null()) insert(t[i]); delete t; } public: ST(int maxN) { init(4); } void insert(Item item) { int i = hash(item.key(), M); while (!st[i].null()) i = (i+1) % M; st[i] = item; if (N++ >= M/2) expand(); } ---------- CHAPTER 15. Radix Search ----- private: Item searchR(link h, Key v, int d) { if (h == 0) return nullItem; if (v == h->item.key()) return h->item; if (digit(v, d) == 0) return searchR(h->l, v, d+1); else return searchR(h->r, v, d+1); } public: Item search(Key v) { return searchR(head, v, 0); } ----- private: Item searchR(link h, Key v, int d) { if (h == 0) return nullItem; if (h->l == 0 && h->r == 0) { Key w = h->item.key(); return (v == w) ? h->item : nullItem; } if (digit(v, d) == 0) return searchR(h->l, v, d+1); else return searchR(h->r, v, d+1); } public: Item search(Key v) { return searchR(head, v, 0); } ----- private: link split(link p, link q, int d) { link t = new node(nullItem); t->N = 2; Key v = p->item.key(); Key w = q->item.key(); switch(digit(v, d)*2 + digit(w, d)) { case 0: t->l = split(p, q, d+1); break; case 1: t->l = p; t->r = q; break; case 2: t->r = p; t->l = q; break; case 3: t->r = split(p, q, d+1); break; } return t; } void insertR(link& h, Item x, int d) { if (h == 0) { h = new node(x); return; } if (h->l == 0 && h->r == 0) { h = split(new node(x), h, d); return; } if (digit(x.key(), d) == 0) insertR(h->l, x, d+1); else insertR(h->r, x, d+1); } public: ST(int maxN) { head = 0; } void insert(Item item) { insertR(head, item, 0); } ----- private: Item searchR(link h, Key v, int d) { if (h->bit <= d) return h->item; if (digit(v, h->bit) == 0) return searchR(h->l, v, h->bit); else return searchR(h->r, v, h->bit); } public: Item search(Key v) { Item t = searchR(head, v, -1); return (v == t.key()) ? t : nullItem; } ----- private: link insertR(link h, Item x, int d, link p) { Key v = x.key(); if ((h->bit >= d) || (h->bit <= p->bit)) { link t = new node(x); t->bit = d; t->l = (digit(v, t->bit) ? h : t); t->r = (digit(v, t->bit) ? t : h); return t; } if (digit(v, h->bit) == 0) h->l = insertR(h->l, x, d, h); else h->r = insertR(h->r, x, d, h); return h; } public: void insert(Item x) { Key v = x.key(); int i; Key w = searchR(head->l, v, -1).key(); if (v == w) return; for (i = 0; digit(v, i) == digit(w, i); i++) ; head->l = insertR(head->l, x, i, head); } ST(int maxN) { head = new node(nullItem); head->l = head->r = head; } ----- private: void showR(link h, ostream& os, int d) { if (h->bit <= d) { h->item.show(os); return; } showR(h->l, os, h->bit); showR(h->r, os, h->bit); } public: void show(ostream& os) { showR(head->l, os, -1); } ----- private: struct node { node **next; node() { next = new node*[R]; for (int i = 0; i < R; i++) next[i] = 0; } }; typedef node *link; link head; Item searchR(link h, Key v, int d) { int i = digit(v, d); if (h == 0) return nullItem; if (i == NULLdigit) { Item dummy(v); return dummy; } return searchR(h->next[i], v, d+1); } void insertR(link& h, Item x, int d) { int i = digit(x.key(), d); if (h == 0) h = new node; if (i == NULLdigit) return; insertR(h->next[i], x, d+1); } public: ST(int maxN) { head = 0; } Item search(Key v) { return searchR(head, v, 0); } void insert(Item x) { insertR(head, x, 0); } ----- private: struct node { Item item; int d; node *l, *m, *r; node(int k) { d = k; l = 0; m = 0; r = 0; } }; typedef node *link; link head; Item nullItem; Item searchR(link h, Key v, int d) { int i = digit(v, d); if (h == 0) return nullItem; if (i == NULLdigit) { Item dummy(v); return dummy; } if (i < h->d) return searchR(h->l, v, d); if (i == h->d) return searchR(h->m, v, d+1); if (i > h->d) return searchR(h->r, v, d); } void insertR(link& h, Item x, int d) { int i = digit(x.key(), d); if (h == 0) h = new node(i); if (i == NULLdigit) return; if (i < h->d) insertR(h->l, x, d); if (i == h->d) insertR(h->m, x, d+1); if (i > h->d) insertR(h->r, x, d); } public: ST(int maxN) { head = 0; } Item search(Key v) { return searchR(head, v, 0); } void insert(Item x) { insertR(head, x, 0); } ----- private: char word[maxW]; void matchR(link h, char *v, int i) { if (h == 0) return; if ((*v == 0) && (h->d == 0)) { word[i] = 0; cout << word << " "; } if ((*v == '*') || (*v == h->d)) { word[i] = h->d; matchR(h->m, v+1, i+1); } if ((*v == '*') || (*v < h->d)) matchR(h->l, v, i); if ((*v == '*') || (*v > h->d)) matchR(h->r, v, i); } public: void match(char *v) { matchR(head, v, 0); } ----- struct node { Item item; int d; node *l, *m, *r; node(Item x, int k) { item = x; d = k; l = 0; m = 0; r = 0; } node(node* h, int k) { d = k; l = 0; m = h; r = 0; } int internal() { return d != NULLdigit; } }; typedef node *link; link heads[R]; Item nullItem; ----- private: link split(link p, link q, int d) { int pd = digit(p->item.key(), d), qd = digit(q->item.key(), d); link t = new node(nullItem, qd); if (pd < qd) { t->m = q; t->l = new node(p, pd); } if (pd == qd) { t->m = split(p, q, d+1); } if (pd > qd) { t->m = q; t->r = new node(p, pd); } return t; } link newext(Item x) { return new node(x, NULLdigit); } void insertR(link& h, Item x, int d) { int i = digit(x.key(), d); if (h == 0) { h = new node(newext(x), i); return; } if (!h->internal()) { h = split(newext(x), h, d); return; } if (i < h->d) insertR(h->l, x, d); if (i == h->d) insertR(h->m, x, d+1); if (i > h->d) insertR(h->r, x, d); } public: ST(int maxN) { for (int i = 0; i < R; i++) heads[i] = 0; } void insert(Item x) { insertR(heads[digit(x.key(), 0)], x, 1); } ----- private: Item searchR(link h, Key v, int d) { if (h == 0) return nullItem; if (h->internal()) { int i = digit(v, d), k = h->d; if (i < k) return searchR(h->l, v, d); if (i == k) return searchR(h->m, v, d+1); if (i > k) return searchR(h->r, v, d); } if (v == h->item.key()) return h->item; return nullItem; } public: Item search(Key v) { return searchR(heads[digit(v, 0)], v, 1); } ----- ---------- CHAPTER 16. External Searching ----- template struct entry { Key key; Item item; struct node *next; }; struct node { int m; entry b[M]; node() { m = 0; } }; typedef node *link; ----- private: Item searchR(link h, Key v, int ht) { int j; if (ht == 0) for (j = 0; j < h->m; j++) { if (v == h->b[j].key) return h->b[j].item; } else for (j = 0; j < h->m; j++) if ((j+1 == h->m) || (v < h->b[j+1].key)) return searchR(h->b[j].next, v, ht-1); return nullItem; } public: Item search(Key v) { return searchR(head, v, HT); } ----- private: link insertR(link h, Item x, int ht) { int i, j; Key v = x.key(); entry t; t.key = v; t.item = x; if (ht == 0) for (j = 0; j < h->m; j++) { if (v < h->b[j].key) break; } else for (j = 0; j < h->m; j++) if ((j+1 == h->m) || (v < h->b[j+1].key)) { link u; u = insertR(h->b[j++].next, x, ht-1); if (u == 0) return 0; t.key = u->b[0].key; t.next = u; break; } for (i = h->m; i > j; i--) h->b[i] = h->b[i-1]; h->b[j] = t; if (++h->m < M) return 0; else return split(h); } public: ST(int maxN) { N = 0; HT = 0; head = new node; } void insert(Item item) { link u = insertR(head, item, HT); if (u == 0) return; link t = new node(); t->m = 2; t->b[0].key = head->b[0].key; t->b[1].key = u->b[0].key; t->b[0].next = head; t->b[1].next = u; head = t; HT++; } ----- link split(link h) { link t = new node(); for (int j = 0; j < M/2; j++) t->b[j] = h->b[M/2+j]; h->m = M/2; t->m = M/2; return t; } ----- template class ST { private: struct node { int m; Item b[M]; int k; node() { m = 0; k = 0; } }; typedef node *link; link* dir; Item nullItem; int N, d, D; public: ST(int maxN) { N = 0; d = 0; D = 1; dir = new link[D]; dir[0] = new node; } }; ----- private: Item search(link h, Key v) { for (int j = 0; j < h->m; j++) if (v == h->b[j].key()) return h->b[j]; return nullItem; } public: Item search(Key v) { return search(dir[bits(v, 0, d)], v); } ----- private: void split(link h) { link t = new node; while (h->m == 0 || h->m == M) { h->m = t->m = 0; for (int j = 0; j < M; j++) if (bits(h->b[j].key(), h->k, 1) == 0) h->b[h->m++] = h->b[j]; else t->b[t->m++] = h->b[j]; t->k = ++(h->k); } insertDIR(t, t->k); } void insert(link h, Item x) { int j; Key v = x.key(); for (j = 0; j < h->m; j++) if (v < h->b[j].key()) break; for (int i = (h->m)++; i > j; i--) h->b[i] = h->b[i-1]; h->b[j] = x; if (h->m == M) split(h); } public: void insert(Item x) { insert(dir[bits(x.key(), 0, d)], x); } ----- void insertDIR(link t, int k) { int i, m, x = bits(t->b[0].key(), 0, k); while (d < k) { link *old = dir; d += 1; D += D; dir = new link[D]; for (i = 0; i < D; i++) dir[i] = old[i/2]; if (d < k) dir[bits(x, 0, d)^1] = new node; } for (m = 1; k < d; k++) m *= 2; for (i = 0; i < m; i++) dir[x*m+i] = t; }