CS100J Lecture 15 Previous Lecture This Lecture Sorting Loop invariants more Rules of Thumb Reading Lewis & Loftus Section 6.3 Savitch Section 6.4 This Lecture Programming concepts Binary search Application of the “rules of thumb” Asymptotic complexity Java Constructs Conditional Expressions CS 100 Lecture 15
Search in a Sorted Array Problem. Find a given value in a sorted array, or say it doesn’t occur in the array. Rule of Thumb. Write a precise specification. /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { . . . } Rule of Thumb. Find inspiration from experience, e.g., looking up a name in a telephone directory. CS 100 Lecture 15
Example Rule of Thumb. Work sample data by hand. Be introspective. Ask yourself: “What am I doing?” val 19 0 1 2 3 4 5=N A 10 12 13 18 19 20 0 1 2 3 4 5=N A 10 12 13 18 19 20 0 1 2 3 4 5=N A 10 12 13 18 19 20 0 1 2 3 4 5=N A 10 12 13 18 19 20 CS 100 Lecture 15
Loop Pattern Rule of Thumb. If you smell an iteration, write it down. Decide between definite iteration and indefinite iteration Write down an appropriate pattern for the iteration. Do not fill in the pattern yet. /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { . . . while ( _______________________) } return ___________________________; CS 100 Lecture 15
Loop Invariant val A Rule of Thumb. 0 L R N Characterize the state after an arbitrary number of iterations, either in English or in a diagram. Introduce a variable to record the subscript of each boundary expected to change independently during the iteration. val 0 L R N A If val occurs in A[0..N], then val occurs in the shaded region A[L..R]. CS 100 Lecture 15
Initial and Final Conditions Rule of Thumb, continued Characterize the initial and final states, i.e., the state before the iteration begins and after the iteration is expected to stop. The characterization of the initial and final states should be special cases of the general characterization. Initial: 0=L N=R A Intermediate: 0 L R N A Final: L 0 R N A If val occurs in A[0..N], then val occurs in the shaded region A[L..R]. CS 100 Lecture 15
Initialization and Termination Rule of Thumb. Use the characterization to refine the initialization, termination condition, and increment of the loop. /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { int L = _____________; int R = _____________; while ( _______________________) . . . } return ___________________________; CS 100 Lecture 15
Specify the Body Rule of Thumb. Use the characterization to specify what the loop body must accomplish. /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { int L = 0; int R = N; /* Make L==R s.t. if val is in A[0..N], then A[L]== val. */ while ( L != R ) /* Reduce the size of the interval A[L..R] approximately in half, preserving the property that if val was in the original interval, then it is in the new interval. */ . . . } return ___________________________; CS 100 Lecture 15
Refine the Body: Even length case Midpoint M = (L+R) / 2; If the interval has even length: then select either or 11 12 13 14 A L M R 11 12 13 14 A L R 11 12 13 14 A L R CS 100 Lecture 15
Refine the Body: Odd length case Midpoint M = (L+R) / 2; If the interval has odd length: then select either or 11 12 13 14 15 A L M R 11 12 13 14 15 A L R 11 12 13 14 15 A L R CS 100 Lecture 15
Refine the Body Rule of Thumb. Avoid different treatments of cases if you can treat all cases uniformly. . . . /* Make L==R s.t. if val is in A[0..N], then A[L]== val. */ while ( L != R ) { /* Reduce the size of the interval A[L..R] approximately in half, preserving the property that if val was in the original interval, then it is in the new interval. */ int M = (L + R) / 2; if (____________________________) R = __________________________; else L = __________________________; } CS 100 Lecture 15
Conditional Expressions expression0 ? expression1 : expression2 Meaning: The value of the conditional expression is expression1 if expression0 is true, and is expression2 otherwise. /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { int L = 0; int R = N; /* Make L==R s.t. if val is in A[0..N], then A[L]== val. */ . . . return ____________________________________; } CS 100 Lecture 15
Final Program /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { int L = 0; int R = N; /* Make L==R s.t. if val is in A[0..N], then A[L]== val. */ while ( L != R ) /* Reduce the size of the interval A[L..R] approximately in half, preserving the property that if val was in the original interval, then it is in the new interval. */ int M = (L + R) / 2; if ( A[M] >= val ) R = M; else L = M+1; } return (A[L]==val) ? L : N+1; CS 100 Lecture 15
Asymptotic Complexity How many iterations does binary search take? N+1 1 2 4 8 16 32 ... #iterations 0 1 2 3 4 5 ... log2(N+1) In contrast, how many iterations does sequential search take in the worst case? /* Given A[0..N] sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or N+1 otherwise. */ int find(int[] A, int N, int val) { int k = 0; while (k <= N && val != A[k]) k++; return k; } #iterations 1 2 4 8 16 32 ... N+1 CS 100 Lecture 15
Better Final Program /* Given A sorted in non-decreasing order, return the subscript of an occurrence of val in A (if val occurs in A) or A.length otherwise. */ int find(int[] A, int val) { int N = A.length - 1; int L = 0; int R = N; /* Make L==R s.t. if val is in A[0..N], then A[L]== val. */ while ( L != R ) /* Reduce the size of the interval A[L..R] approximately in half, preserving the property that if val was in the original interval, then it is in the new interval. */ int M = (L + R) / 2; if ( A[M] >= val ) R = M; else L = M+1; } return (A[L]==val) ? L : N+1; CS 100 Lecture 15