Está en la página 1de 22

Carátula para entrega de prácticas

Facultad de Ingeniería Laboratorio de docencia

Laboratorios de computación
salas A y B
Profesor: Edgar Tista García

Asignatura: Estructuras de datos y algoritmos II

Grupo: 10

No de Práctica(s): 1

Integrante(s): Belmont Muñoz Samuel


No. de Equipo de
cómputo empleado:

No. de Lista o Brigada:

Semestre: Tercero

Fecha de entrega: 1 de Septiembre del 2022

Observaciones:

CALIFICACIÓN: __________
Objetivo general: El estudiante identificará la estructura de los algoritmos de ordenamiento
InsertionSort, SelectionSort y BubbleSort.
Objetivo de la clase: El alumno revisará el uso de bibliotecas como capas de abstracción, así́ como
realización de pruebas de los algoritmos para diferentes instancias de colecciones para conocer la
complejidad de estos.
Desarrollo.
I. Análisis inicial.
En el archivo de ordenamiento.c encontramos los algoritmos de insertion sort como selection
sort implementados en el lenguaje de programación C.
Dentro de dichos algoritmos encontramos la instrucción de la impresión del número de iteración
junto con la impresión del estado del array en esa iteración.
En el archivo llamado “utilidades” encontramos las funciones auxiliares que nos ayudarán en la
realización de la práctica 1, como es la función que realiza la operación de intercambio.
También, encontramos la función que imprime el arreglo completo y por último encontramos la
función que imprime una porción determinada de un arreglo ingresado como parámetro.
En mis cursos anteriores he trabajado con funciones similares, por lo que me encuentro
familiarizado con dichas operaciones y dichos algoritmos.

Una vez agregado el algoritmo de bubble sort, se modificó el código para que se detenga en el
momento que la lista se encuentre ordenada. Quedando de la siguiente manera:
II. Probando los ordenamientos.

Llenado aleatorio del arreglo y ordenado por insertion sort.


Llenado manual y ordenado por Selection sort.
Llenado con el peor de los casos y ordenado por bubble sort.
Puntos más importantes al modificar el programa para el ejercicio 2:
• Se implementó una captura de errores en caso de que el usuario decidiera ingresar una
entrada inválida. Un carácter, una cadena formada por números y letras, una cadena de
puro caracteres alfabéticos o especiales, o simplemente cualquier número no solicitado,
serían causa de una entrada inválida y por lo tanto no ingresaría a ninguna otra parte de
la ejecución hasta que se ingresara una entrada válida.
• Se hizo un menú de modo de ejecución del programa dependiendo a la actividad
solicitada, en este caso, es el ejercicio 2. Más adelante se ocuparán los otros modos.
• Se condicionó la impresión del arreglo por iteración en cada ordenamiento. Esta
ejecución solo se hará en caso de que el tamaño del arreglo sea 20 o para fines prácticos,
cuando se ejecute el modo “ejercicio 2”.
• Se abrieron más archivos de encabezado y sus respectivos archivos para inclusión de
más funciones y así modularizar de manera más efectiva el programa, ayudando también
a la depuración de errores encontrados a lo largo del desarrollo de esta actividad y las
posteriores.
Verificación de la modificación realizada en bubble sort.

Evidencia de que sí se realizó correctamente la modificación a BS.


III. Análisis de complejidad computacional.
a. Insertion Sort
Para la realización de las pruebas de la complejidad de este algoritmo, se colocó un
contador en cada operación del algoritmo, incluyendo las comparaciones, las
inserciones, los intercambios, los incrementos y las asignaciones de variables auxiliares.
Es decir, a cada sentencia se le dio un contador.
Antes de la realización de las pruebas, se realizó de manera manual el análisis de
complejidad de este algoritmo obteniendo los polinomios del mejor de los casos y del
peor de los casos. Cabe mencionar que se colocó la función Sleep(1000) para que
cambiará la semilla de generación de los números aleatorios y así no tener los mismos
valores.
Para la obtención del polinomio del mejor de los
casos:
1. 3
2. 1 + n
3. .
4. …
Se espera que haya 4 instrucciones que se van a
ejecutar una sola vez en todo el programa (tres
declaraciones y una asignación). Sin embargo, la
línea 2 tiene una comparación que se realizará n
veces, siendo n el tamaño del arreglo.

