Browse Source

Added Heapsort implementation and documentation to sorting.py

Miguel E Cruz 2 years ago
parent
commit
4fa793f545
1 changed files with 83 additions and 7 deletions
  1. 83
    7
      sorting.py

+ 83
- 7
sorting.py View File

@@ -4,7 +4,7 @@ Carlos J Corrada Bravo
4 4
 Este programa calcula el promedio de tiempo de ejecución de cuatro algoritmos de ordenamiento
5 5
 La variable maxValor define el valor maximo de los elementos de la lista
6 6
 La variable largoLista define el largo de las listas a ordenar
7
-La variable veces define las veces que se va a hacer el ordenamiento 
7
+La variable veces define las veces que se va a hacer el ordenamiento
8 8
 Al final se imprimen los promedios de cada algortimo
9 9
 """
10 10
 from random import randint
@@ -17,9 +17,85 @@ def mergeSort(lista):
17 17
 	#definan el algoritmo de ordenamiento mergesort
18 18
 	return lista
19 19
 
20
+"""La siguiente implementación del algoritmo 'Heapsort'
21
+fue implementada por Miguel E. Cruz Molina, siguiendo
22
+el diseño propuesto en el libro 'Introduction to
23
+Algorithms' (2009, 3rd ed.), de Cormen, T. H. et al."""
24
+
20 25
 def heapSort(lista):
21
-	#definan el algoritmo de ordenamiento heapsort
22
-	return lista
26
+  """Esta función toma una lista de números y los ordena
27
+  usando el algoritmo 'heapsort', que repetitivamente
28
+  convierte a los elementos no-ordenados en un montículo
29
+  maximal y sustituye el elemento mayor por el último."""
30
+
31
+  # El algoritmo primero genera un montículo maximal
32
+  #   con los elementos en la lista:
33
+  buildHeap(lista, len(lista) - 1)
34
+
35
+  # Por cada uno de los elementos en la lista,
36
+  for i in range(len(lista) - 1, 0, -1):
37
+
38
+    # Se sustituye el elemento en la raíz del montículo
39
+    #   (el elemento más grande) con el último,
40
+
41
+    print(lista)
42
+    temp = lista[i]
43
+    lista[i] = lista[0]
44
+    lista[0] = temp
45
+    print(lista)
46
+
47
+    # Y se genera un montículo con los elementos
48
+    #   restantes, hasta terminar con la lista ordenada.
49
+
50
+    buildHeap(lista, i)
51
+
52
+  return lista
53
+
54
+def buildHeap(lista, heapsize):
55
+  """Esta función toma a una lista de números y la
56
+  convierte en una representación lineal de un montículo
57
+  maximal, i.e. un árbol binario en el que el contenido
58
+  de todo nodo padre (de índice k) es mayor al de sus
59
+  hijos (de índices 2k + 1 y 2k + 2). Este proceso se
60
+  realiza recursivamente, desde el penúltimo 'nivel'
61
+  del árbol hasta la raíz, usando la función auxiliar
62
+  'maxHeapify()'. """
63
+
64
+  for i in range((heapsize-1)//2, -1, -1):
65
+    maxHeapify(lista, i, heapsize)
66
+
67
+def maxHeapify(lista, k, heapsize):
68
+  """Esta función tiene como propósito garantizar que
69
+  la propiedad maximal de un montículo se conserve,
70
+  intercambiando el valor de un nodo padre por el mayor
71
+  valor de entre sus nodos hijos de ser necesario, y
72
+  aplicando el mismo algoritmo sobre el subárbol de ese
73
+  hijo de forma recursiva. La función recibe tres
74
+  argumentos: la lista que contiene el montículo,
75
+  el índice de la raíz del montículo a considerarse,
76
+  y el límite del montículo mayor, que no necesariamente
77
+  es equivalente al largo de la lista."""
78
+
79
+  # Primero se identifican los índices hipotéticos
80
+  #   de los nodos hijos:
81
+  l = 2 * k + 1; r = 2 * k + 2; max = k
82
+
83
+  # Identificar cuál de los tres nodos tiene el mayor
84
+  #   valor.
85
+
86
+  if l < heapsize and lista[max] < lista[l]: max = l
87
+  if r < heapsize and lista[max] < lista[r]: max = r
88
+
89
+  # Si el nodo padre no es el mayor, intercambiarlo
90
+  #   por el nodo hijo con mayor valor, y llamar la
91
+  #   función de modo recursivo sobre el subárbol de
92
+  #   ese hijo.
93
+
94
+  if max != k:
95
+    temp = lista[k]
96
+    lista[k] = lista[max]
97
+    lista[max] = temp
98
+    maxHeapify(lista, max, heapsize)
23 99
 
24 100
 def quickSort(lista):
25 101
 	#definan el algoritmo de ordenamiento quicksort
@@ -61,7 +137,7 @@ def shellSort(lista):
61 137
 
62 138
 maxValor=1000 	#define el valor maximo de los elementos de la lista
63 139
 largoLista=1000 #define el largo de las listas a ordenar
64
-veces=100 		#define las veces que se va a hacer el ordenamiento 
140
+veces=100 		#define las veces que se va a hacer el ordenamiento
65 141
 
66 142
 acumulaMerge=0 	#variable para acumular el tiempo de ejecucion del mergesort
67 143
 acumulaHeap=0 	#variable para acumular el tiempo de ejecucion del heapsort
@@ -80,15 +156,15 @@ for i in range(veces):
80 156
 	t1 = time.clock() 				#seteamos el tiempo al empezar
81 157
 	mergeSort(listaMerge) 				#ejecutamos el algoritmo mergeSort
82 158
 	acumulaMerge+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
83
-	
159
+
84 160
 	t1 = time.clock()				#seteamos el tiempo al empezar
85 161
 	heapSort(listaHeap)					#ejecutamos el algoritmo heapSort
86 162
 	acumulaHeap+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
87
-	
163
+
88 164
 	t1 = time.clock()				#seteamos el tiempo al empezar
89 165
 	quickSort(listaQuick)				#ejecutamos el algoritmo quickSort
90 166
 	acumulaQuick+=time.clock()-t1 	#acumulamos el tiempo de ejecucion
91
-	
167
+
92 168
 	t1 = time.clock()				#seteamos el tiempo al empezar
93 169
 	shellSort(listaShell)				#ejecutamos el algoritmo shellSort
94 170
 	acumulaShell+=time.clock()-t1 	#acumulamos el tiempo de ejecucion