Esencial para los programadores de Java: clasificación rápida de estructuras de datos y algoritmos (1)

La idea básica de clasificación rápida:

Con respecto a la cuestión del algoritmo de clasificación rápida, también puede ser equivalente a un ejemplo típico de implementación del algoritmo divide y vencerás: primero, una serie de secuencias sin clasificar se divide en dos secuencias izquierda y derecha S1 y S2 mediante un número de referencia. Los elementos de S1 son todos más grandes que el número de referencia. Pequeños, los elementos de S2 son todos más grandes que el número de referencia, y luego ordene rápidamente las secuencias izquierda y derecha nuevamente. Puede encontrar los números de referencia de S1 y S2 a voluntad. No es necesario establecer el bit más bajo como número de referencia cada vez, de esta manera, si las subsecuencias (incluidas las subsecuencias de S1 y S2) se someten al algoritmo de clasificación rápida, la secuencia final generada naturalmente se convertirá en una secuencia ordenada.
Describe el uso de los pasos de la idea del algoritmo divide y vencerás:
1. Paso de división: seleccione un número de referencia y luego divida la secuencia de modo que la parte sea mayor que el número de referencia y la parte sea menor que el número de referencia.
2. Paso de gobernanza: ordenar subsecuencias de forma recursiva
3. Paso combinado: este algoritmo no tiene este paso

Las ideas abstractas no pueden darnos una comprensión clara del algoritmo de clasificación rápida. Tomemos prestada una explicación vívida de una publicación en el foro 51CTO para darnos una comprensión clara de la clasificación rápida:

Supongamos que ahora ordenamos los 10 números "6 1 2 7 9 3 4 5 10 8". Primero, encuentre aleatoriamente un número en esta secuencia como número base. Por conveniencia, dejemos que el primer número 6 sea el número base. A continuación, debe colocar todos los números en esta secuencia que son mayores que el número base en el lado derecho de 6, y los números que son menores que el número base en el lado izquierdo de 6, de manera similar a la siguiente disposición:

3 1 2 5 4 6 9 7 10 8

En el estado inicial, el número 6 está en la posición 1 de la secuencia. Nuestro objetivo es mover 6 a una posición en algún lugar en el medio de la secuencia, digamos que esta posición es k. Ahora necesitamos encontrar este k y tomar la k-ésima posición como punto de división. Los números de la izquierda son todos menores o iguales a 6 y los números de la derecha son todos mayores o iguales a 6.
Comience a "sondear" desde ambos extremos de la secuencia inicial "6 1 2 7 9 3 4 5 10 8". Primero busque un número menor que 6 de derecha a izquierda, luego busque un número mayor que 6 de izquierda a derecha y luego intercámbielos. Aquí se pueden usar dos variables i y j para señalar las partes más a la izquierda y más a la derecha de la secuencia, respectivamente. A estas dos variables les damos bonitos nombres "Sentinel i" y "Sentinel j". Al principio, deje que el centinela i apunte al lado izquierdo de la secuencia (es decir, i = 1), apuntando al número 6. Deje que el centinela j apunte a la parte más a la derecha de la secuencia (es decir, = 10), apuntando al número.

Escribe aquí la descripción de la imagen.

Primero, Sentinel J comenzó a enviar. Debido a que el número de referencia establecido aquí es el número más a la izquierda, es muy importante enviar Sentinel J primero (piense por qué). Sentinel j se mueve hacia la izquierda paso a paso (es decir, j–) hasta que encuentra un número menor que 6 y se detiene. A continuación, el centinela i se mueve paso a paso hacia la derecha (es decir, i++) hasta que encuentra un número mayor que 6 y se detiene. Finalmente, el centinela j se detuvo frente al número 5 y el centinela i se detuvo frente al número 7.

Escribe aquí la descripción de la imagen.

Ahora intercambie los valores de los elementos señalados por centinela i y centinela j. La secuencia después del intercambio es la siguiente:

6 1 2 5 9 3 4 7 10 8
Escribe aquí la descripción de la imagen.

