150 likes | 158 Views
Understand binary search, asymptotic complexity, and loop invariants in Java. Apply rules of thumb for efficient searching. Learn to iterate and refine search algorithms.
E N D
CS100J Lecture 15 • Previous 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 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. Lecture 15
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 Example • Rule of Thumb. Work sample data by hand. Be introspective. Ask yourself: “What am I doing?” val 19 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 ___________________________; } Lecture 15
0 L R N A Loop Invariant • Rule of Thumb. • Characterize the state after an arbitrary number of iterations, either in English of in a diagram. • Introduce a variable to record the subscript of each boundary expected to change independently during the iteration. val If val occurs in A[0..N], then val occurs in the shaded region A[L..R]. Lecture 15
0 L R N A 0 R N A 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: Final: L If val occurs in A[0..N], then val occurs in the shaded region A[L..R]. 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 ___________________________; } 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 ___________________________; } Lecture 15
L M R 11 12 13 14 A L R 11 12 13 14 A L R 11 12 13 14 A Refine the Body: Even length case • Midpoint M = (L+R) / 2; • If the interval has even length: • then select either • or Lecture 15
L M R 11 12 13 14 15 A L R 11 12 13 14 15 A L R 11 12 13 14 15 A Refine the Body: Odd length case • Midpoint M = (L+R) / 2; • If the interval has odd length: • then select either • or Lecture 15
Refine the Body . . . /* 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 = __________________________; } . . . • Rule of Thumb. Avoid different treatments of cases if you can treat all cases uniformly. Lecture 15
Conditional Expressions • Conditional Expression expression0 ? expression1 : expression2 Meaning: The value of the conditional expression is expression1ifexpression0istrue, and isexpression2otherwise. /* 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 ____________________________________; } 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; } 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; } N+1 1 2 4 8 16 32 ... #iterations 1 2 4 8 16 32 ... N+1 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; } Lecture 15