0% encontró este documento útil (0 votos)
31 vistas33 páginas

Consult A

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
31 vistas33 páginas

Consult A

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 33

1

TRABJO DE ESTRUCTURA DE DATOS l

PRESENTADO POR:

FLOREZ AGUAS GERSON LUIS

SALGADO PACHECO DIEGO ANDRES

PRESENTADO A:

ALEX DAVID MORALES ACOSTA

CORPORACION UNIVERSITARIA ANTONIO JOSE DE SUCRE

SINCELEJO-SUCRE

2023
2

1. Algoritmo de Ordenamiento Burbuja

El ordenamiento de burbuja es un sencillo algoritmo de ordenamiento. Funciona

revisando cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos

de posición si están en el orden equivocado. Es necesario revisar varias veces toda la lista

hasta que no se necesiten más intercambios, lo cual significa que la lista está ordenada.

Este algoritmo obtiene su nombre de la forma con la que suben por la lista los elementos

durante los intercambios, como si fueran pequeñas «burbujas». También es conocido como

el método del intercambio directo. Dado que solo usa comparaciones para operar elementos,

se lo considera un algoritmo de comparación, siendo uno de los más sencillos de implementar.

El algoritmo de ordenamiento burbuja es un algoritmo simple pero ineficiente para ordenar

una lista de elementos. Funciona comparando pares de elementos adyacentes y, si están en el

orden incorrecto, los intercambia. Este proceso se repite hasta que no se realicen intercambios

en un pase completo a través de la lista. Aquí están los detalles paso a paso del algoritmo:

1. Comenzamos recorriendo la lista de elementos desde el principio (índice 0).

2. Comparamos el elemento en el índice actual con el siguiente elemento (índice +1).

3. Si el elemento en el índice actual es mayor que el siguiente elemento, los

intercambiamos.

4. Continuamos comparando y haciendo intercambios en toda la lista hasta llegar al final

de la lista. En este punto, el elemento más grande ha "burbujeado" hasta el final de la lista.

5. Luego, repetimos los pasos 1-4, pero ignoramos el último elemento de la lista, ya que

sabemos que es el más grande y ya está en su posición correcta.


3

6. Continuamos este proceso hasta que no se realicen intercambios en un pase completo a

través de la lista. Esto indica que la lista está ordenada.

Ahora, respecto a la complejidad temporal:

 Peor Caso: El peor caso ocurre cuando la lista está completamente desordenada y

requiere que se realicen intercambios en cada pase completo a través de la lista. La

complejidad temporal en el peor caso es O(n^2), donde 'n' es el número de elementos en la

lista.

 Mejor Caso: El mejor caso ocurre cuando la lista ya está ordenada, y no se requiere

ningún intercambio durante el proceso. Aunque esto puede parecer ideal, la complejidad

temporal en el mejor caso sigue siendo O(n^2) ya que aún se deben hacer todas las

comparaciones.

 Caso Promedio: El caso promedio también tiene una complejidad temporal de O(n^2)

en la mayoría de las implementaciones. Esto se debe a que el algoritmo de burbuja siempre

realiza comparaciones y posiblemente intercambios en cada par de elementos adyacentes.

 El algoritmo de ordenamiento burbuja (Bubble Sort en inglés) es un algoritmo de

ordenamiento simple pero ineficiente en la mayoría de los casos. Sin embargo, hay

situaciones muy limitadas en las que podría ser más eficiente que otros algoritmos:

 Listas pequeñas: En listas muy pequeñas, el rendimiento del algoritmo de

ordenamiento burbuja puede ser aceptable. Debido a su simplicidad, no tiene mucha

sobrecarga en términos de complejidad y puede funcionar de manera eficiente cuando el

número de elementos a ordenar es muy pequeño.


4

 Listas casi ordenadas: Si la lista está casi completamente ordenada y solo hay unos

pocos elementos fuera de lugar, el algoritmo de burbuja podría requerir un número limitado

de pasadas para ordenar la lista. Esto se debe a que el algoritmo solo realiza intercambios

adyacentes, por lo que los elementos en su posición correcta se "burbujean" rápidamente

hacia su lugar correcto.

 Educación y aprendizaje: El algoritmo de burbuja se utiliza a menudo en la enseñanza

y el aprendizaje de algoritmos de ordenamiento debido a su simplicidad conceptual. Puede

