CS 3343/3341
Analysis of Algorithms
|
Lecture Schedule | ||
---|---|---|
Week | Tuesday | Thursday |
1 | 13 January 2004 | 15 January 2004 |
2 | 20 January 2004 | 22 January 2004 |
3 | 27 January 2004 | 29 January 2004 |
4 | 3 February 2004 | 5 February 2004 |
5 | 10 February 2004 | 12 February 2004 |
6 | 17 February 2004 | 19 February 2004 |
7 | 24 February 2004 | 26 February 2004 |
8 | 2 March 2004 | 4 March 2004 |
9 | 9 March 2004 | 11 March 2004 |
Text solves this by back substitution:
Eventually one gets
= 0 + z + z2 + 2 z3 + 3 z4 + 5 z5 + 8 z5 + ...
G(z) = z/(1 - z - z2)
Roots of 1 - z - z2 are:
Finally, get (with steps given here)
n | 0 1 | | F(n-1) F(n) | | | = | |, where n >= 1 | 1 1 | | F(n) F(n+1) |
These are matices, and the power is iterated matrix multiplication. With ordinary matrix multiplication, the use of this formula would still end up taking O(n) time. However, there are much more efficient algorithms to raise an integer to a power, as described next.
S = set with n elements (perhaps an array); (max, min) = MAXMIN(S); pair_of_numbers MAXMIN(S) { if (S has 2 elements) { suppose S is {a, b}; return (MAX(a, b), MIN(a, b)); // just one comparison } else { divide S into two subsets S1 and S2 (roughly half); (max1, min1) = MAXMIN(S1); (max2, min2) = MAXMIN(S2); return (MAX(max1, max2), MIN(min1, min2)); // two comparisons } }
A = array with n elements, indexed by 0 to n-1 inclusive; void randomize(type[] A) { for (int i = 0; i < n-1; i++) { int r = randomInt(i, n-1); // i to n-1 inclusive interchange(A[i], A[r]); // possibly i == r } }
Asymptotic Execution Times (Big-Theta) | ||||
---|---|---|---|---|
Algorithm | Search | Insert | Delete | Comments |
Unordered List in an array |
n | 1 | n | Simple |
Unordered Linked List |
n | 1 | 1 | Simple |
Ordered List in an array |
log n | n | n | If search is common |
Binary Search Tree |
log n | log n | With effort | O(n) in worst case |
Balanced Tree (AVL) |
log n | log n | log n | All are worst case |
Hashing | 1 | 1 | 1 | Ugly not in order |
int exp(int X, int Y) { int x = X, y = Y, z = 1; while (y > 0) { z = z * x; y = y - 1; } return z; }
This obviously does the correct calculation. But there is a more formal approach.
MaxHeapify(A, i) l = LeftChild(i) r = RightChild(i) if (l <= heapsize(A) && A[l] > A[i]) largest = l else largest = i if (l <= heapsize(A) && A[r] > A[largest]) largest = r if (largest != i) { exchange(A[i], A[largest]) MaxHeapify(A, largest) }
BuildMaxHeap(A) heapsize(A) = n for (i = floor(n/2); i >= 1; i--) MaxHeapify(A, i)
Heapsort(A) BuildMaxHeap(A) for (i = n; i >= 2; i--) { exchange(A[1], A[i]) heapsize(A)-- MaxHeapify(A, 1) }
HeapExtractMax(A) if (heapsize(A) < 1) error("Heap underflow") max = A[1] A[1] = A[heapsize(A)] heapsize(A)-- MaxHeapify(A, 1) return max
HeapIncreaseKey(A, i, key) if (key < A[i]) error("New key smaller than old") A[i] = key while (i > 1 && A[Parent(i)] < A[i]) { exchange(A[i], A[Parent(i)]) i = Parent(i) }
MaxHeapInsert(A, key) heapsize(A)++ A[heapsize(A)] = -infinity HeapIncreaseKey(A, heapsize(A), key)
Three-page introduction to this subject (PDF): Page 1, Page 2, Page 3.
Let B be the sum of all the numbers {ai}. For each 1 <= i <= n and each 0 <= j <= B, let t(i, j) denote the truth value (true of false) of the statement "there is a subset of {a1, a2, ..., ai} which adds up exactly to j." Make up a table with a row for each value of i and a column for each value of j. Then fill in the first row, using the fact that t(1, j) = T if and only if either j = 0 or j = a1. For subsequent values of i and j, the entry t(i, j) in row i has value T if and only if either
or
When we are done filling in the entire table, check the entry t(n, K). The answer to the decision problem is "yes" if and only if this last entry is T.