# This is a correct but poor implementation of quicksort found on the web (in # more than one place). # Comments (except these a the very beginning of the file) are from the # original author (don't know who it is). # DO NOT USE unless you modify it to make it good! # # To see poor behavior: # Try 1) already sorted list of 10000 numbers # >>> l = list(range(10000)) # >>> quicksort(l, 0, 9999) # 2) list of 10000 identical numbers # >>> l = 10000 * [0] # >>> quicksort(l,0,9999) # A good quicksort should handle such situations with no trouble at all. # # The problem is due to the very first line of partition: # pivot = list[end] ############################################################################### import random def partition(list, start, end): pivot = list[end] # Partition around the last value bottom = start-1 # Start outside the area to be partitioned top = end # Ditto done = 0 while not done: # Until all elements are partitioned... while not done: # Until we find an out of place element... bottom = bottom+1 # ... move the bottom up. if bottom == top: # If we hit the top... done = 1 # ... we are done. break if list[bottom] > pivot: # Is the bottom out of place? list[top] = list[bottom] # Then put it at the top... break # ... and start searching from the top. while not done: # Until we find an out of place element... top = top-1 # ... move the top down. if top == bottom: # If we hit the bottom... done = 1 # ... we are done. break if list[top] < pivot: # Is the top out of place? list[bottom] = list[top] # Then put it at the bottom... break # ...and start searching from the bottom. list[top] = pivot # Put the pivot in its place. return top # Return the split point def quicksort(list, start, end): if start < end: # If there are two or more elements... split = partition(list, start, end) # ... partition the sublist... quicksort(list, start, split-1) # ... and sort both halves. quicksort(list, split+1, end) else: return