|
| 1 | +import time, random, tqdm, copy |
| 2 | +def timealgorithm(arrays, algorithm, algoname): |
| 3 | + print(f"Testing sorting algorithm {algoname}") |
| 4 | + newarrays = copy.deepcopy(arrays) |
| 5 | + start = time.time() |
| 6 | + for i in tqdm.tqdm(newarrays): |
| 7 | + algorithm(i) |
| 8 | + newtime = time.time() - start |
| 9 | + print(f"Total time: {newtime} seconds") |
| 10 | + |
| 11 | +def generatearrays(n,arrcount, randomize = True): |
| 12 | + arrays = [] |
| 13 | + for i in range(arrcount): |
| 14 | + k = list(range(n)) |
| 15 | + if(randomize): |
| 16 | + random.shuffle(k) |
| 17 | + arrays.append(k) |
| 18 | + return arrays |
| 19 | + |
| 20 | +def mergesort(arr): |
| 21 | + if(len(arr)==1): |
| 22 | + return arr |
| 23 | + a = mergesort(arr[:len(arr)//2]) |
| 24 | + b = mergesort(arr[len(arr)//2:]) |
| 25 | + aptr, bptr, cptr = 0,0,0 |
| 26 | + while(cptr<len(arr)): |
| 27 | + usea = False |
| 28 | + if(aptr!=len(a) and (bptr==len(b) or a[aptr]<b[bptr])): |
| 29 | + usea = True |
| 30 | + if(usea): |
| 31 | + arr[cptr] = a[aptr] |
| 32 | + aptr+=1 |
| 33 | + else: |
| 34 | + arr[cptr] = b[bptr] |
| 35 | + bptr+=1 |
| 36 | + cptr+=1 |
| 37 | + return arr |
| 38 | +def quicksort(doshuffle,pivot, partition): |
| 39 | + def f(arr): |
| 40 | + def g(arr,start,end): |
| 41 | + if(start>=end): |
| 42 | + return |
| 43 | + k = pivot(arr,start,end) |
| 44 | + if(k!=start): |
| 45 | + arr[k],arr[start] = arr[start],arr[k] |
| 46 | + p = partition(arr,start,end,start) |
| 47 | + g(arr,start,p-1) |
| 48 | + g(arr,p+1,end) |
| 49 | + if(doshuffle): |
| 50 | + random.shuffle(arr) |
| 51 | + g(arr,0,len(arr)-1) |
| 52 | + return arr |
| 53 | + return f |
| 54 | +def validate(sortingalgo): |
| 55 | + for i in range(1,1000): |
| 56 | + a = list(range(i)) |
| 57 | + random.shuffle(a) |
| 58 | + #print(a) |
| 59 | + k = sortingalgo(a) |
| 60 | + if(k!= list(range(i))): |
| 61 | + print("Error") |
| 62 | + #print(k) |
| 63 | + return False |
| 64 | + print("Success") |
| 65 | + return True |
| 66 | +def leftpivot(arr,start,end): |
| 67 | + return start |
| 68 | +def scanpartition(arr,start,end,pivot): |
| 69 | + smaller = [] |
| 70 | + equal = [] |
| 71 | + bigger = [] |
| 72 | + for i in range(start,end+1): |
| 73 | + if(arr[i]<arr[pivot]): |
| 74 | + smaller.append(arr[i]) |
| 75 | + elif(arr[i]>arr[pivot]): |
| 76 | + bigger.append(arr[i]) |
| 77 | + else: |
| 78 | + equal.append(arr[i]) |
| 79 | + v = start+len(smaller) |
| 80 | + for i in [smaller,equal,bigger]: |
| 81 | + for j in i: |
| 82 | + arr[start] = j |
| 83 | + start+=1 |
| 84 | + return v |
| 85 | +def hoarepartition(arr,start,end,pivot): |
| 86 | + i = start+1 |
| 87 | + j = end |
| 88 | + k = arr[pivot] |
| 89 | + while(True): |
| 90 | + while(i<=end and arr[i]<k): |
| 91 | + i+=1 |
| 92 | + while(j>=start and arr[j]>k): |
| 93 | + j-=1 |
| 94 | + if(i>j): |
| 95 | + break |
| 96 | + arr[i],arr[j] = arr[j],arr[i] |
| 97 | + arr[pivot],arr[j] = arr[j],arr[pivot] |
| 98 | + return j |
| 99 | +def exactmedianpivot(arr,start,end): |
| 100 | + vals = arr[start:end+1] |
| 101 | + s,e = 0,len(vals)-1 |
| 102 | + while(abs(s-e)>1): |
| 103 | + j = hoarepartition(vals,s,e,s) |
| 104 | + if(j>len(vals)//2): |
| 105 | + e = j-1 |
| 106 | + else: |
| 107 | + s = j+1 |
| 108 | + #print(s,e,vals,arr,start,end) |
| 109 | + return s+start |
| 110 | +def exactmedianpivotthetan(arr,start,end): |
| 111 | + return arr.index(select(arr[start:end+1],(end-start+1)//2)) |
| 112 | +def select(arr,i): |
| 113 | + if(len(arr)<10): |
| 114 | + arr.sort() |
| 115 | + return arr[i] |
| 116 | + meds = [] |
| 117 | + for i in range(len(arr)//5): |
| 118 | + meds.append(select(arr[5*i:5*(i+1)],2)) |
| 119 | + x = select(meds,len(meds)//2) |
| 120 | + numless = 0 |
| 121 | + for j in arr: |
| 122 | + if(j < x): |
| 123 | + numless+=1 |
| 124 | + if(numless==i): |
| 125 | + return x |
| 126 | + elif(numless<i): |
| 127 | + return select([j for j in arr if j>x],i-numless-1) |
| 128 | + else: |
| 129 | + return select([j for j in arr if j<x],i) |
| 130 | + |
| 131 | +#quicksort(doshuffle, pivot determination, partition scheme) |
| 132 | +quicksortlthrees = quicksort(True,leftpivot,scanpartition) |
| 133 | +quicksorthoare = quicksort(True,leftpivot,hoarepartition) |
| 134 | +quicksortexact = quicksort(False,exactmedianpivot,hoarepartition) |
| 135 | +quicksortexactthetan = quicksort(False,exactmedianpivotthetan,hoarepartition) |
| 136 | +#validate(quicksortexactthetan) |
| 137 | +#generatearrays(elems in array, number of arrays, randomize order) |
| 138 | +arrays = generatearrays(1000,5000, randomize = True) |
| 139 | +timealgorithm(arrays, lambda x: x.sort(),"Powersort") |
| 140 | +timealgorithm(arrays, mergesort,"Mergesort") |
| 141 | +timealgorithm(arrays, quicksortlthrees,"QuicksortL3S") |
| 142 | +timealgorithm(arrays, quicksorthoare,"QuicksortHoare") |
| 143 | +timealgorithm(arrays, quicksortexact,"QuicksortExactMedian") |
| 144 | +timealgorithm(arrays, quicksortexactthetan,"QuicksortPickMedian") |
0 commit comments