& Proofs of Correctness
Many algorithms can be designed with recursive algorithms. Once you are used to them, they can be easier to understand (& prove correct) than iterative algorithms:
protected void recSelSort(int lastIndex, Comparable[] elts) { if (lastIndex > 0) // more than 1 element to sort { int extreme = 0; // index of element w/ largest value // Find "extreme", index of elts w/ largest value. for (int searchIndex = 1; searchIndex <= lastIndex; searchIndex++) { if (elts[extreme].lessThan(elts[searchIndex])) extreme = searchIndex; } // elt at "extreme" <= elts[index..lastIndex] // swap largest elt (at extreme) w/ one at lastIndex Comparable tempElt = elts[extreme]; elts[extreme] = elts[lastIndex]; elts[lastIndex] = tempElt; // elts[lastIndex] now largest in // elts[0..lastIndex] recSelSort(lastIndex-1,elts); // elts[0..lastIndex] are sorted. }How can prove correct?
Mathematical Induction:
A. Prove base case(s). (Usually this is trivial)
B. Show that if algorithm works correctly for all simpler input, then will work for current input.
Reason by induction on size of array (i.e. on lastIndex)
Base: If lastIndex <= 0 then at most one element in elts, and hence sorted - correct.
Induction: Suppose works if lastIndex < n. show it works if last = n (> 0)
(I.e. believe recursive call works, try to show for entire algorithm given call works!)
Loop finds largest element and then swaps with elts[lastIndex].
Thus elts[lastIndex] holds largest elt of list, while others held in elts[0..lastIndex-1]
Since lastIndex- 1 < lastIndex, know (by
induction hypothesis) that
recSelSort(lastIndex-1,elts) sorts
elts[0..lastIndex-1].
Because elts[0..lastIndex-1] in order and elts[lastIndex] is >= all of them, elts[0..lastIndex] is sorted.
Claim: recSelSort(n-1,elts) (i.e, on n elements) involves n*(n-1)/2 comparisons of elements of array.
Base: n = 0 or 1, 0 comparisons and n*(n-1)/2 = 0.
Induction hypothesis:
Suppose recSelSort(k-1,elts) takes k*(k-1)/2
comparisons for all k < n. Show true for n as well!
Look at algorithm: Run algorithm on recSelSort(n-1,elts). Therefore, last = n-1.
Go through for loop "last" = n-1 times, w/ one comparison each time through.
Thus n-1 comparisons. Only other comparisons are in recursive
call:
recSelSort(last-1,elts) where last = n-1.
But by induction (since last < n), this takes last*(last-1)/2 = (n-1)*(n-2)/2 comparisons.
Therefore altogether have (n-1) + (n-1)*(n-2)/2 = (n-1)*2/2 + (n-1)*(n-2)/2
= (n-1)*(2 + n-2)/2 = (n-1)*n/2 = n(n-1)/2 comparisons.
Finished proof.
Therefore RecSelSort takes O(n2) comparisons.
Note: Iterative version of SelectionSort is similar, but needs an extra for loop. See on-line code in Sort.