Browse Source

Added Heapsort algorithm

dylan.cedres 2 years ago
parent
commit
3856a55a76
1 changed files with 73 additions and 63 deletions
  1. 73
    63
      sorting.py

+ 73
- 63
sorting.py View File

@@ -8,45 +8,53 @@ Al final se imprimen los promedios de cada algortimo
8 8
 """
9 9
 from random import randint
10 10
 import time
11
-from copy import deepcopy
12
-import sys
11
+from heapq import heapify, heappush
13 12
 
14
-# This function was created to prevent program from stopping before recursion finished
15
-# Changes python's recursion limit
16
-class recursion_depth:
17
-    def __init__(self, limit):
18
-        self.limit = limit
19
-        self.default_limit = sys.getrecursionlimit()
20
-
21
-    def __enter__(self):
22
-        sys.setrecursionlimit(self.limit)
13
+def mergeSort(lista):
14
+	#definan el algoritmo de ordenamiento mergesort
15
+	return lista
23 16
 
24
-    def __exit__(self, type, value, traceback):
25
-        sys.setrecursionlimit(self.default_limit)
17
+def heapSort(lista):
18
+	#definan el algoritmo de ordenamiento heapsort
19
+	# Dylan A. Cedres Rivera
26 20
 
27
-# Mergesort algorithm
28
-def mergeSort(lista): # Ángel G. Romero Rosario on 10082022
21
+	"""
22
+	Heapsort se conoce por ser un algoritmo de ordenamiento con las caracteristicas de un arbol binario, 
23
+		en donde cada nodo puede tener un maximo de hasta dos hijos, cumpliendo con las restricciones
24
+		de que el primer nodo debe ser el "nodo padre" (primer elemento en la lista, no puede ser hijo de otro nodo) y
25
+		las "hojas" del arbol binario deben ser solo "nodos hijos" (ultimos elementos de la lista, no pueden ser padres de otros nodos).
29 26
 	
