Rask sortering i Java forklart

Quick Sort Java Explained



Hurtigsortering, også skrevet som Quicksort, er et listsorteringsskjema som bruker skill-og-erobre-paradigmet. Det er forskjellige ordninger for Quick Sort, som alle bruker divide-and-conquer-paradigmet. Før du forklarer Quick Sort, må leseren kjenne til konvensjonen for å halvere en liste eller en underliste og medianen til tre verdier.

Halveringskonvensjon

Når antall elementer i en liste er jevnt, betyr halvering av listen at den bokstavelige første halvdelen av listen er den første halvdelen, og den bokstavelige andre halvdelen av listen er den andre halvdelen. Det midtre (midtre) elementet i hele listen, er det siste elementet i den første listen. Dette betyr at den midterste indeksen er lengde / 2 - 1, ettersom indekstellingen begynner fra null. Lengde er antall elementer i listen. For eksempel, hvis antallet elementer er 8, har den første halvdelen av listen 4 elementer, og den andre halvdelen av listen har også 4 elementer. Det er greit. Siden indekstellingen begynner fra 0, er den midterste indeksen 3 = 8 /2 - 1.







Hva med saken, når antall elementer i listen eller underlisten er merkelig? I starten er lengden fortsatt delt med 2. Etter konvensjon er antall elementer i første halvdel av denne divisjonen lengde / 2 + 1/2. Indekstelling begynner fra null. Den midterste indeksen er gitt med lengde / 2 - 1/2. Dette betraktes som mellomtiden, etter konvensjon. For eksempel, hvis antall elementer i en liste er 5, er den midterste indeksen 2 = 5/2 - 1/2. Og det er tre elementer i første halvdel av listen og to elementer i andre halvdel. Det midterste elementet i hele listen er det tredje elementet ved indeks, 2, som er den midterste indeksen fordi indekstelling begynner fra 0.



Divisjon på denne måten er et eksempel på heltall aritmetikk.



Median av tre verdier

Spørsmål: Hva er medianen for sekvensen:





C B A

Løsning:
Ordne listen i stigende rekkefølge:



A B C

Middels sikt, B, er medianen. Det er størrelsen som ligger mellom de to andre størrelsene.

Å lete etter medianen i en liste er ikke sånn. For eksempel, i en liste med 19 usorterte elementer, kan medianen for det første elementet, det midterste elementet og det siste elementet være nødvendig. Disse tre verdiene er kanskje ikke i stigende rekkefølge; og indeksene deres må tas i betraktning.

Med Hurtigsortering er medianen for hele listen og underlistene påkrevd. Pseudokoden for å se etter medianen av tre verdier fordelt på en liste (matrise) er:

midt: =(lav+høy) / 2
hvisarr[midt] <arr[lav]
bytt arr[lav]med arr[midt]
hvisarr[høy] <arr[lav]
bytt arr[lav]med arr[høy]
hvisarr[midt] <arr[høy]
bytt arr[midt]med arr[høy]
dreie: =arr[høy]

Begrepet arr betyr matrise. Dette kodesegmentet ser etter medianen og gjør også litt sortering. Dette kodesegmentet ser enkelt ut, men det kan være ganske forvirrende. Så vær oppmerksom på følgende forklaring:

Sorteringen i denne opplæringen vil produsere en liste der den første verdien er den minste verdien, og den siste verdien er den største verdien. Med alfabetet er A mindre enn Z.

Her er pivoten den resulterende medianen. Lav er den laveste indeksen på listen eller underlisten (ikke nødvendigvis for den laveste verdien); høy er den høyeste indeksen på listen eller underlisten (ikke nødvendigvis for den høyeste verdien), og midten er den konvensjonelle midtindeksen (ikke nødvendigvis for den midterste verdien av hele listen).

Medianen som skal oppnås er mellom verdien av den laveste indeksen, verdien av den midterste indeksen og verdien av den høyeste indeksen.

