Fixed sorting_algorithms

This commit is contained in:
madmaurice 2015-11-13 02:42:25 +01:00
parent c54dfca75d
commit a5ee847442

View file

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