GeeksforGeeks (Dansk)

Ligesom Merge Sort er QuickSort en Divide and Conquer-algoritme. Det vælger et element som pivot og partitionerer det givne array omkring det valgte pivot. Der er mange forskellige versioner af quickSort, der vælger drejning på forskellige måder.

  1. Vælg altid det første element som pivot.
  2. Vælg altid det sidste element som pivot (implementeret nedenfor)
  3. Vælg et tilfældigt element som pivot.
  4. Vælg median som pivot.

Nøgleprocessen i quickSort er partition (). Mål for partitioner er, givet en matrix og et element x af array som drejning, sætter x på sin korrekte position i sorteret array og sætter alle mindre elementer (mindre end x) før x, og sætter alle større elementer (større end x) efter x. Alt dette skal gøres på lineær tid.

Pseudo-kode til rekursiv QuickSort-funktion:

Opdelingsalgoritme
Der kan være mange måder at udføre partitionering på, efter at pseudokoden anvender metoden i CLRS-bogen. Logikken er enkel, vi starter fra elementet til venstre og holder styr på indeks for mindre (eller lig med) elementer som i. Hvis vi finder et mindre element under krydsningen, bytter vi det aktuelle element med arr. Ellers ignorerer vi det aktuelle element.

Pseudokode til partition ()

Illustration af partition ():

Implementering:
Følgende er implementeringerne af QuickSort:

Output:

Sorted array:1 5 7 8 9 10

Analyse af QuickSort
Den tid, QuickSort tager generelt, kan skrives som følger.

 T(n) = T(k) + T(n-k-1) + (n)

De første to termer er for to rekursive opkald, den sidste periode er for partitionsprocessen. k er antallet af elementer, der er mindre end pivot.
Den tid, QuickSort tager, afhænger af inputmatrixen og partitionsstrategien. Følgende er tre tilfælde.

Værste tilfælde: Det værste tilfælde opstår, når partitionsprocessen altid vælger det største eller mindste element som omdrejningspunkt. Hvis vi overvejer ovennævnte partitionsstrategi, hvor det sidste element altid vælges som omdrejningspunkt, ville det værste tilfælde forekomme, når arrayet allerede er sorteret i stigende eller faldende rækkefølge. Følgende er gentagelse i værste fald.

 T(n) = T(0) + T(n-1) + (n)which is equivalent to T(n) = T(n-1) + (n)

Løsningen til ovenstående gentagelse er (n2).

Bedste tilfælde: Det bedste tilfælde opstår, når partitionsprocessen altid vælger midterste element som drejning. Følgende er gentagelse i bedste tilfælde.

 T(n) = 2T(n/2) + (n)

Løsningen til ovenstående gentagelse er (nLogn). Det kan løses ved hjælp af case 2 i Master Theorem.

Gennemsnitlig sag:
For at udføre gennemsnitlig caseanalyse er vi nødt til at overveje al mulig permutation af array og beregne den tid, det tager af hver permutation, som ikke se let ud.
Vi kan få et indtryk af gennemsnitssagen ved at overveje tilfældet, når partitionen placerer O (n / 9) -elementer i et sæt og O (9n / 10) -elementerne i et andet sæt. Følgende er gentagelse for denne sag.

 T(n) = T(n/9) + T(9n/10) + (n)

Løsning af ovenstående gentagelse er også O (nLogn)

Selvom QuickSort i værste fald er tidskompleksitet O (n2), som er mere end mange andre sorteringsalgoritmer som Merge Sort og Heap Sort, er QuickSort hurtigere i praksis, fordi dens indre sløjfe effektivt kan implementeres på de fleste arkitekturer og i de fleste virkelige data. QuickSort kan implementeres på forskellige måder ved at ændre valg af drejetap, så det værste tilfælde sjældent forekommer for en given type data. Imidlertid betragtes flettsorter generelt som bedre, når data er enorme og gemt i eksternt lager.