I koden oppnås den konvensjonelle midtindeksen først. Ved denne starten er listen usortert. Sammenligningen og noen omorganisering i stigende rekkefølge av de tre verdiene skal skje samtidig. Den første if-setningen sammenligner verdien for den laveste indeksen og den for den midterste indeksen. Hvis den for den midterste indeksen er mindre enn den for den laveste indeksen, bytter de to verdiene posisjoner. Dette begynner å sortere og endrer ordningen av verdier i listen eller underlisten. Den andre if-setningen sammenligner verdien for den høyeste indeksen og den for den laveste indeksen. Hvis den for den høyeste indeksen er mindre enn den for den laveste indeksen, bytter de to verdiene posisjoner. Dette fortsetter med en sortering og endring av verdiordningen i listen eller underlisten. Den tredje if-setningen sammenligner verdien for den mellomste indeksen og den for den høyeste indeksen. Hvis den for den høyeste indeksen er mindre enn den midterste indeksen, bytter de to verdiene posisjoner. Noe sortering eller omorganisering kan også forekomme her. Denne tredje if-betingelsen er ikke som de to foregående.

På slutten av disse tre byttene ville mellomverdien til de tre aktuelle verdiene være A [høy], hvis opprinnelige innhold kan ha blitt endret i kodesegmentet. Tenk for eksempel på den usorterte sekvensen:

C B A

Vi vet allerede at medianen er B. Dette bør imidlertid bevises. Målet her er å oppnå medianen av disse tre verdiene ved hjelp av kodesegmentet ovenfor. Den første if-setningen sammenligner B og C. Hvis B er mindre enn C, må posisjonene til B og C byttes. B er mindre enn C, så det nye arrangementet blir:

B C A

Legg merke til at verdiene for den laveste indeksen og den midterste indeksen har endret seg. Den andre if-setningen sammenligner A og B. Hvis A er mindre enn B, må posisjonene til A og B byttes. A er mindre enn B, så det nye arrangementet blir:

A C B

Legg merke til at verdiene for den høyeste indeksen og den laveste indeksen har endret seg. Den tredje if-setningen sammenligner C og B. Hvis C er mindre enn B, må posisjonene til C og B byttes. C er ikke mindre enn B, så ingen bytte finner sted. Den nye ordningen forblir som den forrige, det vil si:

A C B

B er medianen, som er A [høy], og det er svinget. Så, pivoten er født i den ekstreme enden av listen eller undelisten.

Byttingsfunksjonen

En annen funksjon som er nødvendig for Quick Sort er byttefunksjonen. Byttingsfunksjonen, utveksler verdiene til to variabler. Pseudokoden for byttefunksjonen er:

definere bytte(x,og)
temp: =x
x: =og
og: =temp

Her refererer x og y til de faktiske verdiene og ikke til kopiene.

Sorteringen i denne artikkelen vil produsere en liste der den første verdien er den minste verdien, og den siste verdien er den største verdien.

Artikkelinnhold

Hurtigsorteringsalgoritme

Den normale måten å sortere en usortert liste på er å vurdere de to første verdiene. Hvis de ikke er i orden, legg dem i orden. Vurder deretter de tre første verdiene. Skann de to første for å se hvor den tredje verdien passer og passe den på riktig måte. Vurder deretter de fire første verdiene. Skann de tre første verdiene for å se hvor den fjerde verdien passer og passe den på riktig måte. Fortsett med denne fremgangsmåten til hele listen er sortert.

Denne prosedyren, også kjent som brute-force sort, i dataprogrammeringsspråket, er for treg. Hurtigsorteringsalgoritmen kommer med en mye raskere prosedyre.

Trinnene for quicksort -algoritmen er som følger:

  1. Sørg for at det er minst 2 tall å sortere i den usorterte listen.
  2. Få en estimert sentral verdi for listen, kalt pivot. Medianen, som beskrevet ovenfor, er en måte å oppnå pivoten på. Ulike måter kommer med sine fordeler og ulemper. - Ser senere.
  3. Del listen. Dette betyr at du plasserer pivoten i listen. På en slik måte er alle elementene til venstre mindre enn pivotverdien, og alle elementene til høyre er større enn eller lik pivotverdien. Det er forskjellige måter å dele opp på. Hver partisjonsmetode har sine fordeler og ulemper. Partisjonering er å dele seg i skill-og-erobre-paradigmet.
  4. Gjenta trinn 1, 2 og 3 rekursivt for de nye underlisteparene som dukker opp til hele listen er sortert. Dette erobrer i skillet-og-erobre-paradigmet.

