CS1110 3 November 2011 insertion sort, selection sort, quick sort Do exercises on pp. 311-312 to get familiar with concepts and develop skill. Practice in DrJava! Test your methods! • Think about the algorithm and write the invariant for it. • Let the pre/post conditions inspire an invariant, and Let the three of them give you the algorithm. Have a problem in your life? Yes Then don’t worry No Yes Can you do something about it? No 1 Comments on A5 Recursion: Make requirements/descriptions less ambiguous, clearer; give more direction. Need optional problem with more complicated recursive solution would have been an interesting challenge, more recursive functions. They make us think! Make task 5 easier. I could not finish it. Great! No test cases! I had intended here to erupt in largely incoherent rage over that wretched concept of recursion, which I came to hate like an enemy: like a sentient being who, knowing the difference between right and wrong, had purposely chosen to do me harm. However, I then figured out how it works, and it is actually quite elegant, so now I suppose I have learned something against my will. Needed too much help, took too long Add more methods; it did not take long Allow us to do recursive methods with loops rather than recursively. Go over nested loops, because some people find the concept difficult. 2 Binary search –like searching in a telephone book Precondition P: b[h..k] is in ascending order (sorted). v is some value. Store in i to truthify Postcondition Q: b[h..i] <= v and v < b[i+1..k] h k P: b ? h Q: b i <= v Finds rightmost occurrence of v, if v in b[h..k] k >v h k 0 1 2 3 4 5 6 7 8 9 Example b 3 3 3 3 3 4 4 6 7 7 if v is 3, set i to 4 if v is 4, set i to 6 if v is 5, set i to 6 if v is 8, set i to 9 3 h k P: b ? h Q: b i k <= v >v i t h inv: b Binary search <= v ? i= h-1; t= k+1; while ( i+1 != t k >v ){ Looking at b[i+1] gives linear search from left. Looking at b[t-1] gives linear search from right. Looking at middle: b[(i+t)/2] gives a telephone-like search } 4 h P: b Binary search k For k+1-h = 2^15 = 32768 Takes only 16 loop iterations! ? h Q: b i <= v h inv: b k >v i <= v i= h-1; t= k+1; while (i+1 != t) { int e= (i+t) / 2; // {i < e < t} t k ? >v h b i <= v e ? ? t >v k <= v if (b[e] <= v) i= e; // makes progress, keeps inv true else t= e; // makes progress, keeps inv true } 5 Sorting: 0 pre: b insertion sort 0 inv: b “sorted” means in ascending order n 0 post: b ? sorted i n sorted for (int i= 0; i < n; i= i+1) { Push b[i] down into its sorted position in b[0..i]; } n ? 0 i 2 4 4 6 6 7 5 0 i 2 4 4 5 6 6 7 Iteration i makes up to i swaps. In worst case, number of swaps needed is 0 + 1 + 2 + 3 + … (n-1) = (n-1)*n / 2. Called an “n-squared”, or n2, algorithm. b[0..i-1]: i elements in worst case: Iteration 0: 0 swaps Iteration 1: 1 swap Iteration 2: 2 swaps 6 … 0 pre: b n 0 post: b n ? insertion sort 0 invariant: b sorted i n sorted ? Add property to invariant: first segment contains smaller values. selection sort 0 invariant: b i ≤ b[i..], sorted for (int i= 0; i < n; i= i+1) { int j= index of min of b[i..n-1]; Swap b[j] and b[i]; } n ≥ b[0..i-1], ? i n 2 4 4 6 6 8 9 9 7 8 9 i n 2 4 4 6 6 7 9 9 8 8 9 Also an “n-squared”, or n2, algorithm. 7 Partition algorithm: Given an array b[h..k] with some value x in b[h]: h k P: b x ? Swap elements of b[h..k] and store in j to truthify P: h j Q: b <= x x >= x change: h k b 3 5 4 1 6 2 3 8 1 into h j k b 1 2 1 3 5 4 6 3 8 or h j k b 1 2 3 1 3 4 5 6 8 k x is called the pivot value. x is not a program variable; x just denotes the value initially in b[h]. 8 Quicksort /** Sort b[h..k] */ public static void qsort(int[] b, int h, int k) { if (b[h..k] has fewer than 2 elements) return; To sort array of size n. e.g. 215 int j= partition(b, h, k); Worst case: n2 e.g. 230 // b[h..j–1] <= b[j] <= b[j+1..k] Average case: // Sort b[h..j–1] and b[j+1..k] n log n. e.g. 15 * 215 qsort(b, h, j–1); qsort(b, j+1, k); } 215 = 32768 h pre: b x k ? j= partition(b, h, k); h post: b <= x j x k >= x 9 Tony Hoare, in 1968 Quicksort author Tony Hoare in 2007 in Germany Thought of Quicksort in ~1958. Tried to explain it to a colleague, but couldn’t. Few months later: he saw a draft of the definition of the language Algol 58 –later turned into Algol 60. It had recursion. He went and explained Quicksort to his colleague, using recursion, who now understood it. 10 The NATO Software Engineering Conferences homepages.cs.ncl.ac.uk/brian.randell/NATO/ 7-11 Oct 1968, Garmisch, Germany 27-31 Oct 1969, Rome, Italy Download Proceedings, which have transcripts of discussions. See photographs. Software crisis: Academic and industrial people. Admitted for first time that they did not know how to develop software efficiently and effectively. Software Engineering, 1968 Next 10-15 years: intense period of research on software engineering, language design, proving programs correct, etc. 12 Software Engineering, 1968 13 During 1970s, 1980s, intense research on How to prove programs correct, How to make it practical, Methodology for developing algorithms The way we understand recursive methods is based on that methodology. Our understanding of and development of loops is based on that methodology. Throughout, we try to give you thought habits to help you solve programming problems for effectively Mark Twain: Nothing needs changing so much as the habits of others. 14 The way we understand recursive methods is based on that methodology. Our understanding of and development of loops is based on that methodology. Throughout, we try to give you thought habits to help you solve programming problems for effectively Simplicity is key: Learn not only to simplify, learn not to complify. Don’t solve a problem until you know what the problem is (give precise and thorough specs). Separate concerns; focus on one at a time. Develop and test incrementally. Learn to read a program at different levels of abstraction. 15