Source code for sort

"""Illustrates the different sort functions and computes their
cost.

  #. Insertion sort (O(n^2))
  #. Selection sort (O(n^2))
  #. Merge sort (O(nlogn)) [recursive and iterative versions]
  #. Internal sort, used when calling  x.sort() (O(nlong n)
  
     Note:Internal sort is compiled C++ code and does not create a 
     copy of the list to be sorted. Hence, despite having the same
     complexity as merge sort, it is much faster.

"""


import random
import time


[docs]def sel_sort(l): """Selection sort algorithm: :: For each location i in the list l: Find the minimum element in l[i:] Swap ith location with the min element """ for i in range(len(l)-1): cur_min = l[i] min_idx = i for j in range(i+1,len(l)): if l[j] <= cur_min: cur_min = l[j] min_idx = j l[i], l[min_idx] = l[min_idx], l[i]
[docs]def ins_sort(l): """Insertion sort algorithm: :: For each location i in list l: Shift all elements in l[:i] greater than l[i] to right opening a location for l[i] in the list Insert l[i] to the opened location (pointed by j+1) """ for i in range(1, len(l)): x = l[i] j = i-1 while (j >= 0) and (l[j]>x): l[j+1]=l[j] j -= 1 l[j+1] = x return l
[docs]def merge(l1, l2): """Subfunction used for merge sort. :: Merge two sorted lists into a single sorted list by continuously popping the smallest element. When while loop ends, at least one list is empty. The other list is appended to the end of the merged list. """ l = [] while (len(l1) > 0 and len(l2)>0): if l1[0] < l2[0]: l.append( l1.pop(0) ) else: l.append( l2.pop(0) ) if len(l1) > 0: l.extend(l1) elif len(l2) > 0: l.extend(l2) return l
[docs]def merge_sort_rec(l): """Recursive merge sort :: If the list has more than one element: Recursively sort the two halves of the list (l1= l[:mid], l2=l[mid:]) Merge the sorted versions of l1 and l2 and return Else (list has already one or zero elements) Return the list, it is already sorted by definition """ if len(l) <= 1: return l else: mid = len(l)/2 l1 = l[:mid] l2 = l[mid:] l1new = merge_sort_rec(l1) l2new = merge_sort_rec(l2) return merge( l1new, l2new )
[docs]def merge_sort_it(l): """Merge sort iteratively :: Create a list of lists by placing each element in list l into a list ( lmerge = [ [1], [4], [3], [2] ] ) While there are more than 1 sublists in lmerge: For each pair of lists l1, l2 in lmerge Merge l1,l2 and append it to a new list, lmerge2 Replace lmerge with lmerge2 Return the single remaining element (sorted list) in the lmerge """ lmerge = [] for item in l: lmerge.append( [item] ) lmerge2 = [] while len(lmerge) > 1: for i in range(0,len(lmerge)-1,2): ltmp = merge( lmerge[i], lmerge[i+1] ) lmerge2.append( ltmp ) if len(lmerge)%2 == 1: lmerge2.append( lmerge[-1] ) lmerge = lmerge2 lmerge2 = [] return lmerge[0]
def time_func(f, l): """This is used for timing the input function on a given list and print the timing. """ start = time.time() f(l) end = time.time() print "Function %s, total: %.4f" %(f.__name__, end-start) if __name__=="__main__": x = range(5000) random.shuffle(x) ##shuffle the list to create an unsorted list x1 = x[:] ##we are creating copies for ins_sort and sel_sort as these do not return a new list x2 = x[:] time_func(ins_sort, x1) ##n squared time_func(sel_sort, x2) ##n squared time_func(merge_sort_rec, x) ##n * log n time_func(merge_sort_it, x) ## n * log n time_func(list.sort, x) ##internal sort, n * log n