Hurtigsorteringspseudokoden er:

algoritme quicksort(arr,lav,høy)er
hvislav<høyt da
dreie(lav,høy)
s: =skillevegg(arr,lav,høy)
kvicksort(arr,lav,s- 1)
kvicksort(arr,s+ 1,høy)

En partisjon Pseudokode

Partisjonspseudokoden som brukes i denne opplæringen er:

algoritmepartisjon(arr,lav,høy)er
dreie: =arr[høy]
Jeg: =lav
j: =høy
gjøre
gjøre
++Jeg
samtidig som(arr[Jeg] <dreie)
gjøre
-j
samtidig som(arr[j] >dreie)
hvis (Jeg<j)
bytt arr[Jeg]med arr[j]
samtidig som(Jeg<j)
bytt arr[Jeg]med arr[høy]
komme tilbakeJeg

I illustrasjonen av Hurtigsortering nedenfor, brukes denne koden:

Illustrasjon av Quick Sort

Tenk på følgende usorterte liste (matrise) med alfabetiske bokstaver:

Q W E R T Y U I O P

Ved inspeksjon er den sorterte listen:

E I O P Q R T U W Y

Den sorterte listen vil nå bli bevist, ved hjelp av algoritmen og pseudokodesegmentene ovenfor, fra den usorterte listen:

Q W E R T Y U I O P

Den første pivoten bestemmes fra arr [0] = Q, arr [4] = T og arr [9] = P, og identifiseres som Q og plasseres ytterst til høyre på listen. Så, listen med hvilken som helst pivotfunksjonssortering blir:

P W E R T Y U I O Q

Den nåværende pivoten er Q. Pivotprosedyren gjorde en liten sortering og plasserte P i den første posisjonen. Den resulterende listen må omorganiseres (partisjoneres), slik at alle elementene til venstre er mindre i verdi, deretter er pivoten og alle elementene til høyre for pivoten lik eller større enn pivoten. Datamaskinen kan ikke dele seg ved inspeksjon. Så det gjør det ved å bruke indeksene og partisjonsalgoritmen ovenfor.

De lave og høye indeksene er nå 0 og 9. Så datamaskinen begynner med å skanne fra indeksen 0 til den når en indeks, hvis verdi er lik eller større enn pivoten og stopper der midlertidig. Den vil også skanne fra høy (høyre) ende, indeks 9, nedover, til den når en indeks hvis verdi er mindre enn eller lik pivoten og stopper der midlertidig. Dette betyr to stoppstillinger. Hvis i, den inkrementelle indeksvariabelen, fra lav ennå ikke er lik eller større enn den synkende indeksvariabelen, j fra høy, så byttes disse to verdiene. I den nåværende situasjonen stoppet skanning fra begge ender ved W og O. Så listen blir:

P O E R T Y U I W Q

Pivoten er fortsatt Q. Skanningen i motsatte retninger fortsetter og stopper deretter. Hvis i ennå ikke er lik eller større enn j, byttes de to verdiene der skanning fra begge ender stoppet. Denne gangen stoppet skanningen fra begge ender ved R og I. Så ordningen av listen blir:

P O E I T Y U R W Q

Pivoten er fortsatt Q. Skanningen i motsatte retninger fortsetter og stopper deretter. Hvis i ennå ikke er lik eller større enn j, byttes de to verdiene som skanningen stoppet med. Denne gangen stoppet skanning fra begge ender ved T for i og jeg for j. jeg og j har møtt eller krysset. Så det kan ikke byttes. Listen forblir den samme som:

P O E I T Y U R W Q

På dette tidspunktet må pivoten, Q, plasseres i sin endelige posisjon i sorteringen. Dette gjøres ved å bytte arr [i] med arr [høy], bytte T og Q. Listen blir:

P O E I Q Y U R W T

På dette tidspunktet er partisjonering for hele listen avsluttet. Pivot = Q har spilt sin rolle. Det er nå tre underlister, som er:

P O E I Q Y U R W T