En este punto finaliza el primer intercambio. A continuación, el centinela j continúa moviéndose hacia la izquierda (un recordatorio amistoso, el centinela j debe comenzar primero cada vez). Se detuvo después de encontrar 4 (que era más pequeño que el número base 6 y cumplía con los requisitos). Sentinel i también continuó moviéndose hacia la derecha, encontró 9 (que era más grande que el número base 6, cumpliendo con los requisitos) y se detuvo. En este momento, el intercambio se realiza nuevamente y la secuencia después del intercambio es la siguiente:

6 1 2 5 4 3 9 7 10 8

El segundo intercambio ha terminado y el "sondeo" continúa. Sentinel j continuó moviéndose hacia la izquierda, encontró 3 (más pequeño que el número base 6, que cumple con los requisitos) y luego se detuvo. Sentinel i continúa moviéndose hacia la derecha, ¡oh no! En este momento, el centinela i y el centinela j se encontraron, y tanto el centinela i como el centinela j llegaron a 3. Indica que la "detección" finaliza en este momento. Intercambiamos los números base 6 y 3. La secuencia después del intercambio es la siguiente:

3 1 2 5 4 6 9 7 10 8
Escribe aquí la descripción de la imagen.

En este punto, la primera ronda de "detección" realmente ha terminado. En este momento, se utiliza el número base 6 como punto divisorio. Los números a la izquierda de 6 son todos menores o iguales a 6, y los números a la derecha de 6 son todos mayores o iguales a 6. Mirando hacia atrás en el proceso de ahora, de hecho, la misión del centinela j es encontrar un número menor que el número de referencia, y la misión del centinela i es encontrar un número mayor que el número de referencia hasta que i y j se encuentren.
Bien, explicación completada. Ahora que se ha devuelto el número base 6, resulta que se encuentra en la posición 6 de la secuencia. En este punto, hemos dividido la secuencia original en dos secuencias con 6 como punto divisorio. La secuencia de la izquierda es "3 1 2 5 4" y la secuencia de la derecha es "9 7 10 8". A continuación, debe procesar estas dos secuencias por separado. Porque las secuencias a la izquierda y a la derecha del 6 siguen siendo muy confusas. Pero no importa, hemos dominado el método, a continuación, solo necesitamos simular el método ahora para procesar las secuencias a la izquierda y derecha de 6 respectivamente. Ahora tratemos primero la secuencia del lado izquierdo de 6.
La secuencia de la izquierda es "3 1 2 5 4". Ajuste esta secuencia con 3 como número base, de modo que los números a la izquierda de 3 sean todos menores o iguales a 3, y los números a la derecha de 3 sean todos mayores o iguales a 3. Bien, comencemos a escribir.
Si su simulación es correcta, el orden de la secuencia después del ajuste debería ser:

2 1 3 5 4

Bien, ahora 3 está de nuevo en su lugar. A continuación, debemos procesar la secuencia "2 1" a la izquierda de 3 y la secuencia "5 4" a la derecha. La secuencia "2 1" se ajusta en función de 2. Después del procesamiento, la secuencia es "1 2" y 2 ha vuelto a su posición original. La secuencia "1" tiene un solo número y no requiere ningún procesamiento. En este punto, hemos procesado completamente la secuencia "2 1" y obtuvimos la secuencia "1 2". La secuencia "5 4" también se procesa de esta forma, y ​​la secuencia final obtenida es la siguiente:

1 2 3 4 5 6 9 7 10 8

Para la secuencia "9 7 10 8", se simula el mismo proceso hasta que no se pueda dividir ninguna nueva subsecuencia. Eventualmente obtendrás una secuencia como esta, de la siguiente manera

1 2 3 4 5 6 7 8 9 10

En este punto, la clasificación está completamente completa. Es posible que los estudiantes cuidadosos hayan descubierto que cada ronda de clasificación rápida es en realidad para devolver los números de referencia de esta ronda. Hasta que se devuelvan todos los números, la clasificación habrá terminado. La siguiente imagen dominante describe el proceso de procesamiento de todo el algoritmo.

Escribe aquí la descripción de la imagen.

Supongo que te gusta

Origin blog.csdn.net/NTSDB/article/details/52730753
Recomendado
Clasificación