Línea 3, 4 7 9.
3. n-1
4. n-1
5. …
9. n-1
Ya que se encuentran inmediatamente dentro de un for, estas van a depender de la
comparación de la línea 2, lo cual significa que se ejecutarán una vez menos que la
comparación (n-1).
Líneas 5 a 7
5. (n-1) + (n-1)
6. 0
7. 0
La línea 6 y 7 dependen de la 5, si ambas condiciones son verdaderas, se ejecutarán las
líneas 6 y 7.
Ya que es el mejor de los casos, los arreglos se encuentran ordenados, por lo que la
línea 5 se ejecutará solo una vez por iteración (ambas condiciones) y las líneas 6 y 7 no
se ejecutarán.

Línea 2.
Regresando a la línea 2, notamos que se encuentra un incremento, y ya que, este
depende de la condición de la línea 2, se ejecutará n-1 veces. Por lo que el análisis del
mejor de los casos de insertion sort quedaría de la siguiente manera:
1.3
2.1+n+(n-1)
3.n-1
4.n-1
5.n-1 + n-1
6.0
7.0
8….
9.n-1
Sumando y simplificando, el polinomio quedaría como: 7n-2

Insertion Sort Mejor Caso


80000

70000

60000

50000

40000

30000

20000

10000

0
0 2000 4000 6000 8000 10000 12000

Para la obtención del peor de los casos:


Centrémonos en las líneas 5 a 7, ya que estas cambiarán cuando se trate del peor de los
casos.
La línea 5 cuenta con dos instrucciones, las cuales mutuamente dependen de si, en el
peor de los casos, serán verdaderas. ¿Pero cuántas veces se ejecutan?
i j Ejecuciones
1 1,0 2
2 2,1,0 3
3 3,2,1,0 4

n-3 n-3,n-4,…,3,2,1,0 n-2
n-2 n-2, n-3,…,3,2,1,0 n-1
n-1 n-1, n-2,…, 3,2,1,0 n
Si usamos fórmula de la suma de los primeros n números, quedará que las ejecuciones
son n(n+1)/2 -1, esto en cuanto a la primera condición.
¿Pero qué sucede con la otra comparación?
Ejecuciones 1ra Ejecuciones de la 2da
condición condición.
2 1
3 2,
4 3

n-2 n-3
n-1 n-2
n n-1
Se ejecuta una vez menos que la primera condición, ya que, en su última comparación
siempre será falso, por lo que ahí rompe la condición y evita que se ejecuta la segunda
condición.
Esto igual aplica para las líneas 6 y 7, ya que, si dan verdadero las condiciones, se
ejecutarán las mismas veces que la segunda condición.
Así quedará la tabla de ejecuciones:
1.3
2.1+n+(n-1)
3.n-1
4.n-1
5.n(n+1)/2-1+n(n-1)/2
6. n(n-1)/2
7. n(n-1)/2
8….
9.n-1
Por lo que, el polinomio quedaría así: 2n^2+4n-1

Insertion Sort Peor Caso


250000000

200000000

150000000

100000000

50000000

0
0 2000 4000 6000 8000 10000 12000
-50000000
La ejecución de los casos aleatorios queda de la siguiente manera:
Con gráfica:

Insertion Sort Caso aleatorio


120000000

100000000

80000000

60000000

40000000

20000000

0
0 2000 4000 6000 8000 10000 12000
-20000000

Comparando resultados…

Insertion Sort
250000000

200000000

150000000

100000000

50000000

0
0 2000 4000 6000 8000 10000 12000

-50000000
b. Selection sort.
Para la realización de las pruebas de la complejidad de este algoritmo, se colocó un contador
en cada operación del algoritmo, incluyendo las comparaciones, las inserciones, los
intercambios, los incrementos y las asignaciones de variables auxiliares. Es decir, a cada
sentencia se le dio un contador.
Antes de la realización de las pruebas, se realizó de manera manual el análisis de
complejidad de este algoritmo obteniendo los polinomios del mejor de los casos y del peor
de los casos. Cabe mencionar que se colocó la función Sleep(1000) para que cambiará la
semilla de generación de los números aleatorios y así no tener los mismos valores.

Para la obtención del polinomio del mejor de los


casos:
1.3
2.1+ n
3..
4.…
Se espera que haya 4 instrucciones que se van a ejecutar una sola vez en todo el programa
(tres declaraciones y una asignación). Sin embargo, la línea 2 tiene una comparación que
se realizará n veces, siendo n el tamaño del arreglo.
Línea 3, 4 y 7.
3. n-1
4. n-1+…
7. n-1

