# quicksort: pick an element of the list (called the pivot); then # move all elements less than the pivot before it, and all elements # greater than the pivot after it; then (recursively) sort each half # # we print the pivot and the current state of the list each time through # # also count (and print) the number of comparisons and # exchanges # # Matt Bishop MHI 289I, Fall 2023 # # # set this to False to print *only* the original (unsorted) # and the final (sorted) lists # set to True to print the intermediate (partially sorted) lists # showintermediate = False # # we will generate a list of this many numbers # and then shuffle them 7 times using shuffle() # from the random module # import random nnums = 20 # set the number of swaps and comparisons to 0 swaps = 0 compares = 0 # # pick the pivot; this partitions the list into two parts # the list is the part of numlist with index low to index high # def partition(numlist, low, high): global swaps, compares # pick the pivot pivot = numlist[high] # now go through the list; at the end of this loop, # i is the index where the pivot goes; so everything # less than the pivot goes to before that index i = low for j in range(low, high+1): # a comparison with the pivot compares += 1 if numlist[j] < pivot: # now swap this with what's at index i # and advance index i by 1, to keep what # is before the index to where the pivot # will go swaps += 1 numlist[i], numlist[j] = numlist[j], numlist[i] i += 1 # now put the pivot in the right place # remember the pivot is at the end (index high) swaps += 1 numlist[i], numlist[high] = numlist[high], numlist[i] # print the current state of the list? if showintermediate: print("pivot %2d:" % pivot) # and return the index of the pivot return i # use selection sort to sort the word list # start at index 0 (first index), find the smallest element in the rest of the list # if it's less than the value at the first index, swap # repeat, advancing the first index until you reach the end of the list # globals: wordlist, list to search def quicksort(numlist, low, high): # print the current state of the list? if showintermediate: print(" ", numlist) if low < high: p = partition(numlist, low, high) quicksort(numlist, low, p - 1) quicksort(numlist, p + 1, high) # print the current state of the list? if showintermediate: print(" ", numlist) def qsort(numlist): quicksort(numlist, 0, len(numlist)-1) # # generate a list of numbers # we just put the first nnums number into a list (0 .. nnums-1) # and then shuffle it 7 times # def loadnums(): # generate the list; use range and convert it numlist = list(range(nnums)) # now shuffle 7 times; in theory, this makes # it as random as possible for i in range(0, 7): random.shuffle(numlist) # and return the list! return numlist # # this puts it all together # def main(): # we need to print these global compares, swaps # get the list # if it's empty, quit (just in case :) nums = loadnums() if nums == []: return # print the initial list print("Unsorted:", nums) # sort the list qsort(nums) # print the sorted list and the relevant statistics print(" Sorted:", nums) print("This took {} comparisons and {} swaps".format(compares, swaps)) # # and we're off! # main()