ayudar a los estudiantes a comprender los conceptos básicos de cómo funcionan los

algoritmos de ordenamiento antes de pasar a algoritmos más eficientes.

 Sin embargo, es importante tener en cuenta que el algoritmo de ordenamiento burbuja

tiene una complejidad de tiempo promedio y peor caso de O(n^2), lo que significa que su

rendimiento es muy pobre en listas de tamaño moderado o grande en comparación con

algoritmos más eficientes como QuickSort, MergeSort o HeapSort. Por lo tanto, en la mayoría

de las aplicaciones prácticas, se deben preferir otros algoritmos de ordenamiento más

eficientes.
5
6

2. Algoritmo de Ordenamiento Inserción

es una manera muy natural de ordenar para un ser humano y puede usarse fácilmente para

ordenar un mazo de cartas numeradas en forma arbitraria. Requiere O (n2) operaciones para

ordenar una lista de n elementos.

Inicialmente, se tiene un solo elemento que, obviamente, es un conjunto ordenado.

Después, cuando hay k elementos ordenados de menor a mayor se toma el elemento k+1 y se

compara con todos los elementos ya ordenados, deteniéndose cuando se encuentra un

elemento menor (todos los elementos mayores han sido desplazados una posición a la

derecha) o cuando ya no se encuentran elementos (todos los elementos fueron desplazados y

este es el más pequeño). En este punto se inserta el elemento k+1 debiendo desplazarse los

demás elementos.

El algoritmo de ordenamiento por inserción es un método simple pero eficiente para

ordenar una lista de elementos. Funciona tomando uno de los elementos no ordenados de la

lista y colocándolo en la posición correcta en la parte ordenada de la lista. Aquí están los

detalles paso a paso del algoritmo:

1. Comenzamos con una lista de elementos desordenados.

2. Dividimos la lista en dos partes: la parte ordenada y la parte desordenada. Inicialmente,

la parte ordenada consta de un solo elemento, el primer elemento de la lista.

3. Luego, tomamos el primer elemento de la parte desordenada (es decir, el siguiente

elemento sin ordenar) y lo comparamos con los elementos en la parte ordenada.

4. Comenzamos desde el último elemento de la parte ordenada y comparamos el elemento

seleccionado con cada elemento en la parte ordenada hasta encontrar la posición correcta.
7

5. A medida que realizamos estas comparaciones, movemos los elementos en la parte

ordenada que son mayores que el elemento seleccionado hacia la derecha para hacer espacio

para el nuevo elemento.

6. Insertamos el elemento seleccionado en la posición correcta en la parte ordenada.

7. Repetimos los pasos 3-6 para cada elemento en la parte desordenada hasta que todos los

elementos estén ordenados.

8. Cuando hayamos procesado todos los elementos, la lista estará completamente ordenada.

Ahora, en cuanto a la complejidad temporal:

 Peor Caso: El peor caso ocurre cuando la lista está en orden inverso, lo que significa

que cada elemento de la parte desordenada debe compararse y desplazarse hasta el principio

de la parte ordenada. En este caso, la complejidad temporal en el peor caso es O(n^2), donde

'n' es el número de elementos en la lista.

 Mejor Caso: El mejor caso ocurre cuando la lista ya está completamente ordenada. En

este caso, se realizan comparaciones, pero no se requieren desplazamientos de elementos. La

complejidad temporal en el mejor caso es O(n).

 Caso Promedio: En promedio, el algoritmo de ordenamiento por inserción tiene una

complejidad temporal de O(n^2). Esto se debe a que, en la mayoría de las implementaciones,

en promedio se deben realizar aproximadamente n^2/4 comparaciones y n^2/4

desplazamientos, lo que da como resultado una complejidad cuadrática.

 En cuanto a situaciones en las que el algoritmo de ordenamiento por inserción podría

ser más eficiente que otros

 Listas pequeñas: El algoritmo de ordenamiento por inserción puede ser más eficiente

que otros algoritmos de ordenamiento, como el ordenamiento rápido o el ordenamiento de


8

mezcla, cuando se trata de listas pequeñas. Debido a su baja sobrecarga y simplicidad, puede

superar a otros algoritmos en listas con un número limitado de elementos.

 Listas casi ordenadas: Si la lista ya está parcialmente ordenada o tiene solo unos pocos

