| 
						
						
						
					 | 
				
				 | 
				
					@ -0,0 +1,439 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# coding: utf-8 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# # 1 Best cases | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# **1.1** Bubble sort | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# The short version of Bubble sort is given in the online book:   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# https://runestone.academy/runestone/static/FIT5211/SortSearch/TheBubbleSort.html   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# At every iteration, it detects whether an exchange has been made, and only continues iteration if that is the case. Given a sorted list, the first iteration will make no exchange, thus no other iteration will be performed, and only the inner loop will actually iterate over the entire list. The running time in that case is thus $O(n)$.  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# **1.2** Selection sort | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# After every pass of selection sort, the only thing we know is that one more item is now in place. The algorithm has no way of knowing and thus using the fact that the list is already sorted. The algorithm will thus perform the whole $O(n^2)$ operations, as in the worst case. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# **1.3** Merge sort | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# Merge splits the input list into two, without looking at its contents. the contents are only looked at upon merging, after every item in the list has been split into a sublist of size 1. At this point, all merging operations still need to happen. In this case, the running time is thus also $O(n \log{n})$. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# # 2 Merge sort without slicing | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[1]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#start is the index of the first item | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#end is the index past the the last item | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def indexMergeSort(alist, start = None, end = None): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if start == None: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        start = 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if end == None: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        end = len(alist)   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    #note that the print operations still use slicing for convenience | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    #print("Input: ",alist[start:end]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    length = end - start | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if length > 1: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        #print("Splitting ",alist[start:end]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        mid = start + length//2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        indexMergeSort(alist, start, mid) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        indexMergeSort(alist, mid, end) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        i=start # index for the left part of the list | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        j=mid # index for the right part of the list | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        #we use a temporary list | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        templist = [None] * (length) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        k = 0 #index for the temp list | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while i < mid and j < end: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if alist[i] < alist[j]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                templist[k] = alist[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                i=i+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                #we swap | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                templist[k] = alist[j] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                j=j+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while i < mid: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            templist[k] = alist[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            i=i+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while j < end: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            templist[k]=alist[j] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            j=j+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        #we copy the results | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for k in range(length): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            alist[start+k] = templist[k] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        #print("Merging ",alist[start:mid], alist[mid:end]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					alist = [54,26,93,17,77,31,44,55,20] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					indexMergeSort(alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print(alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# # 3 Benchmarking sorting algorithms | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[2]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import random | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def generatelist(n, lower = 0, upper = 1000, seed = 0): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    #https://docs.python.org/3/library/random.html | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    random.seed(seed) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    l = [None] * n | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for i in range(0,n): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        l[i] = random.randrange(lower, upper) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return l | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[3]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print(generatelist(10)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# Below we have copied the sorting functions from the online book: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[4]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def bubbleSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for passnum in range(len(alist)-1,0,-1): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for i in range(passnum): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if alist[i]>alist[i+1]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                temp = alist[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                alist[i] = alist[i+1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                alist[i+1] = temp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[5]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def shortBubbleSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    exchanges = True | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    passnum = len(alist)-1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    while passnum > 0 and exchanges: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       exchanges = False | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       for i in range(passnum): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           if alist[i]>alist[i+1]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					               exchanges = True | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					               temp = alist[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					               alist[i] = alist[i+1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					               alist[i+1] = temp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       passnum = passnum-1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[6]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def selectionSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   for fillslot in range(len(alist)-1,0,-1): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       positionOfMax=0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       for location in range(1,fillslot+1): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           if alist[location]>alist[positionOfMax]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					               positionOfMax = location | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       temp = alist[fillslot] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       alist[fillslot] = alist[positionOfMax] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       alist[positionOfMax] = temp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[7]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def insertionSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   for index in range(1,len(alist)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     currentvalue = alist[index] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     position = index | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     while position>0 and alist[position-1]>currentvalue: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         alist[position]=alist[position-1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         position = position-1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     alist[position]=currentvalue | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[8]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def shellSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    sublistcount = len(alist)//2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    while sublistcount > 0: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for startposition in range(sublistcount): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        gapInsertionSort(alist,startposition,sublistcount) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      #print("After increments of size",sublistcount, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      #                             "The list is",alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      sublistcount = sublistcount // 2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def gapInsertionSort(alist,start,gap): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for i in range(start+gap,len(alist),gap): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        currentvalue = alist[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        position = i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while position>=gap and alist[position-gap]>currentvalue: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            alist[position]=alist[position-gap] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            position = position-gap | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        alist[position]=currentvalue | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[9]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def mergeSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    #print("Splitting ",alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if len(alist)>1: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        mid = len(alist)//2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        lefthalf = alist[:mid] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        righthalf = alist[mid:] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        mergeSort(lefthalf) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        mergeSort(righthalf) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        i=0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        j=0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        k=0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while i < len(lefthalf) and j < len(righthalf): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if lefthalf[i] < righthalf[j]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                alist[k]=lefthalf[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                i=i+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                alist[k]=righthalf[j] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                j=j+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while i < len(lefthalf): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            alist[k]=lefthalf[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            i=i+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while j < len(righthalf): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            alist[k]=righthalf[j] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            j=j+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k=k+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    #print("Merging ",alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[10]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def quickSort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   quickSortHelper(alist,0,len(alist)-1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def quickSortHelper(alist,first,last): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   if first<last: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       splitpoint = partition(alist,first,last) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       quickSortHelper(alist,first,splitpoint-1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       quickSortHelper(alist,splitpoint+1,last) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def partition(alist,first,last): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   pivotvalue = alist[first] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   leftmark = first+1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   rightmark = last | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   done = False | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   while not done: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       while leftmark <= rightmark and alist[leftmark] <= pivotvalue: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           leftmark = leftmark + 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       while alist[rightmark] >= pivotvalue and rightmark >= leftmark: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           rightmark = rightmark -1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       if rightmark < leftmark: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           done = True | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           temp = alist[leftmark] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           alist[leftmark] = alist[rightmark] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           alist[rightmark] = temp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   temp = alist[first] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   alist[first] = alist[rightmark] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   alist[rightmark] = temp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   return rightmark | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# Now we benchmark them: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[11]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					sorting_algorithms = [bubbleSort, shortBubbleSort, selectionSort,                      insertionSort, shellSort, mergeSort,                      indexMergeSort, quickSort] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles = {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[bubbleSort] = "r-" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[shortBubbleSort] = "r:" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[selectionSort] = "y-" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[insertionSort] = "g-" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[shellSort] = "g:" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[mergeSort] = "b--" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[indexMergeSort] = "b:" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[quickSort] = "y--" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[19]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					from timeit import default_timer as timer | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import datetime | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# matplotlib may need to be installed separately | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import matplotlib.pyplot as plt  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def computeandplot(sorting_algorithms): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    step = 100 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    nsamples = 100 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    samples = range(0, nsamples) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    timelimit = 0.05 #seconds, per run | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    totaltime = 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    print("Maximum computing time:",           str(datetime.timedelta(seconds=            timelimit*nsamples*len(sorting_algorithms)))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for sortalgo in sorting_algorithms: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            attimelimit = False | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            times = [timelimit for _ in samples] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for i in samples: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if i == 0: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    times[i] = 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    continue | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                n = step * i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if attimelimit == False: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    l = generatelist(n) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    start = timer() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    sortalgo(l) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    end = timer() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    times[i] = end - start | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    totaltime += times[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if times[i] > timelimit: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        times[i] = timelimit | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        attimelimit = True | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            plt.plot(samples, times,                      styles[sortalgo],                      label=sortalgo.__name__) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    print("Actual computing time:", str(datetime.timedelta(seconds=int(totaltime)))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    plt.xlabel("list size / {}".format(step)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    plt.ylabel("time in seconds") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    plt.show() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					computeandplot(sorting_algorithms) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# # 4 Sorting small integers | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# **4.1** | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[13]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def countsort(alist): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    maxv = max(alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    l = [0]*(maxv+1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for i in alist: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        l[i] += 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    k = 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for i in range(0, len(alist)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while l[k] == 0: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            k += 1 # we count the number of values = k in alist | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        alist[i] = k | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        l[k] -= 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[14]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					alist = [54,26,93,17,77,31,44,55,20] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					countsort(alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print(alist) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# **4.2** | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[15]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import math | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					DEFAULT_BUCKET_SIZE = 5 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def bucketsort(array=alist, bucketSize=DEFAULT_BUCKET_SIZE): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if len(array) == 0: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return array | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  # Determine minimum and maximum values | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  minValue = array[0] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  maxValue = array[0] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for i in range(1, len(array)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if array[i] < minValue: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      minValue = array[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    elif array[i] > maxValue: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      maxValue = array[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  # Initialize buckets | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  buckets = [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for i in range(0, bucketCount): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    buckets.append([]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  # Distribute input array values into buckets | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for i in range(0, len(array)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    buckets[math.floor((array[i] - minValue) / bucketSize)].append(array[i]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  # Sort buckets and place back into input array | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  array = [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for i in range(0, len(buckets)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    insertion_sort(buckets[i]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for j in range(0, len(buckets[i])): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      array.append(buckets[i][j]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return array | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[16]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def default_compare(a, b): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   if a < b: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     return -1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   elif a > b: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     return 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   return 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[17]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def insertion_sort(array): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  for i in range(1, len(array)): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    item = array[i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    indexHole = i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    while indexHole > 0 and default_compare(array[indexHole - 1], item) > 0: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      array[indexHole] = array[indexHole - 1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      indexHole -= 1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    array[indexHole] = item | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return array | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					# In[18]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					new_sorting_algorithms = [bucketsort, indexMergeSort, quickSort] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					styles[bucketsort] = "g--" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					computeandplot(new_sorting_algorithms) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 |