Partisjonen er divisjon og erobring (sortering) i paradigmet. Q er i riktig sorteringsposisjon. Hvert element til venstre for Q er mindre enn Q, og hvert element til høyre for Q er større enn Q. Den venstre listen er imidlertid fortsatt ikke sortert; og den riktige listen er fremdeles ikke sortert. Hele hurtigsorteringsfunksjonen må kalles rekursivt for å kunne sortere venstre undeliste og høyre underliste. Denne tilbakekallingen av Quick Sort må fortsette; nye underlister vil utvikle seg til hele den originale listen er fullstendig sortert. For hver tilbakekalling av hurtigsorteringsfunksjonen blir den venstre undelisten ivaretatt først før den tilhørende høyre underlisten blir ivaretatt. En ny pivot må skaffes for hver deleliste.

For underlisten:

P O E I

Pivoten (medianen) for P, O og I er bestemt. Pivoten vil være O. For denne underlisten, og for hele listen, er den nye arr [lav] arr [0], og den nye arr [høy] er den siste arr [i-1] = arr [ 4-1] = arr [3], der i er den endelige pivotindeksen fra forrige partisjon. Etter at pivot () -funksjonen er kalt, skal den nye pivot -verdien, pivot = O. Ikke forveksle mellom pivot -funksjonen og pivot -verdien. Pivot-funksjonen kan foreta en liten sortering og plassere pivoten ytterst til høyre på delelisten. Denne underlisten blir,

I P E O

Med denne ordningen slutter pivoten alltid i høyre ende av underlisten eller listen etter funksjonskallet. Skanning fra begge ender begynner fra arr [0] og arr [3] til i og j møtes eller krysser. Sammenligningen gjøres med pivot = O. De første stoppene er ved P og E. De byttes, og den nye undelisten blir:

I E P O

Skanningen fra begge ender fortsetter, og de nye stoppene er ved P for i og på E for j. Nå har jeg og j møttes eller krysset. Så underlisten forblir den samme som:

I E P O

Deling av en underliste eller liste avsluttes når pivoten er satt i sin endelige posisjon. Så de nye verdiene for arr [i] og arr [høy] byttes. Det vil si at P og O byttes. Den nye underlisten blir:

I E O P

O er nå på sin endelige posisjon for hele listen. Rollen som en sving er avsluttet. Underlisten er for tiden delt inn i ytterligere tre lister, som er:

I E O P

På dette tidspunktet må hurtig sortering av den første høyre underlisten kalles. Det vil imidlertid ikke bli kalt. I stedet vil det bli notert og reservert, for å bli kalt senere. Siden utsagnene fra partisjoneringsfunksjonen ble utført, fra toppen av funksjonen, er det Hurtigsortering for venstre underliste som må kalles nå (etter at pivot () har blitt kalt). Det vil bli kalt for listen:

DVS

Det vil begynne med å lete etter medianen til I og E. Her, arr [lav] = I, arr [mid] = I og arr [høy] = E. Så medianen, pivot, bør bestemmes av pivotalgoritmen som , I. Imidlertid vil pseudokoden ovenfor bestemme pivoten som E. Denne feilen oppstår her fordi pseudokoden ovenfor er ment for tre elementer og ikke to. I implementeringen nedenfor er det en viss justering av koden. Underlisten blir,

E jeg

Pivoten ender alltid i høyre ende av underlisten eller listen etter funksjonskall. Skanning fra begge ender begynner fra arr [0] og arr [1] eksklusivt til i og j møtes eller krysser. Sammenligningen gjøres med pivot = I. De første og eneste stoppene er ved I og E: ved I for i og på E for j. Nå har jeg og j møtt eller krysset. Så, underlisten forblir den samme som:

E jeg

Deling av en underliste eller liste avsluttes når pivoten er satt i sin endelige posisjon. Så de nye verdiene for arr [i] og arr [høy] byttes. Det skjer her at arr [i] = I og arr [høy] = I. Så den samme verdien byttes med seg selv. Den nye underlisten blir:

E jeg

Jeg er nå på den endelige posisjonen for hele listen. Rollen som en sving er avsluttet. Underlisten er nå delt inn i ytterligere to lister, som er,

E jeg

Nå har pivotene så langt vært Q, O og I. Pivoter slutter på de siste posisjonene. En undeliste over et enkelt element, for eksempel P ovenfor, ender også på sin endelige posisjon.

På dette tidspunktet har den første venstre underlisten blitt fullstendig sortert. Og sorteringsprosedyren er nå på:

E I O P Q Y U R W T