elementos fuera de lugar, el algoritmo de inserción tiende a funcionar bien, ya que solo

necesita mover unos pocos elementos para ordenar la lista.

En general, el algoritmo de ordenamiento por inserción es una buena opción para listas

pequeñas o casi ordenadas, pero para listas más grandes o desordenadas, otros algoritmos

como el ordenamiento rápido o el ordenamiento de mezcla suelen ser más eficientes.


9

3. Algoritmo de Ordenamiento Selección

Consiste en encontrar el menor de todos los elementos del arreglo o vector e intercambiarlo

con el que está en la primera posición. Luego el segundo más pequeño, y así sucesivamente

hasta ordenarlo todo. Su implementación requiere O(n2) comparaciones e intercambios para

ordenar una secuencia de elementos.

El algoritmo de ordenamiento por selección es un algoritmo simple pero ineficiente que se

utiliza para ordenar una lista de elementos en orden ascendente. Funciona seleccionando

repetidamente el elemento más pequeño de la lista no ordenada y colocándolo al principio de

la lista ordenada. Aquí tienes una explicación paso a paso del funcionamiento del algoritmo:

1. Inicialización: Se considera que, al principio, la lista completa está desordenada, y no

hay elementos en la lista ordenada.

2. Búsqueda del elemento mínimo: El algoritmo busca el elemento mínimo en la lista no

ordenada. Para hacer esto, recorre toda la lista no ordenada, comparando cada elemento con el

elemento mínimo encontrado hasta ahora. Si encuentra un elemento menor, lo marca como el

nuevo elemento mínimo.

3. Intercambio: Una vez que se ha encontrado el elemento mínimo en la lista no ordenada,

se intercambia con el primer elemento de la lista no ordenada. Esto efectivamente lo coloca en

la lista ordenada. El primer elemento de la lista no ordenada ahora se considera parte de la

lista ordenada.
10

4. Repetición: Se repiten los pasos 2 y 3 para el resto de la lista no ordenada. En cada

iteración, se busca el mínimo en la lista no ordenada restante y se coloca al principio de la

lista ordenada.

5. Finalización: El algoritmo continúa repitiendo los pasos anteriores hasta que no queden

elementos en la lista no ordenada. En ese momento, toda la lista está ordenada.

Ahora, en cuanto a la complejidad temporal:

 Peor caso: El peor caso ocurre cuando la lista está en orden descendente, lo que

significa que, en cada iteración, se debe buscar el elemento mínimo en toda la lista no

ordenada. En este caso, la complejidad es O(n^2), donde "n" es el número de elementos en la

lista.

 Mejor caso: El mejor caso ocurre cuando la lista ya está ordenada. Aún así, el

algoritmo realizará comparaciones para determinar que los elementos ya están en orden, pero

no realizará intercambios. Por lo tanto, la complejidad es igualmente O(n^2).

 Caso promedio: En el caso promedio, el algoritmo realiza O(n^2) comparaciones e

intercambios.

Dado que la complejidad del algoritmo de selección es cuadrática, no es eficiente para

listas grandes. Sin embargo, puede ser más eficiente que otros algoritmos de ordenamiento en

ciertas situaciones, como cuando el costo de intercambiar elementos es alto en comparación

con el costo de las comparaciones. Además, debido a su simplicidad y facilidad de


11

implementación, puede ser una opción adecuada para listas pequeñas o cuando no se dispone

de recursos para implementar algoritmos más complejos. En general, se prefiere usar

algoritmos de ordenamiento más eficientes, como el algoritmo Quicksort o Mergesort, para

listas de tamaño considerable.

 usar el mínimo elemento entre una posición i y el final de la lista

 Intercambiar el mínimo con el elemento de la posición i

Así, se puede escribir el siguiente pseudocódigo para ordenar una lista de n elementos

indexados desde el 1:

para i=1 hasta n-1;

minimo = i;

para j=i+1 hasta n

si lista[j] < lista[minimo] entonces

minimo = j

fin si

fin para

intercambiar(lista[i], lista[minimo])

fin para

 Aunque el algoritmo de selección es fácil de entender e implementar, no es eficiente

en términos de tiempo en comparación con otros algoritmos de ordenamiento más avanzados

como el QuickSort, MergeSort o incluso el BubbleSort. Sin embargo, hay situaciones en las

