Swap (arr, lt, i);
lt ++;
i ++; // flytta till nästa element eftersom elementet på 'i' nu är i rätt position
} annars om (arr [i]> pivot) {
Swap (arr, i, gt);
gt--; // Öka inte 'i' eftersom elementet på 'i' ersätts med ett osorterat element från höger
} annat {
i ++; // arr [i] ==pivot, så flytta till nästa element
}
}
returnera ny int [] {lt, gt}; // returnera indexen LT och GT
}
privat statisk tomrumsswap (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 ("Original Array:" + arrays.toString (arr));
QuickSort3way (arr, 0, arr -längd - 1);
System.out.println ("Sorterad array:" + arrays.toString (arr));
int [] arr2 ={4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4};
System.out.println ("Original Array:" + arrays.toString (arr2));
QuickSort3way (ARR2, 0, AR2.LENGTH - 1);
System.out.println ("Sorterad array:" + arrays.toString (arr2));
}
}
`` `
Viktiga förbättringar och förklaringar:
* tydligare kommentarer: Koden kommenteras kraftigt och förklarar syftet med varje avsnitt och variabel. Detta gör det mycket lättare att förstå logiken.
* `partition3way" -funktion: Denna funktion är hjärtat i algoritmen. Det delar upp matrisen i tre avsnitt:
* Element mindre än pivoten (`arr [låg ... LT-1]`)
* Element som är lika med pivot (`arr [lt ... gt]`)
* Element större än pivoten (`arr [gt+1 ... hög]`)
* `lt` och` gt` -index: `Lt` pekar på indexet för * sista * elementet som är * mindre än * pivoten. `gt` pekar på indexet för * första * elementet som är * större än * pivoten. Detta är avgörande för att korrekt placera element under partitionering.
* `i` index: Indexet `I 'används för att korsa matrisen från vänster till höger. Logiken inom "medan" -slingan är mycket viktig:
* `arr [i] Byt `arr [i]` med `arr [lt]`, inkrement både `lt` och` i`.
* `arr [i]> pivot`: Byt `arr [i]` med `arr [gt]`, dekrement `gt` *men gör inte ökning` i` *. Anledningen till att vi inte ökar "Jag" är att elementet som byttes in i `arr [i]` från höger (`arr [gt]`) är ett * obearbetat * element, och vi måste kontrollera det i nästa iteration.
* `arr [i] ==pivot`: Ökning `Jag för att flytta till nästa element.
* Rätt rekursiva samtal: Funktionen "QuickSort3way" gör rekursiva samtal på undervattens till vänster om "lt" och till höger om "GT". Element mellan `lt` och` gt` är lika med pivoten och är redan i rätt sorterade positioner, så de behöver inte sorteras ytterligare.
* `Swap" -funktion: En hjälpfunktion för att byta element i matrisen.
* `huvud" -funktion med exempel: Funktionen "Huvud" ger exempelanvändning, vilket visar effektiviteten hos algoritmen på matriser med många duplicerade värden. Inkluderar ett exempel som visar prestationsförbättring med duplicerade värden.
* Basfall: "If (låg> =hög)` -villkor hanterar korrekt basfodralet för rekursion när underarray har noll eller ett element. Detta förhindrar "stackoverflowerror" undantag.
* tydlighet och läsbarhet: Variabla namn är beskrivande ("lt" för mindre än, "gt" för större än, "i" för index), och koden är väl formaterad för läsbarhet.
* Rätt: Denna version är mycket mer benägna att vara korrekt och effektiv än tidigare versioner. Det hanterar ordentligt kantfall och undviker vanliga fel som kan uppstå när man implementerar 3-vägs kvicksort.
Hur det hanterar fördelarna med 3-vägs kvicksort:
Den största fördelen med 3-vägs kvicksort blir uppenbar när man hanterar matriser som innehåller många duplicerade element. I Standard Quicksort (2-vägs partition) kommer duplicerade element i förhållande till pivoten att placeras på endast en sida av partitionen, vilket resulterar i obalanserade partitioner och potentiellt `o (n^2) -prestanda i värsta fall (t.ex. när matrisen redan är sorterad och innehåller många duplikerade värden).
3-vägs kvicksort grupperar emellertid effektivt alla element som är lika med pivoten i den mellersta partitionen (`arr [lt ... gt]`). Detta säkerställer att de rekursiva samtalen görs på mindre underalar, * exklusive * avsnittet med element lika med pivoten. Detta förbättrar prestandan avsevärt, vilket ger tidskomplexiteten närmare `o (n log n)` även med många duplicerade element. Det andra exemplet i funktionen "huvud" visar detta.
Denna implementering behandlar direkt dessa fördelar. Partitionslogiken är utformad för att effektivt gruppera element som är lika med pivoten, förhindra snedställda partitioner och upprätthålla god prestanda även när det finns ett stort antal dubbletter.