Selection Sort

Here, we'll develop our first sorting algorithm.

The idea is simple.

Suppose we have a list L of length n.

Find the largest element in the list L, and put it on the right of the list, at index n-1, by swapping it with whatever element happens to be currently at index n-1.

Now, the largest element of L is in the right place. Find the largest element in L[:(n-1)], and swap it with the element current found at index n-1.

Now, the largest element of L is in the right place, and the second-largest element is in the right place. Find the largest element in L[:(n-2)], and swap it with the element current found at index n-2.

Keep on going until L is sorted. Note that at first, the entire L is unsorted. Then, [L[n-1]] is sorted, but L[:n-1] is unsorted.

Then L[n-2:] is the sorted part, and L[:n-2] is the unsorted part.

Again, we continue this way until L is sorted.

Here is an example:

[3, 1, 2, 3, 6, 0]
#Swap the 6 with the 0

[3, 1, 2, 3, 0, 6]
#Swap the 3 with the 0

[3, 1, 2, 0, 3, 6]
#Swap the 3 with the 0

[0, 1, 2, 3, 3, 6]
#Swap the 2 with the 2 (2 is already in its correct place)

[0, 1, 2, 3, 3, 6]
#Swap the 1 with the 1 (1 is already in its correct place)

[0, 1, 2, 3, 3, 6]
#Swap the 0 with the 0 (0 is already in its correct place)
                       (in fact, it's guaranteed to be, since it's
                        the only element in the unsorted part of the list)

[0, 1, 2, 3, 3, 6]

Let's write a helper function for Selection Sort:

In [1]:
def max_i(L):
    '''Return the index of a largest element in L. If there is more than
    one maximal element, return the index of the leftmost one'''
    cur_max = L[0] #the largest element up to index i
    cur_max_i = 0  #the index of the largest element up to index i
    
    for i in range(1, len(L)):
        if L[i] > cur_max:
            cur_max = L[i]
            cur_max_i = i
    return cur_max_i
    

Now that we've written the helper function, it's easy to write the main Selection Sort function:

In [2]:
def selection_sort(L):
    '''Modify L so that it's sorted in non-decreasing order
    
    Arugment:
    L -- a list of ints
    '''
    for j in range(len(L)):
        ind_of_max = max_i(L[:len(L)-j])
        L[ind_of_max], L[-1-j] = L[-1-j], L[ind_of_max]