""" quicksort.py $ python quicksort.py numbers : [25, 42, 7, 77, 96, 81, 2, 93, 61, 71, 29, 63, 37, 24, 30, 78] sorted : [2, 7, 24, 25, 29, 30, 37, 42, 61, 63, 71, 77, 78, 81, 93, 96] TODO: * add in step counter * put in parition examples & tests * return list_size vs number_of_steps for some examples Jim M | Feb 2013 """ def partition1(array, istart, iend, ipivot): """ Modify array[istart] ... array[iend] in place, such that elements smaller than array[ipivot] come before it, and ones bigger, after. Return index of final pivot position. """ # This version tries to make the idea # clear, without trying to do it efficiently. smaller = [] # numbers below pivot bigger = [] # numbers above bivot pivot = array[ipivot] for i in range(istart, iend+1): if i != ipivot: if array[i] < pivot: smaller.append(array[i]) else: bigger.append(array[i]) array[istart : iend+1] = smaller + [pivot] + bigger return len(smaller) def swap(array, i, j): """ swap two elements in a array, in place """ temp = array[i] array[i] = array[j] array[j] = temp def partition(array, istart, iend, ipivot): """ Same ... but in place, without python list methods """ pivot = array[ipivot] # remember pivot value swap(array, ipivot, iend) # put pivot on right end for now ibound = istart # index of smaller, bigger boundary for i in range(istart, iend): if array[i] < pivot: swap(array, i, ibound) ibound += 1 swap(array, ibound, iend) # put pivot at boundary return ibound def quicksort(array, istart=None, iend=None): if (istart, iend) == (None, None): (istart, iend) = (0, len(array) - 1) if istart < iend: ipivot = (istart + iend)/2 new_ipivot = partition(array, istart, iend, ipivot) quicksort(array, istart, new_ipivot - 1) quicksort(array, new_ipivot + 1, iend) return array def main(): import random numbers = random.sample(range(100), 16) random.shuffle(numbers) print " numbers : " + str(numbers) quicksort(numbers) print " sorted : " + str(numbers) main()