$ \def\compare{ {\mathrm{compare}} } \def\swap{ {\mathrm{swap}} } \def\sort{ {\mathrm{sort}} } \def\insert{ {\mathrm{insert}} } \def\true{ {\mathrm{true}} } \def\false{ {\mathrm{false}} } \def\BubbleSort{ {\mathrm{BubbleSort}} } \def\SelectionSort{ {\mathrm{SelectionSort}} } $
Selection Sort!
01 SelectionSort(a):
02 n <- size(a)
03 for j = 1 to n - 1 do
04 min <- j
05 for i = j+1 to n do
06 if compare(a, min, i)
07 min <- i
08 endif
09 endfor
10 swap(a, j, min)
11 endfor
Goal. Logically deduce that algorithm succeeds on all inputs.
To do:
A logical predicate $P$ is a statement that can be true or false
Examples.
SelectionSort([5,2,7,1])
is sorted”A logical principle to establish the truth of a sequence of predicates
Example. $a$ an array of numbers of size $n$:
…
Question. How does “sortedness” relate to the predicates $P(1), P(2), \ldots, P(n-1)$?
Setup. $P(1), P(2), P(3), \ldots$ a sequence of predicates
Hypotheses. Suppose:
Conclusion. All of $P(1), P(2),\ldots$ are true
Proposition. The output of SelectionSort(a)
is sorted.
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
10 swap(a, i, min)
11 endfor
12 end
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
10 swap(a, i, min)
11 endfor
12 end
Claim 1 (inner loop invariant). After iteration $j$ of the inner loop, min
stores the index of the smallest value in $a[i..j]$.
Claim 2 (outer loop invariant). After iteration $i$ of the outer loop,
Claim 1 (inner loop invariant). After iteration $j$ of the inner loop, min
stores the index of the smallest value in $a[i..j]$.
Claim 2 (outer loop invariant). After iteration $i$ of the outer loop,
Argument overview:
Claim 1 (inner loop invariant). After iteration $j$ of the inner loop, min
stores the index of the smallest value in $a[i..j]$.
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
Use Induction:
Conclusion: Claim 1 holds for all $j$
Claim 1 (inner loop invariant). After iteration $j$ of the inner loop, min
stores the index of the smallest value in $a[i..j]$.
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
Proof of Base Case.
Proof of Inductive Step.
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
10 swap(a, i, min)
11 endfor
12 end
Claim 2 (outer loop invariant). After iteration $i$ of the outer loop,
Argue by induction!
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
.. min <- index of smallest value in a[i..n]
10 swap(a, i, min)
11 endfor
12 end
Claim 2 (outer loop invariant). After iteration $i$ of the outer loop,
Base case.
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
.. min <- index of smallest value in a[i..n]
10 swap(a, i, min)
11 endfor
12 end
Claim 2 (outer loop invariant). After iteration $i$ of the outer loop,
Inductive Step.
$\SelectionSort$ sorts every possible array!
How many $\swap$ operations does $\SelectionSort$ use? Could we do better?
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
10 swap(a, i, min)
11 endfor
12 end
How many $\compare$ operations does $\SelectionSort$ use? Could we do better?
01 SelectionSort(a):
02 n <- size(a)
03 for i = 1 to n - 1 do
04 min <- i
05 for j = i+1 to n do
06 if compare(a, min, j)
07 min <- j
08 endif
09 endfor
10 swap(a, i, min)
11 endfor
12 end
Sorting by “Divide and Conquer”
To read: notes on “Big O” notation (forthcoming)