one-file-projects/sorting_algorithms.py

215 lines
4.7 KiB
Python

from random import randint
from time import clock
from sys import argv
class SortAlgorithm(object):
def __init__(self):
self.swaps = 0
self.vgls = 0
def sort(self,a):
raise Exception("Fail")
def swap(self,a,i,j):
self.swaps += 1
a[i],a[j] = a[j],a[i]
def set(self,a,i,v):
self.swaps += 1
a[i] = v
def vgl(self,b):
self.vgls += 1
return b
class BubbleSort(SortAlgorithm):
def sort(self,a):
n = len(a)
swapped = True
while swapped and n > 1:
swapped = False
for i in range(0,n-1):
if self.vgl(a[i] > a[i+1]):
self.swap(a,i,i+1)
swapped = True
n-=1
return a
class InsertSort(SortAlgorithm):
def sort(self,a):
for i in range(1,len(a)):
t = a[i]
j = i-1
while j >= 0 and self.vgl(a[j] > t):
self.set(a,j,a[j+1])
j-=1
#a[j+1] = t
self.set(a, j+1, t)
return a
class QuickSort(SortAlgorithm):
def sort(self,a):
self.qsort(a, 0, len(a)-1)
return a
def qsort(self,a, left, right):
if left < right:
pivot = self.seperate(a, left, right)
self.qsort(a, left, pivot - 1)
self.qsort(a, pivot+1, right)
def seperate(self, a, left, right):
i = left
j = right-1
pivot = a[right]
while i < j:
while self.vgl(a[i] <= pivot) and i < right: i+=1
while self.vgl(a[j] >= pivot) and j > left: j-=1
if i < j:
self.swap(a,i,j)
if a[i] > pivot:
self.swap(a,i,right)
return i
class HeapSort(SortAlgorithm):
def sort(self,a):
self.heapsort(a)
return list(reversed(a))
def heapify(self, data, i, w):
#indexes = filter(lambda v: v < w, [i,2*(i+1)-1,2*(i+1)])
#largest = max(indexes,key=lambda v: data[v])
r = 2*(i+1)
l = r-1
largest = i
if l < w and self.vgl(data[l] < data[largest]):
largest = l
if r < w and self.vgl(data[r] < data[largest]):
largest = r
if largest != i:
self.swap(data,i,largest)
self.heapify(data, largest, w)
def build_heap(self, data):
w = len(data)
i = int(w/2-1)
while i>=0:
self.heapify(data, i, w)
i-=1
def heapsort(self,data):
self.build_heap(data)
i = len(data)-1
while i > 0:
self.swap(data,i,0)
self.heapify(data, 0, i)
i-=1
class MergeSort(SortAlgorithm):
def sort(self, a):
return self.mergesort(a)
def mergesort(self,a):
if len(a) <= 1:
return a
else:
n = int(len(a)/2);
return self.merge(self.mergesort(a[:n] or []), self.mergesort(a[n:] or []))
def merge(self,a,b):
l = []
while True:
if len(a) == 0:
l += b
break
if len(b) == 0:
l += a
break
if self.vgl(a[0] < b[0]):
l.append(a[0])
a = a[1:]
else:
l.append(b[0])
b = b[1:]
self.swaps+=1
return l
class ShellSort(SortAlgorithm):
def sort(self,a):
spalten = [2147483647, 1131376761, 410151271, 157840433, 58548857, 21521774, 8810089, 3501671, 1355339, 543749, 213331,
84801, 27901, 11969, 4711, 1968, 815, 271, 111, 41, 13, 4, 1]
for k in range(0,23):
h = spalten[k]
for i in range(h,len(a)):
t = a[i]
j = i
while j>=h and self.vgl(a[j-h]>t):
#a[j] = a[j-h]
self.swap(a,j,j-h)
j-=h
a[j] = t
return a
class SelectSort(SortAlgorithm):
def sort(self,a):
n = len(a)
left = 0
while left < n:
m = left
for i in range(left,n):
if self.vgl(a[i] < a[m]):
m = i
self.swap(a,m,left)
left+=1
return a
class SortTester:
def __init__(self, algorithms):
self.algorithms = algorithms
def test(self, size=1000):
results = {}
data = list([ randint(0, size) for i in range(0,size) ])
for algorithm in self.algorithms:
print("Testing %s..." % algorithm.__name__)
inst = algorithm()
c = data[:]
s = inst.sort(c)
if not SortedTest().test(s):
raise Exception(algorithm.__name__+" failed to sort")
results[algorithm] = (inst.vgls,inst.swaps)
return results
class SortedTest:
def test(self, a):
v = a[0]
for n in a[1:]:
if v > n:
return False
v = n
return True
def main():
try:
size = int( argv[1])
except Exception:
size= 1000
print("Benchmarking using %d elements" % size)
result = SortTester(list( SortAlgorithm.__subclasses__() )).test(size=size)
for cls, r in sorted(result.items(),key=lambda e: e[1][0]+e[1][1]):
print("%-12s: %10d, %10d compares, %10d swaps" % (cls.__name__, r[0]+r[1], r[0],r[1]))
if __name__ == '__main__':
main()