from matplotlib import pyplot as plt
import random
import numpy as np
%pylab inline
def min_position(li, start_at):
assert len(li) > 0
assert start_at < len(li)
min_value = li[start_at]
min_position = start_at
for i, value in enumerate(li[start_at + 1:]):
if value < min_value:
min_value = value
min_position = start_at + 1 + i
return min_position
li = [1, 2, 3, 1, 2]
assert min_position(li, 0) == 0
assert min_position(li, 1) == 3
assert min_position(li, 2) == 3
assert min_position(li, 3) == 3
assert min_position(li, 4) == 4
def step(i, li):
idx = min_position(li, i)
li[i], li[idx] = li[idx], li[i] # tuple unpacking
def selection_sort(li, debug=False):
# copy li first so that li is not sorted inplace
# but the function returns a new list with sorted
# values:
li = li[:]
if debug:
print(" ", li)
for i in range(len(li) - 1):
step(i, li)
if debug:
print("{:2d} {}".format(i, li))
return li
import random
data = list(range(10))
selection_sort(data, True)
print()
random.shuffle(data)
selection_sort(data, True)
for i in range(100000):
random.shuffle(data)
assert sorted(data) == selection_sort(data), data
import time
from statistics import median
def measure(n):
data = list(range(n))
times = []
for _ in range(5):
random.shuffle(data)
started = time.time()
selection_sort(data)
times.append(time.time() - started)
return median(times)
times = []
sizes = np.array((100, 300, 500, 750, 1000, 1500, 2000, 2500, 3000))
for size in sizes:
print(size)
times.append(measure(size))
step(i)
scans n - i
elements which needs time a (n - i)
. the swap has constant time c
. This adds up to:
$ a n + a (n - 1) + a (n - 2) + ... + a + n c = a \frac{(n + 1) n}{2} + n c = \frac{a}{2} n^2 + (\frac{a}{2} + c) n $
Thus the runtime is dominated by $n^2$:
plt.plot(sizes, times)
plt.show()