Den første høyre underlisten:

Y U R W T

må fortsatt sorteres.

Erobre den første høyre underlisten
Husk at hurtigsorteringsanropet for den første høyre underlisten ble notert og reservert i stedet for å bli utført. På dette tidspunktet vil det bli utført. Og så er den nye arr [lav] = arr [5] = arr [QPivotIndex+1], og den nye arr [høy] forblir arr [9]. Et lignende sett med aktiviteter som skjedde for den første venstre underlisten vil skje her. Og denne første høyre underlisten er sortert til:

R T U W Y

Og den opprinnelige usorterte listen har blitt sortert til:

E I O P Q R T U W Y

Java -koding

Å sette algoritmen i Java er bare å sette alle de ovennevnte pseudokodesegmentene inn i Java -metoder i en klasse. Ikke glem at det må være en hovedmetode () i klassen som kaller quicksort () -funksjonen med den usorterte matrisen.

Pivot () -metoden

Java pivot () -metoden som returnerer verdien, pivot, bør være:

tomromdreie(røyearr[], intlav, inthøy) {
intmidt= (lav+høy) / 2;
hvis (arr[midt] <arr[lav])
bytte(arr,lav,midt);
hvis (arr[høy] <arr[lav])
bytte(arr,lav,høy);
hvis ((høy-lav) > 2) {
hvis (arr[midt] <arr[høy])
bytte(arr,midt,høy);
}
}

Bytt () -metoden

Byttemetoden () bør være:

tomrombytte(røyearr[], intx, intog) {
røyetemp=arr[x];
arr[x] =arr[og];
arr[og] =temp;
}

Quicksort () -metoden

Quicksort () -metoden bør være:

tomromkvicksort(røyearr[], intlav, inthøy) {
hvis (lav<høy) {
dreie(arr,lav,høy);
ints=skillevegg(arr,lav,høy);
kvicksort(arr,lav,s- 1);
kvicksort(arr,s+ 1,høy);
}
}

Metoden for partisjon ()

Metoden for partisjon () bør være:

intskillevegg(røyearr[], intlav, inthøy) {
røyedreie=arr[høy];
intJeg=lav;
intj=høy;
gjøre {
gjøre
++Jeg;
samtidig som(arr[Jeg] <dreie);
gjøre
-j;
samtidig som(arr[j] >dreie);
hvis (Jeg<j)
bytte(arr,Jeg,j);
}samtidig som(Jeg<j);
bytte(arr,Jeg,høy);
komme tilbakeJeg;
}

Hovedmetoden ()

Hovedmetoden () kan være:

offentligstatisk tomromhoved-(String[]args) {
røyearr[] = {'Q', 'I', 'OG', 'R', 'T', 'OG', 'U', 'JEG', 'ELLER', 'P'};
TheClass QuickSort= nyKlassen();
QuickSort.kvicksort(arr, 0, 9);
System.ute.println('De sorterte elementene:');
til(intJeg=0;Jeg<10;Jeg++) {
System.ute.skrive ut(arr[Jeg]);System.ute.skrive ut('');
}
System.ute.println();
}

Alle metodene ovenfor kan settes inn i en klasse.

Konklusjon

Hurtigsortering er en sorteringsalgoritme som bruker del-og-erobre-paradigmet. Den begynner med å dele en usortert liste i to eller tre delelister. I denne opplæringen har Quick Sort delt en liste inn i tre underlister: en venstre underliste, en midtliste med et enkelt element og en høyre undeliste. Conquering in Quick Sort er å dele en liste eller underliste mens du sorterer den, ved hjelp av en pivotverdi. Denne opplæringen har forklart en implementering av Quick Sort på Java -dataspråket.

Om forfatteren

Chrysanthus Forcha

Oppdageren av matematikkintegrasjon fra First Principles og relaterte serier. Mastergrad i teknisk utdanning, spesialisert seg på elektronikk og dataprogramvare. BSc elektronikk. Jeg har også kunnskap og erfaring på masternivå i databehandling og telekommunikasjon. Av 20.000 forfattere var jeg den 37. beste forfatteren på devarticles.com. Jeg har jobbet på disse feltene i mer enn 10 år.

Se alle innlegg

RELATERT LINUX HINT INNLEGG