El ordenamiento por inserción es un algoritmo de ordenamiento simple e intuitivo que funciona de manera similar a cómo los humanos ordenan cartas en sus manos. Es especialmente útil para listas pequeñas o listas que ya están parcialmente ordenadas. En esta sección, aprenderemos cómo funciona el algoritmo, analizaremos su complejidad y veremos ejemplos prácticos.
Conceptos Básicos
El ordenamiento por inserción construye la lista ordenada de manera incremental, tomando un elemento a la vez y colocándolo en la posición correcta dentro de la lista ya ordenada.
Pasos del Algoritmo
- Inicialización: Comienza con el segundo elemento de la lista (el primer elemento se considera ya ordenado).
- Comparación: Compara el elemento actual con los elementos de la lista ordenada.
- Inserción: Desplaza los elementos mayores hacia la derecha para hacer espacio e inserta el elemento actual en su posición correcta.
- Repetición: Repite los pasos 2 y 3 para todos los elementos de la lista.
Ejemplo Visual
Supongamos que tenemos la lista [5, 2, 4, 6, 1, 3]
.
- Inicialización:
[5, 2, 4, 6, 1, 3]
- Comparación e Inserción:
2
se compara con5
y se inserta antes de5
:[2, 5, 4, 6, 1, 3]
4
se compara con5
y se inserta antes de5
:[2, 4, 5, 6, 1, 3]
6
se compara con5
y se queda en su lugar:[2, 4, 5, 6, 1, 3]
1
se compara con6
,5
,4
y2
y se inserta al principio:[1, 2, 4, 5, 6, 3]
3
se compara con6
,5
,4
y se inserta antes de4
:[1, 2, 3, 4, 5, 6]
Implementación en Python
A continuación, se presenta una implementación del algoritmo de ordenamiento por inserción en Python:
def insertion_sort(arr): # Recorre desde el segundo elemento hasta el final de la lista for i in range(1, len(arr)): key = arr[i] j = i - 1 # Mueve los elementos de arr[0..i-1], que son mayores que key, una posición adelante while j >= 0 and key < arr[j]: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key # Ejemplo de uso arr = [5, 2, 4, 6, 1, 3] insertion_sort(arr) print("Lista ordenada:", arr)
Explicación del Código
- Inicialización:
for i in range(1, len(arr))
recorre la lista desde el segundo elemento. - Comparación:
while j >= 0 and key < arr[j]
compara el elemento actual (key
) con los elementos de la lista ordenada. - Inserción:
arr[j + 1] = key
inserta el elemento en su posición correcta después de desplazar los elementos mayores.
Análisis de Complejidad
Complejidad Temporal
- Mejor Caso: O(n) - Ocurre cuando la lista ya está ordenada.
- Peor Caso: O(n^2) - Ocurre cuando la lista está ordenada en orden inverso.
- Caso Promedio: O(n^2)
Complejidad Espacial
- Espacio Auxiliar: O(1) - Solo se utilizan variables adicionales para la clave y el índice.
Ejercicios Prácticos
Ejercicio 1
Ordena la siguiente lista utilizando el algoritmo de ordenamiento por inserción: [8, 3, 1, 7, 0, 10, 2]
.
Solución:
Ejercicio 2
Modifica el algoritmo de ordenamiento por inserción para que ordene la lista en orden descendente.
Solución:
def insertion_sort_desc(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and key > arr[j]: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key # Ejemplo de uso arr = [5, 2, 4, 6, 1, 3] insertion_sort_desc(arr) print("Lista ordenada en orden descendente:", arr)
Conclusión
El ordenamiento por inserción es un algoritmo eficiente para listas pequeñas o parcialmente ordenadas. Aunque su complejidad en el peor caso es O(n^2), su simplicidad y eficiencia en casos específicos lo hacen una herramienta útil en el análisis y diseño de algoritmos. En la siguiente sección, exploraremos otros algoritmos de ordenamiento más eficientes para listas grandes y desordenadas.
Curso de Análisis y Diseño de Algoritmos
Módulo 1: Introducción a los Algoritmos
Módulo 2: Análisis de Algoritmos
- Análisis de Complejidad Temporal
- Análisis de Complejidad Espacial
- Casos de Complejidad: Mejor, Peor y Promedio
Módulo 3: Estrategias de Diseño de Algoritmos
Módulo 4: Algoritmos Clásicos
- Búsqueda Binaria
- Ordenamiento por Inserción
- Ordenamiento por Mezcla (Merge Sort)
- Ordenamiento Rápido (Quick Sort)
- Algoritmo de Dijkstra
- Algoritmo de Floyd-Warshall