Clasificación rápida normal
Encuentre una base de valor base y luego ordenela en un viaje para que los números a la izquierda de la base sean más pequeños que la base, y los números a la derecha de la base son mayores o iguales a la base. Luego divídalo en dos subarrías clasificando. Recursivo como este.
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t se extiende comparable <? Super t >> void sort (t [] arr, int izquierdo, int right) {if (left> = right) return; int p = particion (arr, izquierdo, derecha); sort (arr, izquierda, p - 1); sort (arr, p + 1, derecha);} privado estático <t extiende comparable <? Super t >> int Partition (t [] arr, int a la izquierda, int right) {t base = arr [izquierda]; int j = izquierda; para (int i = izquierda+1; i <= right; i ++) {if (base.compareTo (arr [i])> 0) {j ++; swap (arr, j, i);}} swap (arr, izquierda, j); j; clasificación} public static void swap (object [] arr, int i, int j) {if (i! = j) {objeto temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private estático void void (objeto [] arr) {para (objeto o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {entero [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 8 0 4 4 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Optimización de clasificación rápida: seleccione aleatoriamente el valor base base base
Cuando la matriz está casi ordenada, el rendimiento de orden rápido es deficiente (porque después de cada pedido, el tamaño recursivo de los submarinos izquierdo y derecho es muy diferente, y es probable que la parte más grande alcance O (n^2) al final).
Solución: El valor de referencia se selecciona al azar, en lugar de tomar el primer número cada vez. Esto no será perturbado por "matrices casi ordenadas". Pero el rendimiento de clasificación de "matrices casi fuera de servicio" puede caer ligeramente, al menos hay más de la parte que se cambia antes de clasificar. Este intercambio no tiene sentido en el orden ... hay muchos componentes de "suerte" ...
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1);} public static <t se extiende comparable <? Super t >> void sort (t [] arr, int izquierdo, int right) {if (left> = right) return; int p = particion (arr, izquierdo, derecha); sort (arr, izquierda, p - 1); sort (arr, p + 1, derecha);} privado estático <t extiende comparable <? Super t >> int Partition (t [] arr, int izquierdo, int right) {// Antes de clasificar, deje que el valor de referencia se intercambie con un número aleatorio. De esta manera, el valor de referencia es aleatorio. // No hará que la escala recursiva de los lados izquierdo y derecho sea inconsistente cuando la matriz esté relativamente ordenada, lo que resulta en el peor intercambio de complejidad de tiempo (arr, izquierdo, (int) (math.random ()*(derecha - izquierda+1)+izquierda)); t base = arr [izquierda]; int j = izquierda; para (int i = izquierda+1; i <= derecha; i++) {{{if { (base.compareto (arr [i])> 0) {j ++; swap (arr, j, i);}} swap (arr, left, j); return j; // return de la esquina inferior del valor de referencia después de un sort mentiroso} public static void swap (object [] arr, int i, int j) {i temp;}}private static void printArr(Object[] arr) {for (Object o : arr) {System.out.print(o);System.out.print("/t");}System.out.println();}public static void main(String args[]) {Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}La clasificación rápida continúa optimizando: use la clasificación de inserción en conjunción
El orden rápido es reducir continuamente la escala del problema para resolver subproblemas y requiere una recursión continua. Sin embargo, la recursión es lo suficientemente pequeña, y si esta recursión inestable + continúa ejecutándose, la eficiencia puede no ser muy buena.
Entonces, cuando el problema es pequeño y casi ordenado, la clasificación de inserción funciona bien. A menudo puede ver tales comentarios en matrices.sort () que viene con Java: "Use el tipo de inserción en matrices pequeñas", "Ordena de inserción en matrices más pequeñas"
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param Arr Array para ordenarse* @param Izquierda Cerrar a la izquierda* @param Cerrar a la derecha* @param K Cuando la clasificación rápida se recursa en la escala del subproblem <= k, la optimización de inserción de clasificación se usa* @Param <t> genic, genic, se clasifica a la clasificación de la clasificación, se compara. Comparable <? Super t >> void sort (t [] arr, int loft, int right, int k) {// Las horas de escala se clasifican por inserción if (derecha - izquierda <= k) {insertionsort (arr, izquierda, derecha); return;} int p = particion (arr, izquierda, derecha); sort (arr, izquierda, p - 1, k); sort (arr, p + 1, derecha, k);} static static. Super t >> sin inycionsort (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && curareto (arr [j]) <0; j--) {j + 1] = arr [j];} arr [j + 1] <T se extiende comparable <? Super t >> int Partition (t [] arr, int izquierdo, int right) {// Antes de clasificar, deje que el valor de referencia intercambie con un número aleatorio. De esta manera, el valor de referencia es aleatorio. // No hará que la escala recursiva de los lados izquierdo y derecho sea inconsistente cuando la matriz sea relativamente ordenada, lo que resulta en el peor intercambio de complejidad de tiempo (arr, izquierda, (int) (math.random () * (derecha - izquierda + 1) + izquierda)); t base = arr [arr [int j = izquierda; para (int i = izquierda + 1; i <= derecha; i + +) {si (if (base]; int j = izquierda; para (int i = izquierda + 1; i <= derecha; i + +) {si (if (base]; int j = izquierda; para (int i = izquierda + 1; i <= derecha; i + +) {if (si (base]; int j = izquierda; para (int i = izquierda + 1; i <= derecha; i ++) > 0) {j ++; swap (arr, j, i);}} swap (arr, left, j); return j; // return la esquina inferior del valor base después de mentir en la clasificación} public static void swap (object [] arr, int i, int j) {if (i! = J) {objeto temp = arr [i]; arr [i] = arr [j]; j] = temp; printarr (objeto [] arr) {for (object o: arr) {system.out.print (o); system.out.print ("/t");} system.out.println ();} public static void main (string []) {entero [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; imprent (arr)//3 1 7 3 3 2 3 3 3. 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}La clasificación rápida continúa optimizando: clasificación rápida de dos vías
En la clasificación rápida normal inicial, se dice que el valor base en el lado izquierdo de la base es más pequeño que la base, mientras que la base en el lado derecho es mayor o igual a la base. Estos igual a la base se reunirán a la derecha (o cambiarán ligeramente la relación de tamaño se reunirá a la izquierda). De todos modos, se volverá a apartar. Cuando se repiten muchos números en la matriz, conducirá a una gran diferencia en el tamaño de los dos subs. En este momento, quiero asignar los números iguales a la base a ambos lados de la base, en lugar de reunirlos.
(Nota: al probar el código, es mejor mirar la parte del tipo de inserción y parecer en mi código a continuación ... de lo contrario, cuando el volumen de datos es menor que k = 16, el tipo de inserción se realiza ...)
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param Arr Array para ordenarse* @param Izquierda Cerrar a la izquierda* @param Cerrar a la derecha* @param K Cuando la clasificación rápida se recursa en la escala del subproblem <= k, la optimización de inserción de clasificación se usa* @Param <t> genic, genic, se clasifica a la clasificación de la clasificación, se compara. Comparable <? Super t >> void sort (t [] arr, int loft, int right, int k) {// insisttionsort (arr, izquierda, derecha); // return; //} if (izquierda> = right) return; int p = partition (arr, izquierda, derecha); sort (arr, izquierda, derecha); sort (arr, izquierda, P - 1, k); sort (arr, p + 1, derecha, k);} Public staty); Super t >> sin inycionsort (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && curareto (arr [j]) <0; j--) {j + 1] = arr [j];} arr [j + 1] <T se extiende comparable <? Super t >> int Partition (t [] arr, int izquierdo, int right) {// Antes de clasificar, deje que el valor de referencia intercambie con un número aleatorio. De esta manera, el valor de referencia es aleatorio. // no hará que las escalas recursivas de los lados izquierdo y derecho sean inconsistentes cuando la matriz se ordene relativamente, lo que resulta en el peor intercambio de complejidad de tiempo (arr, izquierda, (int) (math.random () * (derecha - izquierda + 1) + izquierda)); t base = arr [arruzo];//valor básico, tirar este valor de referencia cada tiempo, verlo como el tipo de [izquierda + 1 ... +1; // Para el intervalo [izquierda+1 ......... Derecha] mencionado en la línea anterior, I significa [izquierda+1 ...... i) El intervalo abierto a la derecha izquierda es menor o igual a la base. int j = derecho; // Para el intervalo [izquierda+1 ... 1 ...... derecha] mencionado en las dos líneas anteriores, j significa que los valores de (j ...... derecha] intervalos de color abierto y cerrado a la derecha izquierda son mayores o iguales a la base. While (true) {// escanear de izquierda a derecha, escanee el primer elemento más grande que la base, y luego me detengo. fuera el primer elemento más pequeño que la base, y luego J se detiene allí. static void swap (object [] arr, int i, int j) {if (i! = j) {objeto temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} Private Static void printarr (objeto [] arr) {para (objeto o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {entero [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 8 0 4 4 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Continúe optimizando la clasificación rápida: dos clasificaciones rápidas no requieren intercambio, use intercambio
Cuando las dos rutas anteriores encuentran valores mayores que la base y los valores menores que la base, usan el método swap () para intercambiar. El intercambio de dos dígitos implica la operación de la tercera temperatura variable, con más operaciones de lectura y escritura. A continuación, use el método de asignación directa para colocar el menor que a la derecha y el mayor que a la izquierda. Cuando yo y J nos reunimos, esa posición es donde se debe colocar la base. Este viaje se completa. Solo recurrir.
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param Arr Array para ordenarse* @param Izquierda Cerrar a la izquierda* @param Cerrar a la derecha* @param K Cuando la clasificación rápida se recursa en la escala del subproblem <= k, la optimización de inserción de clasificación se usa* @Param <t> genic, genic, se clasifica a la clasificación de la clasificación, se compara. Comparable <? Super t >> void sort (t [] arr, int loft, int right, int k) {// insisttionsort (arr, izquierda, derecha); // return; //} if (izquierda> = right) return; int p = partition (arr, izquierda, derecha); sort (arr, izquierda, derecha); sort (arr, izquierda, P - 1, k); sort (arr, p + 1, derecha, k);} Public staty); Super t >> sin inycionsort (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && curareto (arr [j]) <0; j--) {j + 1] = arr [j];} arr [j + 1] <T se extiende comparable <? Super t >> int Partition (t [] arr, int izquierdo, int right) {// Antes de clasificar, deje que el valor de referencia intercambie con un número aleatorio. De esta manera, el valor de referencia es aleatorio. // no hará que las escalas recursivas de los lados izquierdo y derecho sean inconsistentes cuando la matriz esté relativamente ordenada, lo que resulta en el peor intercambio de complejidad de tiempo (arr, izquierdo, (int) (math.random () * (derecha-izquierda + 1) + izquierda)); t base = arr [arr [valor];/valor básico, tirar este valor de referencia cada tiempo, verlo como la especie de la forma de [izquierda + 1 ... = izquierda; // Para el intervalo [izquierda+1 ......... derecha] mencionado en la línea anterior, I significa [izquierda+1 ...... i) Los valores de intervalo cerrados a la derecha cerrada es menor o igual a la base. int j = right; // Para el intervalo [izquierda+1 ...... derecha] mencionado en las dos líneas anteriores, j significa que los valores de (j ...... derecha] intervalos de izquierda y cerrada a la derecha son mayores o iguales a la base. While (i <j) {// escanear desde la derecha a la izquierda, escanear el primer elemento más pequeño que la base, y luego j detente allí. mientras (j> i && arr [j] .compareto (base). arr [j]; // escanear de izquierda a derecha, escanee el primer elemento más grande que la base y luego me detengo allí. ! = j) {objeto temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private static void imprimir (objeto [] arr) {for (object o: arr) {system.out.print (o); system.out.print ("/t");} system.println ();} public static void main (string (string () {Entero [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 9 8 0 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}}}}}La clasificación rápida continúa optimizando: cuando se usan una gran cantidad de datos y muchas repeticiones, use una clasificación rápida de tres vías
Divida la matriz en tres caminos. La primera ruta es más pequeña que la base, la segunda ruta es igual a la base y la tercera ruta es mayor que la base.
Use un puntero para escanear de adelante hacia atrás, si:
1. El número apuntado por CUR es menor que la base, luego: intercambie los valores de arr [cur] y arr [i], y luego i ++, cur ++.
2. El número apuntado por CUR es igual a la base, entonces: Cur ++
3. El número apuntado por CUR es mayor que la base, luego: intercambie los valores de arr [cur] y arr [j], y luego j--.
Cuando CUR> J, significa que se han completado las tres rutas.
Public Class Quicksort {public static <t se extiende comparable <? Super t >> void sort (t [] arr) {sort (arr, 0, arr.length - 1, 16);}/*** @param Arr Array para ordenarse* @param Izquierda Cerrar a la izquierda* @param Cerrar a la derecha* @param K Cuando la clasificación rápida se recursa en la escala del subproblem <= k, la optimización de inserción de clasificación se usa* @Param <t> genic, genic, se clasifica a la clasificación de la clasificación, se compara. Comparable <? Super t >> void sort (t [] arr, int loft, int right, int k) {// insisttionsort (arr, izquierda, derecha); // return; //} if (izquierda> = right) return; int [] ret = partition (arr, izquierda, derecha); sort (arr, izquierda, ret [0], k); sort (arr, retr [1], derecha, k);} Public static <t se extiende extiende? Super t >> sin inserción (t [] arr, int l, int r) {for (int i = l + 1; i <= r; i ++) {t cur = arr [i]; int j = i-1; for (; j> = 0 && curpareto (arr [j]) <0; j--) {j + 1] = arr [j];} arr [j + 1] La matriz de Arr de @param se clasificará* @param izquierdo el límite izquierdo de la matriz para que se ordene* @param derecho el límite derecho de la matriz a clasificar* @param <t> genéricos* @return*/private static <t se extiende comparable <? Super t >> int [] particion (t [] arr, int izquierdo, int right) {// Antes de clasificar, deje que el valor de referencia se intercambie con un número aleatorio. De esta manera, el valor de referencia es aleatorio. // no hará que las escalas recursivas en los lados izquierda y derecha sean inconsistentes cuando la matriz sea relativamente ordenada, lo que resulta en el peor intercambio de complejidad de tiempo (arr, izquierdo, (int) (math.random () * (derecha - izquierda + 1) + izquierda)); t base = arr [arr [lente]; // valor básico, tirar este valor de referencia cada tiempo, verlo como el tipo de intento de la izquierda + 1 ...... ... Las filas se dividen en los siguientes tres canales (intervalos) int i = izquierda; // izquierda indica que [lleft ... izquierda) Los números en el intervalo abierto derecho cerrado izquierdo son más pequeños que la base int j = derecha; // Izquierda indica que (Rright ... derecha] Los números en los intervalos cerrados izquierdo y derecho son más grandes que la base INT de la base. <= j) {if (arr [cur] .compareto (base) == 0) {cur ++;} else if (arr [cur] .compareto (base) <0) {swap (arr, cur ++, i ++);} else {swap (arr, cur, j--);}} return int [] {i-1, j+1}; // El subproblema solo necesita resolver la izquierda y la derecha de I y J} public static void swap (object [] arr, int i, int j) {if (i! = j) {object temp = arr [i]; arr [i] = arr [j]; arr [j] = temp;}} private estatic imprentarr (objeto [] arr) {para (objeto o: arr) {System.out.print (o); System.out.print ("/t");} System.out.println ();} public static void main (string args []) {entero [] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6}; printarr (arr); // 3 5 1 7 2 8 0 4 4 4 6sort (arr); printarr (arr); // 0 1 2 3 4 5 6 7 8 9}}Resumir
Lo anterior es toda la explicación detallada de la implementación de programación Java Código de clasificación y optimización rápida. Espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!