Portada » Informática » Algoritmos de Ordenamiento: Complejidad, Estabilidad y Criterios de Selección
Esta tabla resume la complejidad temporal (mejor, peor y caso promedio) y la estabilidad de algunos métodos de ordenamiento comunes.
Método | Mejor Caso | Peor Caso | Caso Promedio | Estabilidad |
---|---|---|---|---|
Inserción | O(n) | O(n2) | O(n2) | Sí |
Selección | O(n2) | O(n2) | O(n2) | No |
Burbuja | O(n2) | O(n2) | O(n2) | Sí |
Shellsort | O(n log n) | O(n2) | O(n2) | No |
Mergesort | O(n log n) | O(n log n) | O(n log n) | Sí |
Quicksort | O(n log n) | O(n2) | O(n log n) | No |
El método de la burbuja es uno de los más sencillos. Consiste en comparar elementos adyacentes y, si cumplen una condición (ser mayor o menor que el otro), intercambiarlos de posición. El arreglo se recorre repetidamente hasta que no se realicen más intercambios, indicando que está completamente ordenado.
Esta versión mejorada del algoritmo de burbuja optimiza su rendimiento al terminar la ejecución tan pronto como los datos están completamente ordenados. Esto se logra mediante el uso de una bandera (o flag) que detecta la ausencia de intercambios durante una pasada completa, señalando que el arreglo ya está ordenado.
Este algoritmo se basa en comparaciones. Para que realice su trabajo de ordenación, son indispensables dos elementos:
El algoritmo consiste en realizar varias pasadas sobre el arreglo. En cada pasada, se toma un elemento y se inserta en su posición correcta dentro de la porción ya ordenada del arreglo. De esta manera, se mantiene una sublista ordenada que crece con cada iteración.
Cuando todos los elementos han sido analizados, la lista está completamente ordenada. Es importante destacar que, en el algoritmo por inserción, el arreglo no está totalmente ordenado hasta que el algoritmo finaliza. Además, en cada pasada, no se recorre todo el arreglo, sino solo los elementos ya analizados y ordenados en pasadas anteriores. Esto lo convierte en un algoritmo «en línea» (online), lo que significa que no necesita disponer de todos los elementos a ordenar desde el principio, sino que puede aceptarlos uno a uno y procesarlos a medida que los recibe.
Basado en comparaciones e intercambios, el Shellsort ofrece resultados significativamente mejores que los obtenidos con los métodos de burbuja, selección o inserción.
Se trata de un algoritmo de ordenación interna, aunque podría adaptarse para ordenación externa.
Requiere que el tiempo de acceso a cualquier dato sea constante (fue ideado para trabajar con arreglos, punteros, etc.). En estructuras como listas enlazadas, el tiempo de acceso no es constante, lo que afectaría su rendimiento.
El algoritmo se considera no estable, ya que, dados dos elementos con valores iguales, no garantiza mantener su orden relativo inicial.
La implementación original de Shell tiene una complejidad en el peor caso de O(n²), aunque en el caso promedio o en situaciones típicas comprobadas empíricamente, sus resultados son considerablemente mejores que los de otros algoritmos de ordenación interna de orden O(n²).
Este algoritmo consiste básicamente en dividir la lista de números en partes iguales y luego «mezclarlas» comparándolas para dejarlas ordenadas. Es un algoritmo recursivo con un número mínimo de comparaciones, basado en la técnica «divide y vencerás».
El tiempo de ejecución es O(N log N) en el mejor, promedio y peor caso. Su principal desventaja es que requiere un arreglo auxiliar, lo cual tiene dos consecuencias:
En cada recursión, se toma un arreglo de elementos desordenados, se divide en dos mitades, se aplica recursión a cada una de estas mitades hasta que se obtienen arreglos de un solo elemento, y luego se intercalan (mezclan) cada división para obtener el arreglo ordenado.
La intercala toma dos secuencias o arreglos de elementos y, a partir de estos, construye una tercera secuencia que contiene todos los elementos en orden.
El método de ordenamiento rápido, o Quicksort, es probablemente el más utilizado de todos. El algoritmo básico fue desarrollado en 1960 por C.A.R. Hoare. Este método es popular por su facilidad de implementación, sus buenos resultados generales y, en muchos casos, por consumir menos recursos que otros métodos de ordenación.
Entre sus ventajas, destaca que en el caso promedio tiene una eficiencia de O(n log n) y posee un bucle interno extremadamente corto. Uno de sus inconvenientes es que es recursivo (aunque existen versiones no recursivas), y otro es su fragilidad durante la implementación: un simple error puede causar un comportamiento inesperado o incorrecto.
Se han implementado y analizado muchas versiones mejoradas, pero es fácil decepcionarse porque este algoritmo está tan bien equilibrado que los efectos de mejoras en una parte del programa pueden verse descompensados por las consecuencias de un mal rendimiento en otra.
Al igual que el algoritmo de ordenación por mezclas (Mergesort), el algoritmo de ordenación rápida (Quicksort) utiliza la técnica «divide y vencerás». Se basa en que, en cada recursión, se divide el arreglo en subarreglos, se resuelven cada uno por separado y luego se unen las soluciones.
Cada algoritmo se comporta de modo diferente según la cantidad y la forma en que se presenten los datos. No existe un algoritmo «adecuado» universal; solo existe el mejor para cada caso particular. Por lo tanto, es crucial conocer a fondo el problema que se quiere resolver para aplicar el algoritmo más apropiado.
A continuación, se presentan algunas preguntas clave que pueden ayudar en la elección:
Si la información está casi ordenada, un algoritmo sencillo como el método de la burbuja podría ser suficiente. Si los datos están muy desordenados, un algoritmo más eficiente como Quicksort podría ser el más indicado.
Si la cantidad de datos es pequeña, no es necesario utilizar un algoritmo complejo; es preferible uno de fácil implementación. Para cantidades muy grandes, es fundamental evitar algoritmos que requieran mucha memoria adicional.
Algunos algoritmos solo funcionan con tipos de datos específicos (como enteros o enteros positivos), mientras que otros son generales y aplicables a cualquier tipo de dato comparable.
En los algoritmos que realizan múltiples intercambios, si los registros son de gran tamaño, estos intercambios pueden ser más lentos.