30
-	def merge(l1, l2):
31
-		if len(l1) == 0:
32
-			return l2
33
-		elif len(l2) == 0:
34
-			return l1
35
-		elif l1[0] < l2[0]:
36
-			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
37
-		else:
38
-			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
27
+	El orden del heapsort puede ser MinHeap (menor a mayor), 
28
+		en donde el nodo padre del arbol binario es el elemento mas pequeno de la lista, 
29
+		o puede ser MaxHeap (mayor a menor), en donde el nodo padre es el elemento mas grande de la lista.
30
+	"""
31
+
32
+	# Nuevo heap para insertar los elementos de lista creada con numeros aleatorios
33
+	myHeap = []
34
+	heapify(myHeap)
35
+
36
+	# Se copian los elementos de lista al heap y se ordenan de menor a mayor los elementos con cada push.
37
+	# Todos los elementos se les asigna un signo contrario al que tienen, para poder crear un MaxHeap, de manera
38
+	# 	que los numeros mas grandes se convierten en los mas pequenos.
39
+	# Si se quiere hacer un MinHeap, la instruccion de multiplicar por -1 no es neceseria 
40
+	for element in lista:
41
+		heappush(myHeap, -1 * element)
42
+
43
+	# print("lista antes de 'heapificar'", lista)
44
+
45
+
46
+	# Este loop se utiliza para crear un MaxHeap, de manera que le devuelve el signo original que tenian los 
47
+	#	elementos antes de que se anadieran al heap.
48
+	# Esto significa que los elementos mas pequenos, se convierten en los mas grandes, dejando la forma de un MaxHeap,
49
+	#	con el numero mas grande quedando como el nodo padre del arbol binario.
50
+	# Si se quiere hacer un MinHeap, este loop no se necesita. 
51
+	for i in range(len(myHeap)):
52
+		myHeap[i] = myHeap[i] * -1
53
+
54
+	# print("lista 'heapificada'", myHeap)
39 55
 	
40
-	if len(lista) <= 1:								# If there are no more items, return lista
41
-		return lista
42
-
43
-	else:
44
-		mid = len(lista) // 2 						# Find the middle in lista and call function to merge lista
45
-		return merge(mergeSort(lista[:mid]), mergeSort(lista[mid:]))
46
-
47
-
48
-def heapSort(lista):
49
-	#definan el algoritmo de ordenamiento heapsort
56
+	# Copia los elementos del heap ordenado de vuelta a la lista inicialmente generada y la devuelve
57
+	lista = myHeap
50 58
 	return lista
51 59
 
52 60
 def quickSort(lista):
@@ -57,39 +65,41 @@ def shellSort(lista):
57 65
 	#definan el algoritmo de ordenamiento shellsort
58 66
 	return lista
59 67
 
60
-# timeCode function/thunk -> (duration, return value)
61
-# measures the time it takes for a function/thunk to return
62
-def timeCode(fn):
63
-	t1 = time.perf_counter()
64
-	res = fn()
65
-	duration = time.perf_counter() - t1
66
-	return (duration, res)
67
-
68
-maxValor = 1000 	#define el valor maximo de los elementos de la lista
69
-largoLista = 1000   #define el largo de las listas a ordenar
70
-veces = 100 		#define las veces que se va a hacer el ordenamiento
68
+maxValor=1000 	#define el valor maximo de los elementos de la lista
69
+largoLista=1000 #define el largo de las listas a ordenar
70
+veces=100 		#define las veces que se va a hacer el ordenamiento 
71 71
 
72
-acumulaMerge = 0 	#variable para acumular el tiempo de ejecucion del mergesort
73
-acumulaHeap = 0 	#variable para acumular el tiempo de ejecucion del heapsort
74
-acumulaQuick = 0 	#variable para acumular el tiempo de ejecucion del quicksort
75
-acumulaShell = 0 	#variable para acumular el tiempo de ejecucion del shellsort
72
+acumulaMerge=0 	#variable para acumular el tiempo de ejecucion del mergesort
73
+acumulaHeap=0 	#variable para acumular el tiempo de ejecucion del heapsort
74
+acumulaQuick=0 	#variable para acumular el tiempo de ejecucion del quicksort
75
+acumulaShell=0 	#variable para acumular el tiempo de ejecucion del shellsort
76 76
 
77 77
 for i in range(veces):
78 78
 	mergelista = [randint(0,maxValor) for r in range(largoLista)] #creamos una lista con valores al azar
79
-	heaplista = deepcopy(mergelista)
80
-	quicklista = deepcopy(mergelista)
81
-	searchlista = deepcopy(mergelista)
79
+	heaplista=list(mergelista)
80
+	quicklista=list(mergelista)
81
+	searchlista=list(mergelista)
82 82
 
83
-	with recursion_depth(1100): # This function excedes python's recursion limit
84
-		acumulaMerge += timeCode(lambda: mergeSort(mergelista))[0]
85
-
86
-	acumulaHeap += timeCode(lambda: heapSort(heaplista))[0]
87
-	acumulaQuick += timeCode(lambda: quickSort(quicklista))[0]
88
-	acumulaShell += timeCode(lambda: shellSort(searchlista))[0]
83
+	t1 = time.clock() 				#seteamos el tiempo al empezar
84
+	mergeSort(mergelista) 				#ejecutamos el algoritmo mergeSort
85
+	acumulaMerge+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
86
+	
87
+	t1 = time.clock()				#seteamos el tiempo al empezar
88
+	heapSort(heaplista)					#ejecutamos el algoritmo heapSort
89
+	acumulaHeap+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
90
+	
91
+	t1 = time.clock()				#seteamos el tiempo al empezar
92
+	quickSort(quicklista)				#ejecutamos el algoritmo quickSort
93
+	acumulaQuick+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
94
+	
95
+	t1 = time.clock()				#seteamos el tiempo al empezar
96
+	shellSort(searchlista)				#ejecutamos el algoritmo shellSort
97
+	acumulaShell+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
89 98
 
90 99
 #imprimos los resultados
91
-print(f"Promedio de tiempo de ejecucion de {str(veces)} listas de largo {str(largoLista)}")
92
-print(f"MergeSort {str(acumulaMerge / veces)} segundos")
93
-print(f"HeapSort {str(acumulaHeap / veces)} segundos")
94
-print(f"QuickSort {str(acumulaQuick / veces)} segundos")
95
-print(f"ShellSort {str(acumulaShell / veces)} segundos")
100
+print( "Promedio de tiempo de ejecucion de "+ str(veces) +" listas de largo " + str(largoLista) )
101
+# print( "MergeSort " + str(acumulaMerge/veces) + " segundos" )
102
+print( "HeapSort " + str(acumulaHeap/veces) + " segundos" )
103
+# print( "QuickSort " + str(acumulaQuick/veces) + " segundos" )
104
+# print( "ShellSort " + str(acumulaShell/veces) + " segundos" )
105
+