que el algoritmo de selección podría ser más eficiente que otros algoritmos:
12

 Listas Pequeñas: En listas pequeñas, el rendimiento de los algoritmos de ordenamiento

no suele ser un problema crítico. En este caso, el algoritmo de selección puede ser una opción

viable debido a su simplicidad y facilidad de implementación.

 Memoria Limitada: El algoritmo de selección requiere un número constante de

intercambios, lo que puede ser beneficioso en sistemas con restricciones de memoria. Otros

algoritmos, como MergeSort, requieren memoria adicional para copiar elementos y dividir

listas.

 Listas Casi Ordenadas: Si se sabe que la lista está casi ordenada, es decir, solo hay

unos pocos elementos fuera de lugar, el algoritmo de selección podría funcionar relativamente

rápido en comparación con otros algoritmos más complejos. Esto se debe a que, en promedio,

requerirá menos intercambios que otros algoritmos.

 Optimizaciones Específicas: En algunos casos, es posible optimizar el algoritmo de

selección para que sea más eficiente. Por ejemplo, en lugar de buscar el elemento más

pequeño en cada iteración, se podría buscar tanto el elemento más pequeño como el más

grande, reduciendo el número de intercambios a la mitad.

En general, el algoritmo de selección no se recomienda para listas grandes o para

aplicaciones donde el rendimiento sea crítico, ya que tiene una complejidad de tiempo

promedio de O(n^2), donde "n" es el número de elementos en la lista. Sin embargo, en

situaciones específicas como las mencionadas anteriormente, puede ser una opción aceptable

debido a su simplicidad y baja sobrecarga de memoria. Para listas más grandes y rendimiento

crítico, se suelen preferir algoritmos de ordenamiento más eficientes como QuickSort o

MergeSort, que tienen complejidades de tiempo mejores en el caso promedio.


13

4. Algoritmo de Ordenamiento Shellsort

El algoritmo de ordenación Shell está basada en el algoritmo de ordenación por inserción.

Tiene mejores resultados que el algoritmo de Burbuja, Selección o Inserción directa.

El ShellSort ordena por inserción de subconjuntos del vector que están separados entre sí

por iguales a la mitad del tamaño del vector, es decir, va armando subvectores de tamaño

igual a k/2, e intercambiando valores, los cuales se van reduciendo rápidamente.

Ejemplo.

Tenemos el vector original.

Iteración 1:

Se formarán subvectores en saltos de 5, es decir el primer subvector está compuesto par la

posición 0, 5 y 11 del vector original (Color rojo).


14

El segundo subvector estará conformado por la posición 1 y 7 del vector original (Color

verde).

Y así sucesivamente hasta tener todos los elementos en un subvector.

En total tenemos 5 subvectores, estos subvectores se ordenan internamente y regresan al

vector original con las posiciones ordenadas.

Subvector 1

45 55 58 Ordenado no hay cambios


15

Nuevo vector después de iteración 1:

Iteración 2:

Se modifica K, K=5/2=2.

Ahora los saltos se hacen de 2 en 2 para formar los nuevos subvectores.

De esta forma se crean dos subvectores (rojo y verde), se ordenan internamente y se

regresan con las posiciones ordenadas por cada subvector.

Se crea el nuevo vector con los nuevos números ordenados.

Iteración 3:

Se modifica k. K=2/2=1.
16

Cuando k=1 sólo podenos obtener 1 subvector; el vector original. Cuando k=1 Shell

funciona igual que el algoritmo de inserción dejando así el vector ordenado.

Código del algoritmo ShellSort

