Idea:
Algorithm
for each index i in the list, starting at 1 do
Save the value stored at location i in variable x
Initialize j at location i-1
while j is non-negative and the location to insert x has not been found do
Shift the value at j up to j+1
Decrement j
Insert the value stored in x in location j+1
Code (in-class exercise):
def ins_sort(v):
The code test_sort.py posted on the Piazza site, and attached to the end of these notes, will be used to do timing experiments on all of the sorts we write.
Makes use of the random module
Includes three main functions:
We will discuss each of these in turn.
The sorting functions themselves are functions in the module sort
Notice that the sorting function is passed as an argument to run_and_time:
We will start with experiments to analyze selection sort (see textbook) and insertion sort.
Given two lists that are each already sorted, our problem is to generate a new sorted list containing all of the items from both lists.
For example,
L1 = [ 9, 12, 17, 25 ]
L2 = [ 3, 5, 11, 13, 16 ]
must be merged into a new list containing
[ 3, 5, 9, 11, 12, 13, 16, 17, 25 ]
Idea:
We don’t actually remove the items from L1 or L2. Instead we keep an index to the next location of L1 and L2 that has not yet been copied.
We’ll write the code in class, starting from here
def merge(L1, L2):
i1 = 0
i2 = 0
L = []
return L
Exercises: These are based on the code we write in class.
Key observation: all lists of length 1 are sorted
Therefore, for a list of length that is to be sorted:
Requires
Code (in class):
def merge_sort(v):
if len(v) <= 1:
return
Selection sort and insertion sort are dramatically slower than merge sort, which in turn is dramatically slower than Python’s built-in sort, a highly optimized, C language implementation of merge sort.
Shows
Both of these are important!
Final question: what happens when values are “almost” sorted?
For our insertion sort code, show the contents of the following list after each iteration of the outer for loop
v = [ 12, 4, 11, 2, 6, 18, 9 ]
While you can and should use the implementation to test your answers, you should start by manually generating the answers on your own.
Show the contents of the to_merge list at the end of the merge_sort implementation developed in class when it is called with
v = [ 17, 15, 29, 66, 31, 19, 9, 33 ].
Consider the following function
def extract( comp, v ):
x = v[0]
for i in range(1,len(v)):
if comp(v[i],x):
x = v[i]
return x
Note that comp is a function that has been passed to extract.
Write a function called compare_lower(a,b) such that if L is a list then the call
extract(compare_lower,L)
returns the smallest value in L.
Write a function called compare_upper(a,b) such that if L is a list then the call
extract(compare_upper,L)
returns the largest value in L.
Write a version of merge that does all of the work inside the while loop and does not use the extend. This is a good test of your logic skills.
Based on your previous solution write a function to merge three sorted lists. This is an even greater challenge to your logic skills.
Note that when it comes to Test 3, you will not be required to have memorized the code of the sorting functions, but you should know the algorithms!