Som Merge Sort, er QuickSort en Divide and Conquer-algoritme. Den plukker et element som pivot og partisjonerer den gitte matrisen rundt den valgte pivoten. Det er mange forskjellige versjoner av quickSort som velger pivot på forskjellige måter.
- Velg alltid det første elementet som pivot.
- Velg alltid det siste elementet som pivot (implementert nedenfor)
- Velg et tilfeldig element som pivot.
- Velg median som pivot.
Nøkkelprosessen i quickSort er partisjon (). Mål for partisjoner er, gitt en matrise og et element x av matrisen som pivot, setter x på riktig posisjon i sortert matrise og setter alle mindre elementer (mindre enn x) før x, og setter alle større elementer (større enn x) etter x. Alt dette bør gjøres i lineær tid.
Pseudokode for rekursiv QuickSort-funksjon:
Partisjonsalgoritme
Det kan være mange måter å gjøre partisjon på, etter at pseudokoden bruker metoden gitt i CLRS-boken. Logikken er enkel, vi starter fra elementet til venstre og holder oversikt over indeksen til mindre (eller lik) elementer som i. Mens vi krysser, hvis vi finner et mindre element, bytter vi nåværende element med arr. Ellers ignorerer vi nåværende element.
Pseudokode for partisjon ()
Illustrasjon av partisjon ():
Implementering:
Følgende er implementeringene av QuickSort:
Output:
Sorted array:1 5 7 8 9 10
Analyse av QuickSort
Tiden det tar av QuickSort generelt kan skrives som følger.
T(n) = T(k) + T(n-k-1) + (n)
De to første begrepene er for to rekursive samtaler, den siste termen er for partisjonsprosessen. k er antall elementer som er mindre enn pivot.
Tiden det tar av QuickSort, avhenger av inngangsmatrisen og partisjonsstrategien. Følgende er tre tilfeller.
Verste tilfelle: Det verste tilfellet oppstår når partisjonsprosessen alltid velger det største eller minste elementet som pivot. Hvis vi vurderer over partisjonsstrategi der siste element alltid blir valgt som pivot, ville det verste tilfellet oppstå når matrisen allerede er sortert i økende eller synkende rekkefølge. Følgende er gjentakelse i verste fall.
T(n) = T(0) + T(n-1) + (n)which is equivalent to T(n) = T(n-1) + (n)
Løsningen med gjentakelse ovenfor er (n2).
Beste tilfelle: Det beste tilfellet oppstår når partisjonsprosessen alltid velger midtre element som sving. Følgende er gjentakelse for best case.
T(n) = 2T(n/2) + (n)
Løsningen til gjentakelse ovenfor er (nLogn). Det kan løses ved å bruke case 2 i Master Theorem.
Gjennomsnittlig sak:
For å gjøre gjennomsnittlig saksanalyse må vi vurdere all mulig permutasjon av matrisen og beregne tiden det tar av hver permutasjon som ikke se enkelt ut.
Vi kan få en ide om gjennomsnittlig sak ved å vurdere saken når partisjonen setter O (n / 9) -elementer i ett sett og O (9n / 10) -elementer i et annet sett. Følgende er gjentakelse for denne saken.
T(n) = T(n/9) + T(9n/10) + (n)
Løsning av ovennevnte tilbakefall er også O (nLogn)
Selv om QuickSort i verste fall er tidskompleksiteten til O (n2) som er mer enn mange andre sorteringsalgoritmer som Merge Sort og Heap Sort, er QuickSort raskere i praksis, fordi den indre sløyfen kan implementeres effektivt på de fleste arkitekturer og i de fleste virkelige data. QuickSort kan implementeres på forskjellige måter ved å endre valg av pivot, slik at det verste tilfellet sjelden forekommer for en gitt type data. Imidlertid blir flettesorter generelt sett på som bedre når data er enorme og lagret i ekstern lagring.
Er QuickSort stabil?
Standardimplementeringen er ikke stabil. Imidlertid kan enhver sorteringsalgoritme gjøres stabil ved å betrakte indekser som sammenligningsparameter.
Er QuickSort på plass?
I henhold til den brede definisjonen av algoritme på stedet, kvalifiserer den som en stedlig sorteringsalgoritme, da den bruker ekstra plass bare for lagring av rekursive funksjonsanrop, men ikke for å manipulere inngangen.
Hvordan implementere QuickSort for lenkede lister?
QuickSort på enkeltkoblet liste
QuickSort på dobbeltkoblet liste
Kan vi implementere QuickSort Iterativt?
Ja, se Iterativ Quick Sort.
Hvorfor Quick Sort foretrekkes fremfor MergeSort for sortering av arrays
Rask sortering er i sin generelle form en stedssortering (dvs. det krever ikke ekstra lagring), mens sammenslåing krever O (N) ekstra lagring, N angir matrisestørrelsen som kan være ganske dyr. Tildeling og de-allokering av ekstra plass som brukes til flettesortering øker algoritmens kjøretid. Sammenligning av gjennomsnittlig kompleksitet finner vi at begge typer sorter har O (NlogN) gjennomsnittlig kompleksitet, men konstantene er forskjellige. For arrays mister flettesortering på grunn av bruk av ekstra O (N) lagringsplass.
De fleste praktiske implementeringer av Quick Sort bruker randomisert versjon. Den randomiserte versjonen har forventet tidskompleksitet på O (nLogn).Det verste tilfellet er også mulig i randomisert versjon, men i verste fall forekommer det ikke for et bestemt mønster (som sortert matrise), og randomisert Quick Sort fungerer bra i praksis.
Quick Sort er også en cache-vennlig sortering algoritme da den har god referanselokalitet når den brukes til matriser.
Quick Sort er også halen rekursiv, derfor er haleanropsoptimaliseringer gjort.
Hvorfor MergeSort foretrekkes fremfor QuickSort for sammenkoblede lister ?
Når det gjelder koblede lister, er saken forskjellig, hovedsakelig på grunn av forskjell i minnetildeling av matriser og koblede lister. I motsetning til matriser, kan det hende at koblede listenoder ikke ligger i minnet. I motsetning til array, i koblet liste, kan vi sette inn elementer i midten i O (1) ekstra plass og O (1) tid. Derfor kan fletteoperasjon av flettesortering implementeres uten ekstra plass for koblede lister.
I matriser kan vi gjøre tilfeldig tilgang ettersom elementene er kontinuerlige i minnet. La oss si at vi har et heltall (4-byte) matrise A og la adressen til A være x, så for å få tilgang til A, kan vi få direkte tilgang til minnet ved (x + i * 4). I motsetning til arrays, kan vi ikke gjøre tilfeldig tilgang i koblet liste. Rask sortering krever mye av denne typen tilgang. I koblet liste for å få tilgang til ith-indeksen, må vi reise hver eneste node fra hodet til ith-node, ettersom vi ikke har kontinuerlig hukommelse. Derfor øker overhead for rask sortering. Merge sort får tilgang til data sekvensielt og behovet for tilfeldig tilgang er lite.
Hvordan optimalisere QuickSort slik at det tar O (Log n) ekstra plass i verste fall?
Se QuickSort Tail Call Optimization (Redusering av worst case-plass til Log n)
Øyeblikksbilder:
- Quiz på QuickSort
- Nylige artikler om QuickSort
- Kodepraksis for sortering.
Andre sorteringsalgoritmer på GeeksforGeeks / GeeksQuiz:
Seleksjonssortering, Boblesortering, Innsettingssortering, Flettesortering, Haugsortering, Hurtigsortering , Radix Sort, Counting Sort, Bucket Sort, ShellSort, Comb Sort, Pigeonhole Sort