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 = 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 = 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 result = SortTester(list( SortAlgorithm.__subclasses__() )).test(size=size) for cls, r in result.items(): print "%-12s: %10d, %d compares, %d swaps" % (cls.__name__, r[0]+r[1], r[0],r[1]) def test(): print HeapSort().sort([randint(0,500) for i in range(0,100)]) if __name__ == '__main__': main()