Ya que se encuentran inmediatamente dentro del for principal, estas van a depender de la
comparación de la línea 2, lo cual significa que se ejecutarán una vez menos que la
comparación (n-1). Sin embargo, en la línea 4, esto solo aplica a la asignación inicial del for
secundario (j=i+1).
Líneas 4 a 6.
4. …+ n(n+1)/2 – 1 + n(n-1)/2
5. n(n-1)/2
6. 0
La línea 4 contiene una comparación que se ejecutará n(n+1)/2 veces, pero para demostrar
esto, veamos la siguiente tabla.
i j Ejecuciones
0 1, 2, 3, …, n n
1 2,3,4,…, n n-1
2 3,4,5,…, n n-2

n-3 n-3, n-2, n-1, n 4
n-2 n-2, n-1, n 3
n-1 n-1,n 2
Podemos notar diferencias con la tabla del anterior método de ordenamiento, sin embargo,
este también es una suma de los primeros n números menos 1, es decir, n(n+1)/2 -1.
Y de la misma manera que el anterior método de ordenamiento, lo que está dentro del for
secundario, se ejecutará una vez menos por iteración de este for. Es decir, n(n-1)/2 veces.
Para concluir el análisis del mejor de los casos de selection sort, podemos mencionar que
las líneas 6 y 8, no tienen ejecución, por lo que, quedaría así el análisis.
1.3
2.1 + n + n-1
3.n-1
4.n-1+ n(n+1)/2 – 1 + n(n-1)/2
5. n(n-1)/2
6.0
7.n-1
8.0
9….
Desarrollando y simplificando, el polinomio queda de la siguiente manera:
3/2n^2+9/2n-1

Con gráfica:

Selection Sort Mejor de los casos


160000000

140000000

120000000

100000000

80000000

60000000

40000000

20000000

0
0 2000 4000 6000 8000 10000 12000
-20000000

Para la obtención del peor de los casos:


Mi método para la obtención del peor de los casos fue dirigido de manera empírica,
obteniendo datos por ejecución, llegando a la conclusión con los siguientes datos:
n Suma de las ejecuciones de la línea 6.
10 25
20 100
30 225
100 2500
200 10000
500 62500
1000 1000000
Observando, además, que la suma de las ejecuciones va desde n-1 hasta 1, pero con
decremento de dos. Por lo que la suma de todos los primeros n-1 números con saltos de dos
en dos, dan como resultado n^2/4.
Con esto, se tiene el número de ejecuciones de la línea 6, sin embargo, aún no se tienen las
ejecuciones de la línea 8.
Las ejecuciones de la línea 8 no van más allá de lo obtenido para las ejecuciones de la línea
6, ya que, está relacionada con la instrucción ejecutada en dicha línea. Siendo que la variable
utilizada en la línea 6 va a ser partícipe de la comparación de la línea 7, por lo que, se
ejecutará de la misma cantidad de veces de forma lineal, es decir, se ejecutara n/2 veces.
1.3
2.1 + n + n-1
3.n-1
4.n-1+ n(n+1)/2 – 1 + n(n-1)/2
5. n(n-1)/2
6.n^2/4
7.n-1
8.n/2
9….

Con esto podemos obtener el polinomio:

Mejor de los casos + n^2/4+n/2= 7/4n^2+5n-1

Con gráfica:

Selection Sort Peor de los casos


200000000
180000000
160000000
140000000
120000000
100000000
80000000
60000000
40000000
20000000
0
-20000000 0 2000 4000 6000 8000 10000 12000
La ejecución de los casos aleatorios:
La gráfica de los casos aleatorios sería:

Selection Sort Casos aleatorios


160000000

140000000

120000000

100000000

80000000

60000000

40000000

20000000

0
0 2000 4000 6000 8000 10000 12000
-20000000

Comparando resultados…

Selection Sort
200000001 Casos aleatorios Peor de los casos Mejor

180000001

160000001

140000001

120000001

100000001

80000001

60000001

40000001

20000001

1
0 2000 4000 6000 8000 10000 12000

