Sin descripción

sorting.py 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. """
  2. Carlos J Corrada Bravo
  3. Este programa calcula el promedio de tiempo de ejecucion de cuatro algoritmos de ordenamiento
  4. La variable maxValor define el valor maximo de los elementos de la lista
  5. La variable largoLista define el largo de las listas a ordenar
  6. La variable veces define las veces que se va a hacer el ordenamiento
  7. Al final se imprimen los promedios de cada algortimo
  8. """
  9. from random import randint
  10. import time
  11. from copy import deepcopy
  12. import sys
  13. # This function was created to prevent program from stopping before recursion finished
  14. # Changes python's recursion limit
  15. class recursion_depth:
  16. def __init__(self, limit):
  17. self.limit = limit
  18. self.default_limit = sys.getrecursionlimit()
  19. def __enter__(self):
  20. sys.setrecursionlimit(self.limit)
  21. def __exit__(self, type, value, traceback):
  22. sys.setrecursionlimit(self.default_limit)
  23. # Mergesort algorithm
  24. def mergeSort(lista): # Ángel G. Romero Rosario on 10082022
  25. def merge(l1, l2):
  26. if len(l1) == 0:
  27. return l2
  28. elif len(l2) == 0:
  29. return l1
  30. elif l1[0] < l2[0]:
  31. return l1[0:1] + merge(l1[1:],l2) # If l1[0] < l2[0] save l1[0] first to the list and call the function again
  32. else:
  33. return l2[0:1] + merge(l1, l2[1:]) # If l2[0] < l1[0] save l2[0] first to the list and call the function again
  34. if len(lista) <= 1: # If there are no more items, return lista
  35. return lista
  36. else:
  37. mid = len(lista) // 2 # Find the middle in lista and call function to merge lista
  38. return merge(mergeSort(lista[:mid]), mergeSort(lista[mid:]))
  39. def heapSort(lista):
  40. #definan el algoritmo de ordenamiento heapsort
  41. return lista
  42. def quickSort(lista):
  43. #definan el algoritmo de ordenamiento quicksort
  44. if(len(lista) != 0):
  45. if(len(lista) == 1):
  46. return lista
  47. else:
  48. p = lista[0]
  49. for i in lista[1:]:
  50. if(p > i):
  51. x = i
  52. del lista[lista.index(i)]
  53. lista.insert(lista.index(p), x)
  54. l = quickSort(lista[ :lista.index(p)])
  55. m = quickSort(lista[lista.index(p) + 1:])
  56. if(m != None and l != None):
  57. return l + lista[lista.index(p):lista.index(p) + 1] + m
  58. elif(m == None):
  59. return l + lista[lista.index(p):lista.index(p) + 1]
  60. elif(l == None):
  61. return lista[lista.index(p):lista.index(p) + 1] + m
  62. # inplace
  63. # complexity: O(N^2)
  64. def shellSort(lst):
  65. # initial gap
  66. gap = len(lst)
  67. while 0 < gap:
  68. # sort every sublist with given gap
  69. for start in range(gap):
  70. f = range(start, len(lst), gap)
  71. s = range(start + gap, len(lst), gap)
  72. # bubble sort on sublist
  73. swapped = True
  74. while swapped:
  75. swapped = False
  76. # iterate through every adjacent pair in sublist
  77. for c, n in zip(f, s):
  78. if lst[n] < lst[c]:
  79. lst[c], lst[n] = lst[n], lst[c]
  80. swapped = True
  81. # reduce gap towards 0
  82. gap = gap // 2
  83. return lst
  84. # timeCode function/thunk -> (duration, return value)
  85. # measures the time it takes for a function/thunk to return
  86. def timeCode(fn):
  87. t1 = time.perf_counter()
  88. res = fn()
  89. duration = time.perf_counter() - t1
  90. return (duration, res)
  91. maxValor = 1000 #define el valor maximo de los elementos de la lista
  92. largoLista = 1000 #define el largo de las listas a ordenar
  93. veces = 100 #define las veces que se va a hacer el ordenamiento
  94. acumulaMerge = 0 #variable para acumular el tiempo de ejecucion del mergesort
  95. acumulaHeap = 0 #variable para acumular el tiempo de ejecucion del heapsort
  96. acumulaQuick = 0 #variable para acumular el tiempo de ejecucion del quicksort
  97. acumulaShell = 0 #variable para acumular el tiempo de ejecucion del shellsort
  98. for i in range(veces):
  99. mergelista = [randint(0,maxValor) for r in range(largoLista)] #creamos una lista con valores al azar
  100. heaplista = deepcopy(mergelista)
  101. quicklista = deepcopy(mergelista)
  102. searchlista = deepcopy(mergelista)
  103. with recursion_depth(1500): # This function excedes python's recursion limit
  104. acumulaMerge += timeCode(lambda: mergeSort(mergelista))[0]
  105. acumulaHeap += timeCode(lambda: heapSort(heaplista))[0]
  106. acumulaQuick += timeCode(lambda: quickSort(quicklista))[0]
  107. acumulaShell += timeCode(lambda: shellSort(searchlista))[0]
  108. #imprimos los resultados
  109. print(f"Promedio de tiempo de ejecucion de {str(veces)} listas de largo {str(largoLista)}")
  110. print(f"MergeSort {str(acumulaMerge / veces)} segundos")
  111. print(f"HeapSort {str(acumulaHeap / veces)} segundos")
  112. print(f"QuickSort {str(acumulaQuick / veces)} segundos")
  113. print(f"ShellSort {str(acumulaShell / veces)} segundos")