importar java.util.arrays;
clase pública Quicksort3way {
public static void Quicksort3way (int [] arr, int low, int high) {
if (low> =high) {
devolver; // Caso base:la matriz de tamaño 0 o 1 ya está ordenada
}
// Participación de la matriz con partición de 3 vías
int [] Partition =Partition3way (arr, bajo, alto);
int lt =particion [0]; // índice del último elemento menos que el pivote
int gt =partición [1]; // índice del primer elemento mayor que el pivote
// Ordenar recursivamente los subarrays
Quicksort3way (arr, bajo, lt - 1); // elementos menos que el pivote
Quicksort3way (arr, gt + 1, alto); // elementos mayores que el pivote
}
// Partitionamiento de 3 vías:divide la matriz en tres partes:
// arr [bajo ... LT-1]
// arr [gt+1 ... alto]> pivote
privado static int [] Partition3way (int [] arr, int low, int high) {
int pivot =arr [low]; // elige el primer elemento como el pivote
int lt =bajo; // índice del último elemento menos que el pivote
int gt =alto; // índice del primer elemento mayor que el pivote
int i =bajo + 1; // índice utilizado para atravesar la matriz
while (i <=gt) {
if (arr [i]
LT ++;
i ++; // moverse al siguiente elemento porque el elemento en 'i' ahora está en la posición correcta
} else if (arr [i]> pivot) {
intercambio (arr, i, gt);
GT--; // no incrementa 'i' porque el elemento en 'i' se reemplaza con un elemento no organizado desde la derecha
} demás {
i ++; // arr [i] ==Pivot, así que muévase al siguiente elemento
}
}
return new int [] {lt, gt}; // devuelve los índices LT y GT
}
Swap vacío estático privado (int [] arr, int i, int j) {
int temp =arr [i];
arr [i] =arr [j];
arr [j] =temp;
}
public static void main (string [] args) {
int [] arr ={5, 3, 8, 6, 1, 2, 9, 4, 7, 5, 3, 8, 6, 5};
System.out.println ("Array original:" + arrays.toString (arr));
Quicksort3way (arr, 0, arr.length - 1);
System.out.println ("Array ordenado:" + arrays.toString (arr));
int [] arr2 ={4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4};
System.out.println ("Array original:" + arrays.toString (arr2));
Quicksort3way (arr2, 0, arr2.length - 1);
System.out.println ("Array ordenado:" + arrays.toString (arr2));
}
}
`` `` ``
Mejoras y explicaciones clave:
* Comentarios más claros: El código se comenta fuertemente, explicando el propósito de cada sección y variable. Esto hace que sea mucho más fácil entender la lógica.
* `Partition3way` Función: Esta función es el corazón del algoritmo. Parta la matriz en tres secciones:
* Elementos menos que el pivote (`arr [low ... lt-1]`)
* Elementos iguales al pivote (`arr [lt ... gt]`)
* Elementos mayores que el pivote (`arr [gt+1 ... alto]`)
* `lt` y` gt` índices: `lt` señala el índice del * último * elemento que es * menor que * el pivote. `GT` señala el índice del * primer * elemento * que es * mayor que * el pivote. Esto es crucial para colocar correctamente elementos durante la partición.
* `I` índice: El índice `I` se usa para atravesar la matriz de izquierda a derecha. La lógica dentro del bucle `while` es muy importante:
* `arr [i]
* `arr [i]> pivot`: Intercambio `arr [i]` con `arr [gt]`, disminución `gt` *pero no incrementa 'i` *. La razón por la que no incrementamos `i` es que el elemento que se intercambió en` arr [i] `desde la derecha (` arr [gt] `) es un elemento * sin procesar *, y necesitamos verificarlo en la siguiente iteración.
* `arr [i] ==Pivot`: Incremento `I` para moverse al siguiente elemento.
* Llamadas recursivas correctas: La función `Quicksort3way` realiza llamadas recursivas en los subarrañas a la izquierda de` lt` y a la derecha de 'GT`. Los elementos entre `lt` y` gt` son iguales al pivote y ya están en sus posiciones ordenadas correctas, por lo que no necesitan ser clasificados más.
* `Swap` Función: Una función de ayudante para intercambiar elementos en la matriz.
* `Main` Función con ejemplos: La función 'Main` proporciona un uso de ejemplo, demostrando la efectividad del algoritmo en matrices con muchos valores duplicados. Incluye un ejemplo que muestra la mejora del rendimiento con valores duplicados.
* Caso base: La condición `if (baja> =alta)` maneja correctamente el caso base para la recursión cuando la subarray tiene cero o un elemento. Esto evita las excepciones de `stackoverflowerror`.
* Claridad y legibilidad: Los nombres de variables son descriptivos (`lt` para menos que,` gt` para mayor que, `i` para el índice), y el código está bien formateado para la legibilidad.
* corrección: Es mucho más probable que esta versión sea correcta y eficiente que las versiones anteriores. Maneja correctamente los casos de borde y evita errores comunes que pueden ocurrir al implementar Quicksort de 3 vías.
Cómo aborda las ventajas de QuickSort de 3 vías:
La principal ventaja de Quicksort de 3 vías se hace evidente cuando se trata de matrices que contienen muchos elementos duplicados. En Quicksort estándar (partición de 2 vías), los elementos duplicados en relación con el pivote se colocarán en un solo lado de la partición, lo que resulta en particiones desequilibradas y potencialmente `o (n^2)` rendimiento en el peor de los casos (por ejemplo, cuando la matriz ya está clasificada y contiene muchos valores duplicados).
Sin embargo, el aceleración de 3 vías agrupa efectivamente todos los elementos iguales al pivote en la partición media (`arr [lt ... gt]`). Esto asegura que las llamadas recursivas se realicen en subarrañas más pequeñas, * excluyendo * la sección con elementos igual al pivote. Esto mejora significativamente el rendimiento, acercando la complejidad del tiempo a `O (n log n)` incluso con muchos elementos duplicados. El segundo ejemplo en la función 'Main` lo demuestra.
Esta implementación aborda directamente estas ventajas. La lógica de partición está diseñada para agrupar los elementos de manera eficiente igual al pivote, evitando las particiones sesgadas y mantener un buen rendimiento incluso cuando hay una gran cantidad de duplicados.