Notamos que no hay mucha diferencia entre el mejor de los casos y el promedio de ejecuciones
obtenido de las pruebas del programa.
c. Bubble sort.
Para la realización de las pruebas de la complejidad de este algoritmo, se colocó un
contador en cada operación del algoritmo, incluyendo las comparaciones, las
inserciones, los intercambios, los incrementos y las asignaciones de variables auxiliares.
Es decir, a cada sentencia se le dio un contador.
Antes de la realización de las pruebas, se realizó de manera manual el análisis de
complejidad de este algoritmo obteniendo los polinomios del mejor de los casos y del
peor de los casos. Cabe mencionar que se colocó la función Sleep(1000) para que
cambiará la semilla de generación de los números aleatorios y así no tener los mismos
valores.
Para la obtención del polinomio del mejor de los
casos:
1. 3
2. 1
3. 2
4. 1 + 1
Se espera que haya 7 instrucciones que se van a
ejecutar una sola vez en todo el programa (cuatro
declaraciones y tres asignaciones). Sin embargo,
la línea 2 tiene una comparación, que, en el mejor de los casos solo se ejecutará una
vez.
Líneas 5 y 6.
5. 1 + n + n-1
6. n-1
7. …
La línea 5 cuenta con tres instrucciones, j=0, j<i y j++, que, en el mejor de los casos, j=0
se ejecutará solo una vez, mientras que la comparación se ejecutará n veces, ya que,
cuando i = n-1, j inicia desde 0 y recorrerá el ciclo for n veces, es decir, se ejecutará solo
una vez el ciclo for, cumpliendo n iteraciones. La instrucción del decremento, como
sabemos, se ejecutará una vez menos que la comparación, siendo que se ejecutará n-1
veces.
La línea 6 sigue la misma norma que el decremento, siendo que se ejecutará n-1 veces.
Líneas 7 y 8.
En el mejor de los casos no se ejecutarán dichas las líneas 7 y 8.
Líneas 10 y 11.
En el mejor de los casos se ejecutarán solo una vez cada línea.
Teniendo en cuenta esto, el análisis quedaría como:
1. 3
2. 1
3. 2
4. 1 +1
5. 1 + n + n-1
6. n-1
7. 0
8. 0
9. …
10. 1
11. 1
Sumando y simplificando las ejecuciones obtenidas, el polinomio del mejor de los casos
quedaría como:
3n+9
Con gráfica:

Bubble Sort Mejor de los casos


35000

30000

25000

20000

15000

10000

5000

0
0 2000 4000 6000 8000 10000 12000
Para la obtención del peor de los casos:
1. 3
2. 1
3. 2
4. 1 + n
En el peor de los casos, sí se hará el ciclo for completo, por lo que, hará n iteraciones.
Para las líneas 5 a 6.
5. n-1 + n(n+1)/2-1+n (n-1)/2
6. n(n-1)/2
7. …
La línea 5 cuenta con tres instrucciones, una asignación, una comparación y un
decremento. La asignación se ejecutará n-1 veces, ya que se encuentre inmediatamente
después del for principal. La comparación en cambio, se ejecutará k veces por cada
iteración del for principal.
i j Ejecuciones
n-1 0, 1, 2,…n-3, n-2, n-1 n
n-2 0,1,2,…,n-3,n-2 n-1
n-3 0,1,2,…, n-3 n-2

2 0,1,2 3
1 0,1 2
Por lo que, la formula de la suma de los primeros n números serviría. Siendo que se
ejecutará n(n+1)/2-1

Ejecuciones de la Ejecuciones dentro del


condición for
n n-1
n-1 n-2
n-2 n-3

4 3
3 2
2 1
Siendo que la fórmula de la suma de los primeros n-1 números sirve. Entonces, se
ejecutará n(n-1)/2 veces el decremento.
La línea 6 obedece la misma norma que el decremento de la línea 5.
Líneas 7 y 8.
7. n (n-1)/2
8. n(n-1)/2
9. …
Ya que, en el peor de los casos la condición de la línea 6 será verdadera siempre,
entonces, estas líneas se ejecutarán las mismas veces que la línea 6.
Líneas 10 y 11.
Ya que, la condición de la línea 10 está inmediatamente dentro del for principal, se
ejecutará n-1 veces, sin embargo, ya que es el peor de los casos, nunca entrará. Por lo
que, la línea 11 no se ejecutará.
Teniendo todo esto en cuenta, el análisis del peor de los casos quedaría:
1. 3
2. 1
3. 2
4. 1 +n
5. n-1 + (n(n+1)/2-1) + (n(n-1)/2)
6. (n(n-1)/2)
7. (n(n-1)/2)
8. (n(n-1)/2)
9. …
10. n-1
11. 0
Sumando y simplificando las ejecuciones, el polinomio para el peor de los casos
quedaría:
5/2n^2+5/2n+3
Con gráfica:

Bubble Sort Peor de los casos


300000000

250000000

200000000

150000000

100000000

50000000

0
0 2000 4000 6000 8000 10000 12000
-50000000
La ejecución de los casos aleatorios:
La gráfica de los casos aleatorios sería:

Bubble Sort casos aleatorios


250000000

200000000

150000000

100000000

50000000

0
0 2000 4000 6000 8000 10000 12000
-50000000

Comparando resultados…

Bubble Sort
Casos aleatorios Mejor de los casos Peor de los casos

300000000

250000000

200000000

150000000

100000000

50000000

0
0 2000 4000 6000 8000 10000 12000

-50000000

También podría gustarte