# selection_sort.py def min_index(b, i, n): """return index of min item in b[i..n-1]. Pre: i <= n.""" j = i k = i + 1 # inv: b[j] is min of b[i..k-1] while k < n: j = k if b[k] < b[j] else j k += 1 # post: b[j] is min of b[i..n-1] return j def selection_sort(b): """Sort list b in place.""" n = len(b) i = 0 # inv: b[0..i-1] sorted; # b[i..n-1] >= b[0..i-1] while i < n: j = min_index(b, i, n) # b[j] is min item in b[i..n-1] b[i], b[j] = b[j], b[i] i += 1 # post: b[0..n-1] sorted def selection_sort2(b): """Sort list b in place.""" n = len(b) i = 0 # inv: b[0..i-1] sorted; # b[i..n-1] >= b[0..i-1] while i < n: j = i k = i + 1 # inv (inner): b[j] is min of b[i..k-1] while k < n: j = k if b[k] < b[j] else j k += 1 # post (inner): b[j] is min of b[i..n-1] b[i], b[j] = b[j], b[i] i += 1 # post: b[0..n-1] sorted def selection_sort3(b): """Sort list b in place.""" n = len(b) # inv: b[0..i-1] sorted; # b[i..n-1] >= b[0..i-1] for i in range(n): j = i # inv (inner): b[j] is min of b[i..k-1] for k in range(i + 1, n): j = k if b[k] < b[j] else j # post (inner): b[j] is min of b[i..n-1] b[i], b[j] = b[j], b[i] # post: b[0..n-1] sorted if __name__ == '__main__': for sort_fn in [selection_sort, selection_sort2, selection_sort3]: for x in [[], [2], [1,2], [2,1], [2,4,3,7,5,9,2,1]]: y = x[:] y.sort() z = x[:] sort_fn(z) assert z == y, str(x) + ' -> ' + str(z) + ' != ' + str(y)