#---------------------------------------------------------------------- # Program to test the efficiency (running time) of various methods # of sorting a list of integers. # # Copyright (C) March 6, 2020 -- Dr. William T. Verts #---------------------------------------------------------------------- import random,time #---------------------------------------------------------------------- # One of the worst sorts ever. It takes no advantage of items already # in the proper order, and runs the same number of times where the list # is sorted or not. Its only benefit is that it is very short. #---------------------------------------------------------------------- def BubbleSort (L): for I in range(len(L)-1): for J in range(I+1,len(L)): if L[I] > L[J]: Temp = L[I] L[I] = L[J] L[J] = Temp return #---------------------------------------------------------------------- # Not a bad sort if the list is already sorted or nearly so, but can # as bad as BubbleSort in the worst case (list sorted in descending # order). #---------------------------------------------------------------------- def InsertionSort (L): for I in range(1,len(L)): J = I Test = L[J] while (J > 0) and (Test < L[J-1]): L[J] = L[J-1] J = J - 1 L[J] = Test return #---------------------------------------------------------------------- # Another bad sort. It, too, works OK if the list is sorted or nearly # so, but is as bad as BubbleSort in the worst case (and actually takes # longer time). #---------------------------------------------------------------------- def ExchangeSort (L): More = True N = len(L) while More: More = False N = N - 1 for I in range(N): if L[I] > L[I+1]: Temp = L[I] L[I] = L[I+1] L[I+1] = Temp More = True return #---------------------------------------------------------------------- # A very good sort and simple to write. #---------------------------------------------------------------------- def ShellsSort (L): N = len(L) M = N // 2 while (M > 0): for J in range(M,N): Test = L[J] I = J - M while (I >= 0) and (L[I] > Test): L[I+M] = L[I] I = I - M if (I+M != J): L[I+M] = Test M = M // 2 return #---------------------------------------------------------------------- # An excellent sort in general, but a few unusual cases can make # it as bad as BubbleSort. Recursive (containing a function that # calls itself). #---------------------------------------------------------------------- def QuickSort (L): def LocalSort (Low,High): if (Low >= High): return L2 = Low H2 = High Pivot = L[(L2+H2) // 2] while (L2 <= H2): while L[L2] < Pivot: L2 = L2 + 1 while L[H2] > Pivot: H2 = H2 - 1 if L2 <= H2: Temp = L[L2] L[L2] = L[H2] L[H2] = Temp L2 = L2 + 1 H2 = H2 - 1 if Low < H2: LocalSort(Low,H2) if L2 < High: LocalSort(L2,High) return LocalSort (0, len(L)-1) return #---------------------------------------------------------------------- # The built-in Python sort. Very complicated, but screamingly fast. # Worst-case performance equals QuickSort's average case, best case # (list contains a lot of sorted chunks) is MUCH faster. The # implementation of Tim's Sort (named after Tim Peters) is 3300 lines # of C code. #---------------------------------------------------------------------- def TimsSort (L): L.sort() return #---------------------------------------------------------------------- # Scramble the order of a list of numbers by picking two indexes at # random and swapping their contents, and doing this the same number of # times as there are items in the list. #---------------------------------------------------------------------- def Scramble (L): N = len(L) for I in range(N): N1 = random.randrange(N) N2 = random.randrange(N) # swap L[N1] with L[N2] Temp = L[N1] L[N1] = L[N2] L[N2] = Temp return #---------------------------------------------------------------------- # Check the performance of a particular sorting function. The first # argument is the list to sort, the second argument is the sorting # function to test, and the third argument is the name of the sorting # technique. Notice the use of formatting in the string being printed #(see page 330 of the Companion). #---------------------------------------------------------------------- def Performance (L, SortFunction, SortName): Scramble(L) Before = time.perf_counter() SortFunction(L) After = time.perf_counter() Elapsed = After - Before while len(SortName) < 15: SortName = SortName + " " print (SortName, " = %10.7f" % Elapsed, " seconds") return #---------------------------------------------------------------------- # Get the number of items, build a list, and test the performance # of a number of sorting techniques. #---------------------------------------------------------------------- N = int(input("Enter number of items --- ")) L = [] for I in range(N): L = L + [I] Performance(L, BubbleSort, "Bubble Sort") Performance(L, InsertionSort, "Insertion Sort") Performance(L, ExchangeSort, "Exchange Sort") Performance(L, ShellsSort, "Shell's Sort") Performance(L, QuickSort, "QuickSort") Performance(L, TimsSort, "Tim's Sort")