def insertion_sort(A): j = 1 while j < len(A): key = A[j] i = j - 1 while (i >= 0) and (A[i] > key): A[i + 1] = A[i] i = i -1 A[i + 1] = key j = j + 1 B = [5, 4, 6, 3, 7, 2, 8, 1, 9] print B insertion_sort(B) print B def invariant(A, original_A): l1 = list(A) l2 = list(original_A) l2.sort() return l1 == l2 invariant([1, 2, 3, 4], [4, 3, 2, 1]) invariant([1, 2, 3, 4, 4], [4, 3, 2, 1, 5]) def right_insertion_sort(A): original_A = list(A) j = 1 assert invariant(A[0:j], original_A[0:j]) while j < len(A): assert invariant(A[0:j], original_A[0:j]) key = A[j] i = j - 1 while (i >= 0) and (A[i] > key): A[i + 1] = A[i] i = i -1 A[i + 1] = key j = j + 1 assert invariant(A[0:j], original_A[0:j]) B = [5, 4, 6, 3, 7, 2, 8, 1, 9] right_insertion_sort(B) print B def wrong_insertion_sort(A): original_A = list(A) j = 1 try: assert invariant(A[0:j], original_A[0:j]) while j < len(A): assert invariant(A[0:j], original_A[0:j]) key = A[j] i = j - 1 while (i >= 0) and (A[i] < key): A[i + 1] = A[i] i = i - 1 A[i + 1] = key j = j + 1 assert invariant(A[0:j], original_A[0:j]) except AssertionError: print "Error en el invariante de ciclo!" print "j=", j print "i=", i print "A=", A print "Original A=", original_A B = [5, 4, 6, 3, 7, 2, 8, 1, 9] wrong_insertion_sort(B) class Counter: ''' Class Counter Implements a step counter, which is used to compute the number of basic operations performed in a particular call to a function. ''' def __init__(self): self.steps = 0 def reset(self): self.steps = 0 def count(self): self.steps += 1 def print_steps(self): print "Number of steps =", self.steps def acct_insertion_sort(A, acct): j = 1; acct.count() acct.count() while j < len(A): acct.count() key = A[j]; acct.count() i = j - 1; acct.count() acct.count() while (i >= 0) and (A[i] > key): acct.count() A[i + 1] = A[i]; acct.count() i = i -1; acct.count() A[i + 1] = key; acct.count() j = j + 1; acct.count() B = [5, 4, 6, 3, 7, 2, 8, 1, 9,10] acct = Counter() acct_insertion_sort(B, acct) acct.print_steps() import random as rnd def exper_analysis(n): results = [] acct = Counter() for i in range(n): l = range(i) rnd.shuffle(l) acct.reset() acct_insertion_sort(l, acct) results.append(acct.steps) return results print exper_analysis(10) import numpy as np import pylab as pl pl.clf() x = np.arange(100) y = np.array(exper_analysis(100)) pl.plot(x, y, 'k.')