import java.util.arrays;
Classe pubblica QuickSort3way {
public static void QuickSort3way (int [] arr, int basso, int alto) {
if (low> =alto) {
ritorno; // Caso di base:l'array di dimensione 0 o 1 è già ordinato
}
// partizione dell'array usando il partizionamento a 3 vie
int [] partizione =partizione3way (arr, basso, alto);
int lt =partizione [0]; // indice dell'ultimo elemento inferiore al perno
int gt =partizione [1]; // indice del primo elemento maggiore del perno
// ordina ricorsivamente i subarrays
QuickSort3way (arr, basso, lt - 1); // elementi meno del perno
QuickSort3way (arr, GT + 1, alto); // elementi maggiori del perno
}
// Partizionamento a 3 vie:partizioni l'array in tre parti:
// arr [basso ... lt-1]
// arr [gt+1 ... alto]> pivot
privato static int [] partizione3way (int [] arr, int basso, int alto) {
int pivot =arr [basso]; // Scegli il primo elemento come perno
int lt =basso; // indice dell'ultimo elemento inferiore al perno
int gt =alto; // indice del primo elemento maggiore del perno
int i =basso + 1; // indice utilizzato per attraversare l'array
while (i <=gt) {
if (arr [i]
LT ++;
I ++; // Passa all'elemento successivo perché l'elemento in 'i' è ora nella posizione corretta
} else if (arr [i]> pivot) {
scambia (arr, i, gt);
GT--; // Non incrementare 'i' perché l'elemento a 'i' viene sostituito con un elemento non desiderato da destra
} altro {
I ++; // arr [i] ==pivot, quindi spostati all'elemento successivo
}
}
restituire new int [] {lt, gt}; // restituisce gli indici LT e GT
}
swap vuoto statico privato (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 originale:" + arrays.tostring (arr));
QuickSort3way (arr, 0, arr.length - 1);
System.out.println ("Array Ordined:" + Arrays.ToString (arr));
int [] arr2 ={4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4};
System.out.println ("Array originale:" + Arrays.ToString (ARR2));
QuickSort3way (arr2, 0, arr2.length - 1);
System.out.println ("Array ordinato:" + Arrays.ToString (ARR2));
}
}
`` `
Miglioramenti e spiegazioni chiave:
* Commenti più chiari: Il codice è fortemente commentato, spiegando lo scopo di ciascuna sezione e variabile. Questo rende molto più facile capire la logica.
* `Partition3way` Funzione: Questa funzione è il cuore dell'algoritmo. Partizza l'array in tre sezioni:
* Elementi inferiori al perno (`arr [Low ... lt-1]`)
* Elementi uguali al perno (`arr [lt ... gt]`)
* Elementi maggiori del perno (`arr [gt+1 ... alto]`)
* `lt` e` gt` indici: `Lt` indica l'indice dell'elemento * ultimo * che è * meno del * perno. `gt` indica l'indice del * primo * elemento * maggiore del * pivot. Questo è cruciale per il posizionamento corretto degli elementi durante il partizionamento.
* `I` indice: L'indice `I` viene utilizzato per attraversare l'array da sinistra a destra. La logica all'interno del ciclo `why` è molto importante:
* `arr [i]
* `arr [i]> pivot`: Scambia `arr [i]` con `arr [gt]`, decremento `gt` *ma non incrementare` i` *. Il motivo per cui non incrediamo `I` è che l'elemento che è stato scambiato in` arr [i] `da destra (` arr [gt] `) è un elemento * non elaborato * e dobbiamo controllarlo nella prossima iterazione.
* `arr [i] ==pivot`: Incremento `Devo passare all'elemento successivo.
* Chiamate ricorsive corrette: La funzione `QuickSort3way" fa chiamate ricorsive sui subarrays a sinistra di `lt` e a destra di` gt '. Gli elementi tra `lt` e` gt` sono uguali al perno e sono già nelle loro posizioni ordinate corrette, quindi non hanno bisogno di essere ordinati ulteriormente.
* `Swap` Function: Una funzione di supporto per scambiare elementi nell'array.
* Funzione principale "con esempi: La funzione "principale" fornisce un utilizzo di esempio, dimostrando l'efficacia dell'algoritmo su array con molti valori duplicati. Include un esempio che mostra il miglioramento delle prestazioni con i valori duplicati.
* Caso base: La condizione `if (basso> =alto)` gestisce correttamente il caso di base per la ricorsione quando il subarray ha zero o un elemento. Ciò impedisce le eccezioni di `stackoverflowerror '.
* chiarezza e leggibilità: I nomi delle variabili sono descrittivi (`lt` per meno di,` gt` per maggiore di, `io` per indice) e il codice è ben formattato per la leggibilità.
* correttezza: Questa versione ha molte più probabilità di essere corretta ed efficiente rispetto alle versioni precedenti. Gestisce correttamente i casi di bordo ed evita errori comuni che possono verificarsi durante l'implementazione di QuickSort a 3 vie.
Come affronta i vantaggi di QuickSort a 3 vie:
Il vantaggio principale di QuickSort a 3 vie diventa evidente quando si tratta di array che contengono molti elementi duplicati. Nella QuickSort standard (partizione a 2 vie), gli elementi duplicati rispetto al perno verranno posizionati su un solo lato della partizione, risultando in partizioni sbilanciate e potenzialmente `o (n^2)` prestazioni nel caso peggiore (ad esempio, quando l'array è già ordinato e contiene molti valori duplicati).
Quicksort a 3 vie, tuttavia, raggruppa efficacemente tutti gli elementi uguali al perno nella partizione centrale (`arr [lt ... gt]`). Ciò garantisce che le chiamate ricorsive siano effettuate su subarray più piccoli, * esclusi * la sezione con elementi pari al perno. Ciò migliora significativamente le prestazioni, avvicinando la complessità temporale a `O (n log n)` anche con molti elementi duplicati. Il secondo esempio nella funzione `Main` dimostra questo.
Questa implementazione affronta direttamente questi vantaggi. La logica di partizione è progettata per raggruppare in modo efficiente elementi pari al perno, prevenendo le partizioni distorte e mantenendo buone prestazioni anche quando ci sono un gran numero di duplicati.
Informazioni correlate
Programmazione © www.354353.com