public static int[] ordenacionShell(int vec[]){

int cont=0;

final int N=vec.length;

int k=N/2;

while (k>=1){

for (int i = 0; i < k; i++){

//para cada subvector recorremos sus elementos

for (int j = k+i; j < N; j+= k)

int v = vec[j];

int n = j - k;

while (n>=0&& vec[n] >v){

vec[n + k] = vec[n];

n-=k;

vec[n + k] = v;
17

//obtenemos un nuevo salto

k /= 2;

return vec;

Implementación

public class Shell {

public static void main(String[] args) {

int vec[]={45,17,23,67,21,55,8,18,89,26,58};

System.out.println("Vector original");

imprimirVector(vec);

System.out.println("\n");

vec=ordenacionShell(vec);

imprimirVector(vec);

public static int[] ordenacionShell(int vec[]){

int cont=0;

final int N=vec.length;

int k=N/2;

while (k>=1){

for (int i = 0; i < k; i++){


18

//para cada subvector recorremos sus elementos

for (int j = k+i; j < N; j+= k)

int v = vec[j];

int n = j - k;

while (n>=0&& vec[n] >v){

vec[n + k] = vec[n];

n-=k;

vec[n + k] = v;

//obtenemos un nuevo salto

k /= 2;

System.out.print("iteracion: "+(++cont)+":

");imprimirVector(vec);System.out.println();

return vec;

public static void imprimirVector(int vec[]){

for(int i=0;i<vec.length;i++){

System.out.print(vec[i]+" ");

}
19

}
20

 El algoritmo de ordenamiento Shellsort es una mejora con respecto a los algoritmos

de ordenamiento por inserción. Funciona dividiendo la lista en subconjuntos más pequeños y

luego aplicando el algoritmo de inserción en cada uno de estos subconjuntos. A medida que

avanza el proceso, los subconjuntos se vuelven más pequeños y, en última instancia, el

algoritmo se convierte en una especie de ordenamiento por inserción en la lista completa.

Aquí tienes una explicación paso a paso del funcionamiento del algoritmo:

1. Elección de la secuencia de incrementos: Antes de comenzar la ordenación, se elige

una secuencia de incrementos que se utilizará para dividir la lista en subconjuntos. Estos

incrementos deben ser enteros positivos y terminar en 1.

2. División en subconjuntos: La lista se divide en subconjuntos de acuerdo con la

secuencia de incrementos. En la primera pasada, los subconjuntos se crean tomando

elementos que están separados por la distancia igual al primer incremento. Luego, en cada

pasada subsiguiente, los subconjuntos se crean tomando elementos separados por el siguiente

valor en la secuencia de incrementos. Esto crea varios subconjuntos pequeños.

3. Ordenamiento por inserción en cada subconjunto: Luego, se aplica el algoritmo de

ordenamiento por inserción en cada uno de estos subconjuntos pequeños. Esto implica

comparar y mover los elementos dentro de cada subconjunto para que estén en orden.

4. Reducción de la secuencia de incrementos: Después de que todos los subconjuntos se

hayan ordenado, se reduce la secuencia de incrementos. Esto significa que se pasa al siguiente

valor en la secuencia de incrementos y se repiten los pasos 2 y 3.


21

5. Repeticiones: Los pasos 2-4 se repiten hasta que la secuencia de incrementos llega a 1.

En ese punto, se realiza una última pasada con un incremento de 1, que es esencialmente una

pasada de ordenamiento por inserción en la lista completa.

6. Finalización: Una vez que se ha realizado la última pasada, la lista completa estará

ordenada.

Ahora, en cuanto a la complejidad temporal:

 Peor caso: La complejidad temporal del Shellsort depende en gran medida de la

secuencia de incrementos seleccionada. En el peor caso, si se utiliza una secuencia de

incrementos subóptima, la complejidad puede ser peor que O(n^2), pero con secuencias de

incrementos adecuadas, como la secuencia de incrementos de Shell original (1, 4, 13, 40, ...),

la complejidad puede ser O(n^(3/2)).

 Mejor caso: El mejor caso ocurre cuando la lista ya está casi ordenada, lo que

significa que los elementos en cada subconjunto están muy cerca de su posición final. En este

caso, el Shellsort puede tener un rendimiento cercano a O(n log n), dependiendo de la

secuencia de incrementos utilizada.

 Caso promedio: El caso promedio suele ser mejor que el peor caso, pero peor que el

mejor caso, dependiendo de la secuencia de incrementos.


22

 Situaciones en las que el algoritmo podría ser más eficiente que otros:

 Shellsort puede ser más eficiente que algoritmos de ordenamiento simples como el

de burbuja o el de selección, especialmente en listas de tamaño moderado.

 Puede ser eficiente cuando se sabe que la lista está casi ordenada, ya que tiende a

tener un buen rendimiento en tales casos.

 Si se elige una secuencia de incrementos adecuada, Shellsort puede ser más rápido

que algoritmos de ordenamiento más avanzados como Quicksort o Mergesort en listas de

tamaño moderado.

Sin embargo, para listas muy grandes, otros algoritmos de ordenamiento como Quicksort y

Mergesort tienden a ser más eficientes en general debido a su mejor complejidad temporal en

el peor caso. La elección de la secuencia de incrementos es un aspecto crítico para el

rendimiento de Shellsort, y encontrar la secuencia óptima puede ser un desafío en algunos

casos.
23

5. Algoritmo de Ordenamiento por Mezcla (Merge)

La Ordenamiento por mezcla es uno de los algoritmos de ordenación más populares y

eficientes. Se basa en el principio del algoritmo divide y vencerás. Funciona dividiendo el

array en dos mitades repetidamente hasta que obtenemos el array dividido en elementos

individuales. Un elemento individual es un array ordenado en sí mismo. El ordenamiento por

mezcla combina repetidamente estas pequeñas matrices ordenadas para producir submatrices

ordenadas más grandes hasta que obtenemos una array final ordenada. Se utiliza mucho en

aplicaciones de comercio electrónico.

Algoritmo de ordenamiento por mezcla

El método de ordenamiento por mezcla descendente comienza desde la parte superior con

el array completo y procede hacia abajo a los elementos individuales con recursión.

Supongamos que tenemos un array sin ordenar A[] que contiene n elementos.

Merge ()

 Inicializa el array auxiliar output para almacenar la salida ordenada.

 Inicializa 3 punteros i, j y k.

i apunta al principio de la primera subarray beg.

j apunta al principio de la segunda subarray mid+1.

k inicializado con beg mantiene el índice actual del array ordenado output.

 Hasta que lleguemos al final de la subarray arr[beg, .... ,mid] o arr[mid+1, .... ,end],

escogemos el valor más pequeño entre los elementos en el índice i &j y lo insertamos

en output.
24

 Escoge los elementos restantes y los inserta en output una vez que uno de los arrays se

ha agotado.

 Copiar output en arr[beg, ... , end].

Ejemplo de ordenamiento por mezcla

Supongamos que tenemos el array (5,3,4,2,1,6). Vamos a ordenarlo utilizando el algoritmo

de ordenamiento por mezcla.

Obtenemos el array ordenado - (1 2 3 4 5 6)

Implementación del algoritmo Ordenamiento por mezcla

#include<iostream>

using namespace std;

void merge(int arr[], int beg, int mid, int end) {

int output[end - beg + 1];

int i = beg, j = mid + 1, k = 0;

// add smaller of both elements to the output

while (i <= mid && j <= end) {

if (arr[i] <= arr[j]) {


25

output[k] = arr[i];

k += 1; i += 1;

else {

output[k] = arr[j];

k += 1; j += 1;

// remaining elements from first array

while (i <= mid) {

output[k] = arr[i];

k += 1; i += 1;

// remaining elements from the second array

while (j <= end) {

output[k] = arr[j];

k += 1; j += 1;

// copy output to the original array

for (i = beg; i <= end; i += 1) {

arr[i] = output[i - beg];

void mergeSort(int arr[], int beg, int end) {


26

if (beg < end) {

int mid = (beg + end) / 2;

//divide and conquer

mergeSort(arr, beg, mid); // divide : first half

mergeSort(arr, mid + 1, end); // divide: second half

merge(arr, beg, mid, end); // conquer

int main() {

int n = 6;

int arr[6] = {5, 3, 4, 2, 1, 6};

cout << "Input array: ";

for (int i = 0; i < n; i++) {

cout << arr[i] << " ";

cout << "\n";

mergeSort(arr, 0, n - 1); // Sort elements in ascending order

cout << "Output array: ";

for (int i = 0; i < n; i++) {

cout << arr[i] << " ";

cout << "\n";

}
27

Complejidad del algoritmo Ordenamiento por mezcla

Complejidad temporal

 Caso medio

Merge Sort es un algoritmo recursivo. La siguiente relación de recurrencia da la expresión

de la complejidad temporal de Merge sort.

T(n) = 2T(n/2) + θ(n)

El resultado de esta relación de recurrencia da T(n) = nLogn.También podemos verlo como

un array de tamaño n que se divide en un máximo de Logn partes, y la fusión de cada parte

toma O(n) tiempo.

Por tanto, la complejidad temporal es del orden de [Big Theta]: O(nLogn).

 El peor caso

La complejidad temporal en el peor de los casos es del orden de [Big O]: O(nLogn).

 El mejor caso

La complejidad temporal en el mejor de los casos es [Big Omega]: O(nLogn). Es la misma

que la complejidad temporal del peor caso.

 El algoritmo de ordenamiento por mezcla (Merge Sort en inglés) es un algoritmo de

ordenamiento eficiente que se basa en el principio de dividir y conquistar. Divide la lista en

dos mitades, ordena cada mitad de forma recursiva y luego combina (mezcla) las dos mitades

ordenadas para obtener la lista ordenada final. Aquí hay situaciones en las que el algoritmo de

ordenamiento por mezcla podría ser más eficiente que otros algoritmos:

 Rendimiento estable: Merge Sort es un algoritmo estable, lo que significa que

conserva el orden relativo de elementos con valores iguales. Esto puede ser crucial en
28

aplicaciones donde se necesita mantener el orden original de los elementos que tienen valores

idénticos.

 Listas enlazadas: En el caso de listas enlazadas, Merge Sort puede ser más eficiente

que otros algoritmos de ordenamiento, como QuickSort, que tienden a realizar más

operaciones de puntero. Merge Sort simplemente cambia los enlaces, lo que hace que sea más

fácil de implementar y más rápido en listas enlazadas.

 Listas grandes y memoria disponible: Aunque Merge Sort tiene una complejidad

temporal de O(n log n), donde "n" es el número de elementos en la lista, puede ser más

eficiente en términos de memoria en comparación con algoritmos como QuickSort, que

requieren una cantidad significativa de memoria adicional para la pila de llamadas recursivas.

 Listas ya parcialmente ordenadas: Merge Sort no se ve muy afectado por el grado de

orden de la lista inicial. Incluso en el peor caso, su rendimiento es consistente. Esto lo hace

adecuado para listas que ya están parcialmente ordenadas o en las que no se conoce la

distribución de los datos.

 Estabilidad del tiempo de ejecución: A diferencia de QuickSort, que puede tener un

rendimiento pobre en el peor caso (O(n^2)), Merge Sort siempre tiene un rendimiento

consistente y predecible con una complejidad de tiempo de O(n log n) en todos los casos. Esto

lo hace adecuado para aplicaciones donde se requiere un rendimiento confiable en todos los

escenarios.
29

En resumen, el algoritmo de ordenamiento por mezcla (Merge Sort) es una excelente

opción cuando se valora la estabilidad en el ordenamiento, se trabaja con listas enlazadas, se

tienen listas grandes o se necesita un rendimiento predecible en todas las situaciones. Aunque

su complejidad de tiempo es mayor que la de algunos otros algoritmos, su eficiencia en

términos de estabilidad y uso de memoria lo convierte en una elección sólida en muchas

circunstancias.

6. Algoritmo de Ordenamiento Rápido (Quick)

El ordenamiento rápido (quicksort en inglés) es un algoritmo basado en la técnica de divide

y vencerás, que permite, en promedio, ordenar n elementos en un tiempo proporcional a n log

n. Esta es la técnica de ordenamiento más rápida conocida. Fue desarrollada por C. Antony R.

Hoare en 1960. El algoritmo original es recursivo, pero se utilizan versiones iterativas para

mejorar su rendimiento (los algoritmos recursivos son en general más lentos que los

iterativos, y consumen más recursos).

El algoritmo trabaja de la siguiente forma:

 Elegir un elemento del conjunto de elementos a ordenar, al que llamaremos pivote.

 Resituar los demás elementos de la lista a cada lado del pivote, de manera que a un

lado queden todos los menores que él, y al otro los mayores. Los elementos iguales al pivote

pueden ser colocados tanto a su derecha como a su izquierda, dependiendo de la

implementación deseada. En este momento, el pivote ocupa exactamente el lugar que le

corresponderá en la lista ordenada.

 La lista queda separada en dos sublistas, una formada por los elementos a la izquierda

del pivote, y otra por los elementos a su derecha.


30

 Repetir este proceso de forma recursiva para cada sublista mientras éstas contengan

más de un elemento. Una vez terminado este proceso todos los elementos estarán ordenados.

Como se puede suponer, la eficiencia del algoritmo depende de la posición en la que

termine el pivote elegido.

Ahora, en cuanto a la complejidad temporal:

 En el mejor caso, el pivote termina en el centro de la lista, dividiéndola en dos

sublistas de igual tamaño. En este caso, el orden de complejidad del algoritmo es O(n·log

n).

 En el peor caso, el pivote termina en un extremo de la lista. El orden de complejidad

del algoritmo es entonces de O(n²). El peor caso dependerá de la implementación del

algoritmo, aunque habitualmente ocurre en listas que se encuentran ordenadas, o casi

ordenadas. Pero principalmente depende del pivote, si por ejemplo el algoritmo implementado

toma como pivote siempre el primer elemento del array, y el array que le pasamos está

ordenado, siempre va a generar a su izquierda un array vacío, lo que es ineficiente.

 En el caso promedio, el orden es O(n·log n).

No es extraño, pues, que la mayoría de las optimizaciones que se aplican al algoritmo se

centren en la elección del pivote.


31

 El algoritmo de ordenamiento rápido, también conocido como QuickSort, es un

algoritmo de ordenamiento eficiente que utiliza la estrategia de "dividir y conquistar". Aquí

hay situaciones en las que el algoritmo QuickSort podría ser más eficiente que otros

algoritmos:

 Rendimiento en general: En muchos casos, QuickSort es más rápido en la práctica que

otros algoritmos de ordenamiento, como Bubble Sort o Insertion Sort, especialmente cuando

se trata de listas grandes y desordenadas. Su complejidad promedio es de O(n log n), lo que lo

hace altamente eficiente en términos de tiempo.

 Rendimiento en el mejor caso: QuickSort tiene un rendimiento excepcional en el

mejor caso, con una complejidad de tiempo de O(n log n). Esto lo convierte en una excelente

elección cuando se trabaja con listas que ya están parcial o completamente ordenadas, ya que

en estos casos su rendimiento es óptimo.

 Memoria disponible: A diferencia de MergeSort, que puede requerir memoria

adicional para mantener las sublistas en cada llamada recursiva, QuickSort es un algoritmo de

ordenamiento in situ. Esto significa que no necesita memoria adicional para copiar elementos

en sublistas, lo que lo hace eficiente en términos de uso de memoria.

 Búsqueda en tiempo real: QuickSort se puede utilizar en situaciones en las que se

necesita realizar una búsqueda en tiempo real mientras se mantiene la lista ordenada. A

medida que los elementos se ordenan, se pueden buscar y recuperar rápidamente en la lista

ordenada.
32

 Implementación eficiente: QuickSort es un algoritmo relativamente simple de

implementar y es adecuado para ordenar arreglos y listas enlazadas. Su simplicidad y

eficiencia en términos de tiempo lo hacen atractivo en muchas aplicaciones.

 Adaptabilidad: QuickSort es un algoritmo adaptable que se adapta bien a diferentes

situaciones y tamaños de datos. Puede optimizarse para tratar con datos específicos o

estructuras de datos particulares.

Sin embargo, es importante mencionar que QuickSort no siempre es la mejor opción en

todos los casos. En situaciones donde se requiere un rendimiento consistente en todos los

casos (por ejemplo, en aplicaciones críticas), algoritmos como MergeSort pueden ser

preferibles debido a su rendimiento constante. Además, QuickSort puede tener un rendimiento

pobre en el peor caso (O(n^2)) en listas que ya están ordenadas en orden ascendente o

descendente. En tales casos, algoritmos como MergeSort o HeapSort pueden ser más

adecuados. En resumen, QuickSort es una excelente opción en muchas situaciones, pero la

elección del algoritmo de ordenamiento debe basarse en las características específicas de los

datos y los requisitos de la aplicación.


33

BIBLIOGRAFIA

https://es.wikipedia.org/wiki/Ordenamiento_de_burbuja

https://es.wikipedia.org/wiki/Ordenamiento_por_inserci%C3%B3n

https://www.ecured.cu/Algoritmo_de_ordenamiento_por_selecci%C3%B3n

https://tutospoo.jimdofree.com/tutoriales-java/m%C3%A9todos-de-ordenaci%C3%B3n/

shellshort/

https://www.delftstack.com/es/tutorial/algorithm/merge-sort/

https://es.wikipedia.org/wiki/Quicksort

http://mis-algoritmos.com/ordenamiento-rapido-quicksort#!

También podría gustarte