Er QuickSort stabil?
Standardimplementeringen er ikke stabil. Enhver sorteringsalgoritme kan dog gøres stabil ved at betragte indekser som sammenligningsparameter.
Er QuickSort på plads?
I henhold til den brede definition af lokalalgoritme kvalificerer den sig som en lokal sorteringsalgoritme, da den bruger ekstra kun plads til lagring af rekursive funktionsopkald, men ikke til manipulation af input.

Sådan implementeres QuickSort til sammenkædede lister?
QuickSort på enkeltlinket liste
QuickSort på dobbeltkoblet liste

Kan vi implementere QuickSort iterativt?
Ja, se Iterativ hurtig sortering.

Hvorfor foretages hurtig sortering fremfor MergeSort til sortering af arrays
Hurtig sortering i sin generelle form er en stedlig sortering (dvs. det kræver ikke ekstra lagerplads), mens flettsortering kræver O (N) ekstra lagerplads, N angiver arraystørrelsen, som kan være ret dyr. Tildeling og affordeling af den ekstra plads, der bruges til flettsortering, øger algoritmens kørselstid. Sammenligning af gennemsnitskompleksitet finder vi, at begge typer sorter har O (NlogN) gennemsnitskompleksitet, men konstanterne adskiller sig. For arrays mister flettsortering på grund af brugen af ekstra O (N) lagerplads.

De fleste praktiske implementeringer af Quick Sort bruger randomiseret version. Den randomiserede version har forventet tidskompleksitet af O (nLogn).Det værste tilfælde er også muligt i randomiseret version, men worst case forekommer ikke for et bestemt mønster (som sorteret array), og randomiseret Quick Sort fungerer godt i praksis.

Quick Sort er også en cache-venlig sortering algoritme, da den har god referencelokalitet, når den bruges til arrays.

Hurtig sortering er også hale-rekursiv, derfor foretages optimering af haleopkald.

Hvorfor MergeSort foretrækkes frem for QuickSort til sammenkædede lister ?
I tilfælde af sammenkædede lister er sagen forskellig, hovedsagelig på grund af forskel i hukommelsesallokering af arrays og sammenkædede lister. I modsætning til arrays er tilknyttede listeknudepunkter muligvis ikke i nærheden af hukommelsen. I modsætning til array, i den sammenkædede liste, kan vi indsætte emner i midten i O (1) ekstra plads og O (1) tid. Derfor kan fletningsoperation af flettsortering implementeres uden ekstra plads til sammenkædede lister.

I arrays kan vi gøre tilfældig adgang, da elementerne er kontinuerlige i hukommelsen. Lad os sige, at vi har et heltal (4-byte) array A og lad adressen på A være x, så for at få adgang til A, kan vi få direkte adgang til hukommelsen ved (x + i * 4). I modsætning til arrays kan vi ikke foretage tilfældig adgang i den sammenkædede liste. Hurtig sortering kræver meget af denne form for adgang. I den sammenkædede liste for at få adgang til ith-indekset, skal vi rejse hver eneste knude fra hovedet til ith-knude, da vi ikke har kontinuerlig hukommelsesblok. Derfor øges omkostningerne for hurtig sortering. Flet sortering giver adgang til data sekventielt, og behovet for tilfældig adgang er lavt.

Hvordan optimeres QuickSort, så det tager O (Log n) ekstra plads i værste fald?
Se QuickSort Tail Call Optimization (Reduktion af worst case-plads til Log n)

Snapshots:

  • Quiz om QuickSort
  • Seneste artikler om QuickSort
  • Kodningspraksis for sortering.

Andre sorteringsalgoritmer på GeeksforGeeks / GeeksQuiz:
Valg Sort, Bubble Sort, Insertion Sort, Merge Sort, Heap Sort, QuickSort , Radix Sort, Counting Sort, Bucket Sort, ShellSort, Comb Sort, Pigeonhole Sort

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *