El algoritmo de ordenación rápida se puede dividir en los siguientes pasos
Identificar pivote.
Particionar la lista vinculada basada en pivote.
Divida la lista vinculada recursivamente en 2 partes.
Ahora, si siempre elijo el último elemento como pivote, identificar el elemento pivote (1er paso) lleva tiempo .
Después de identificar el elemento pivote, podemos almacenar sus datos y compararlos con todos los demás elementos para identificar el punto de partición correcto (segundo paso). Cada comparación tomará tiempo ya que almacenamos los datos dinámicos y cada intercambio lleva tiempo . Entonces, en total, lleva tiempo para n elementos.
Entonces la relación de recurrencia es:
que es que es lo mismo que en el orden de fusión con una lista vinculada.
Entonces, ¿por qué se prefiere la ordenación por fusión sobre la ordenación rápida para las listas vinculadas?
Respuestas:
El patrón de acceso a la memoria en Quicksort es aleatorio, también la implementación inmediata está en su lugar, por lo que utiliza muchos intercambios si las celdas logran el resultado ordenado.
Al mismo tiempo, la ordenación de fusión es externa, requiere una matriz adicional para devolver el resultado ordenado. En la matriz significa una sobrecarga de espacio adicional, en el caso de que sea una lista vinculada, es posible extraer el valor y comenzar a fusionar nodos. El acceso es más secuencial en la naturaleza.
Debido a esto, el ordenamiento rápido no es una opción natural para la lista vinculada, mientras que la ordenación por fusión tiene una gran ventaja.
La notación de Landau podría (más o menos, porque Quicksort todavía está ) de acuerdo, pero la constante es mucho más alta.O ( n2)
En el caso promedio, ambos algoritmos están en por lo que el caso asintótico es el mismo, pero la preferencia se debe estrictamente a la constante oculta y, a veces, el problema es la estabilidad (quicksort es inherentemente inestable, mergsort es estable) .O (nlogn )
fuente
Puede ordenar rápidamente las listas vinculadas, sin embargo, estará muy limitado en términos de selección de pivote, restringiéndolo a pivotes cerca del frente de la lista, lo cual es malo para entradas casi ordenadas, a menos que desee recorrer cada segmento dos veces (una vez para pivote y una vez para la partición). Y deberá mantener una pila de los límites de partición para las listas que aún necesita ordenar. Esa pila puede crecer a cuando la selección de pivote es mala junto con la complejidad del tiempo creciendo a .O ( n 2 )O ( n ) O ( n2)
La ordenación por fusión en listas vinculadas se puede ejecutar usando solo espacio adicional si adopta un enfoque ascendente contando dónde están los límites de las particiones y fusionándose en consecuencia.O ( 1 )
Sin embargo, al agregar una única matriz de punteros de 64 elementos, puede evitar esa iteración adicional y ordenar listas de hasta elementos en O ( 1 ) espacio adicional adicional.264 O ( 1 )
Este es el algoritmo que utiliza el kernel de Linux para ordenar sus listas vinculadas. Aunque con algunas optimizaciones adicionales, como ignorar el
previous
puntero durante todas las operaciones excepto la última fusión.fuente
Puede escribir ordenamiento por mezcla, partición tipo, especie de árbol y comparar los resultados
Es bastante fácil de árbol de escritura tipo si permitir algo más de espacio
para el árbol de una especie cada nodo de la lista enlazada debe tener dos punteros aunque especie por separado lista enlazada
En lista enlazada prefiero insertar y eliminar en lugar de intercambiar la
partición Hoare solo se puede hacer para una lista doblemente vinculada
Este código necesita algunas mejoras.
En primer lugar, debemos limitar el almacenamiento adicional a las necesidades de recursión,
luego debemos tratar de reemplazar la recursión con iteración.
Si queremos mejorar aún más el algoritmo, deberíamos usar el árbol de equilibrio automático.
fuente
Quicksort
Quizás muestre los pasos para quicksort
Si la lista contiene más de un nodo
primera sublista contiene nodos con teclas menores que la tecla pivote. La
segunda sublista contiene nodos con teclas iguales a la tecla pivote. La
tercera sublista contiene nodos con teclas mayores que la tecla pivote.
Anuncio 1.
Si queremos elegir un pivote rápido, la elección es limitada.
Podemos elegir el nodo principal o el nodo de cola.
Nuestra lista debe tener un puntero al nodo si queremos que nuestro pivote
sea accesible rápidamente; de lo contrario, tenemos que buscar el nodo.
Anuncio 2.
Podemos usar operaciones de cola para este paso
. Primero, podemos quitar el nodo de la lista original vinculada,
comparar su clave con la tecla pivote y poner el nodo en cola en la sublista correcta. Las sublistas
se crean a partir de nodos existentes y no hay necesidad de
asignar memoria para nuevos nodos.
El puntero al nodo de cola será útil porque las operaciones de cola
y la concatenación se ejecutan más rápido con la presencia de este puntero
fuente