Pojasnjeno hitro razvrščanje v Javi

Quick Sort Java Explained



Hitro razvrščanje, napisano tudi kot Quicksort, je shema razvrščanja seznamov, ki uporablja paradigmo razdeli in osvoji. Za hitro razvrščanje obstajajo različne sheme, pri čemer vse uporabljajo paradigmo razdeli in osvoji. Preden razloži Hitro razvrščanje, mora bralec poznati konvencijo za prepolovitev seznama ali pod-seznama in mediano treh vrednosti.

Konvencija o prepolovitvi

Ko je število elementov na seznamu enakomerno, prepolovitev seznama pomeni, da je dobesedna prva polovica seznama prva polovica, dobesedna druga polovica seznama pa druga polovica. Srednji (srednji) element celotnega seznama je zadnji element prvega seznama. To pomeni, da je srednji indeks dolžina / 2 - 1, saj se štetje indeksov začne od nič. Dolžina je število elementov na seznamu. Na primer, če je število elementov 8, potem ima prva polovica seznama 4 elemente, druga polovica seznama pa tudi 4 elemente. To je v redu. Ker se štetje indeksov začne od 0, je srednji indeks 3 = 8 /2 - 1.







Kaj pa primer, ko je število elementov na seznamu ali pod-seznamu liho? Na začetku se dolžina še vedno deli z 2. Po dogovoru je število elementov v prvi polovici te delitve dolžina / 2 + 1/2. Štetje indeksov se začne od nič. Srednji indeks je podan po dolžini / 2 - 1/2. To se po dogovoru šteje za srednjeročno. Na primer, če je število elementov na seznamu 5, potem je srednji indeks 2 = 5/2 - 1/2. V prvi polovici seznama so trije elementi, v drugi polovici pa dva elementa. Srednji element celotnega seznama je tretji element pri indeksu 2, ki je srednji indeks, ker se štetje indeksov začne od 0.



Delitev na ta način je primer celoštevilčne aritmetike.



Mediana treh vrednosti

Vprašanje: Kakšna je mediana zaporedja:





C B A

Rešitev:
Seznam razporedite po naraščajočem vrstnem redu:



A B C

Srednji izraz, B, je mediana. To je velikost, ki leži med drugimi dvema velikostma.

Iskanje mediane na seznamu ni tako. Na primer na seznamu 19 nerazvrščenih elementov bo morda potrebna mediana za prvi element, srednji element in zadnji element. Te tri vrednosti morda niso v naraščajočem vrstnem redu; zato je treba upoštevati njihove indekse.

S hitrim razvrščanjem je potrebna mediana za celoten seznam in pod-sezname. Psevdokoda za iskanje mediane treh vrednosti, razporejenih na seznamu (matriki), je:

sredi: =(nizka+visoko) / 2
čepribl[sredi] <pribl[nizka]
zamenjaj pr[nizka]z nasl[sredi]
čepribl[visoko] <pribl[nizka]
zamenjaj pr[nizka]z nasl[visoko]
čepribl[sredi] <pribl[visoko]
zamenjaj pr[sredi]z nasl[visoko]
pivot: =pribl[visoko]

Izraz arr pomeni matriko. Ta kodni segment išče mediano in opravi tudi nekaj razvrščanja. Ta segment kode je videti preprost, vendar je lahko precej zmeden. Zato bodite pozorni na naslednjo razlago:

Razvrščanje v tej vadnici bo ustvarilo seznam, kjer je prva vrednost najmanjša vrednost, zadnja pa največja vrednost. Pri abecedi je A manjši od Z.

Tu je vrtišče nastala mediana. Low je najnižji indeks seznama ali pod-seznama (ni nujno, da je najnižja vrednost); high je najvišji indeks seznama ali pod-seznama (ne nujno za najvišjo vrednost), srednji pa konvencionalni srednji indeks (ne nujno za srednjo vrednost celotnega seznama).

Mediana, ki jo je treba dobiti, je med vrednostjo najnižjega indeksa, vrednostjo srednjega indeksa in vrednostjo najvišjega indeksa.

V kodi je najprej pridobljen običajni srednji indeks. Na tem začetku je seznam nerazvrščen. Primerjava in nekaj preurejanja v naraščajočem vrstnem redu treh vrednosti bosta potekala hkrati. Prvi stavek if primerja vrednost najnižjega in srednjega indeksa. Če je vrednost srednjega indeksa manjša od vrednosti najnižjega indeksa, se dve vrednosti zamenjata za položaje. S tem se začne razvrščanje in spremeni razporeditev vrednosti na seznamu ali pod-seznamu. Drugi stavek if primerja vrednost najvišjega in najnižjega indeksa. Če je vrednost najvišjega indeksa manjša od vrednosti najnižjega indeksa, se vrednosti zamenjata za dve poziciji. To nadaljuje z nekaterim razvrščanjem in spreminjanjem razporeditve vrednosti na seznamu ali pod-seznamu. Tretji stavek if primerja vrednost srednjega in najvišjega indeksa. Če je najvišji indeks manjši od srednjega, se vrednosti zamenjata za dve poziciji. Tu se lahko pojavi tudi nekaj razvrščanja ali preureditve. Ta tretji pogoj if ni podoben prejšnjim dvema.

Na koncu teh treh zamenjav bi bila srednja vrednost zadevnih treh vrednosti A [visoka], katere prvotna vsebina bi se lahko spremenila v segmentu kod. Razmislite na primer o nerazvrščanem zaporedju:

C B A

Že vemo, da je mediana B. Vendar je to treba dokazati. Cilj je tukaj pridobiti mediano teh treh vrednosti z uporabo zgornjega kodnega segmenta. Prvi stavek if primerja B in C. Če je B manjši od C, je treba zamenjati položaji B in C. B je manjši od C, zato nova ureditev postane:

B C A

Upoštevajte, da sta se vrednosti za najnižji in srednji indeks spremenili. Drugi stavek if primerja A in B. Če je A manjši od B, je treba zamenjati položaji A in B. A je manjši od B, zato nova ureditev postane:

A C B

Upoštevajte, da sta se vrednosti najvišjega in najnižjega indeksa spremenili. Tretji stavek if primerja C in B. Če je C manjši od B, je treba zamenjati položaji C in B. C ni manjši od B, zato zamenjave ni. Nova ureditev ostaja kot prejšnja, to je:

A C B

B je mediana, ki je, A [visoka], in to je vrtišče. Tako se pivot rodi na skrajnem koncu seznama ali pod-seznama.

Funkcija zamenjave

Druga funkcija, ki jo potrebuje Quick Sort, je funkcija zamenjave. Funkcija zamenjave izmenja vrednosti dveh spremenljivk. Psevdokoda za funkcijo zamenjave je:

opredeliti zamenjavo(x,in)
temp: =x
x: =in
in: =temp

Tu se x in y nanašata na dejanske vrednosti in ne na kopije.

Razvrščanje v tem članku bo ustvarilo seznam, kjer je prva vrednost najmanjša vrednost, zadnja pa največja vrednost.

Vsebina članka

Algoritem hitrega razvrščanja

Običajen način razvrščanja nerazvrščenega seznama je upoštevanje prvih dveh vrednosti. Če niso v redu, jih uredite. Nato razmislite o prvih treh vrednostih. Skenirajte prva dva, da vidite, kje ustreza tretja vrednost, in jo ustrezno prilegajte. Nato upoštevajte prve štiri vrednosti. Skenirajte prve tri vrednosti, da vidite, kje se četrta vrednost prilega, in jo ustrezno prilagodite. Nadaljujte s tem postopkom, dokler ne razvrstite celotnega seznama.

Ta postopek, znan tudi kot groba sila, v računalniškem programiranju je prepočasen. Algoritem hitrega razvrščanja ima veliko hitrejši postopek.

Koraki za algoritem hitrega razvrščanja so naslednji:

  1. Prepričajte se, da sta na nerazvrščanem seznamu vsaj 2 številki za razvrščanje.
  2. Pridobite ocenjeno osrednjo vrednost seznama, imenovano pivot. Mediana, kot je opisano zgoraj, je eden od načinov za pridobitev vrtilne točke. Različni načini imajo svoje prednosti in slabosti. - Poglej kasneje.
  3. Seznam razdelite na particije. To pomeni, da pivot postavite na seznam. Na ta način so vsi elementi na levi manjši od vrtilne vrednosti, vsi elementi na desni pa so večji ali enaki vrednosti vrtilne vrednosti. Obstajajo različni načini razdelitve. Vsaka metoda razdelitve ima svoje prednosti in slabosti. Razdelitev je razdeljena v paradigmi razdeli in osvoji.
  4. Korake 1, 2 in 3 ponavljajte rekurzivno za nove pare pod-seznamov, ki se pojavijo, dokler ne razvrstite celotnega seznama. To je zmagovalno v paradigmi loči in osvoji.

Psevdokoda Quick Sort je:

algoritem za hitro razvrščanje(pribl,nizka,visoko)je
čenizka<visoko torej
pivot(nizka,visoko)
str: =predelna stena(pribl,nizka,visoko)
hitro razvrščanje(pribl,nizka,str- 1)
hitro razvrščanje(pribl,str+ 1,visoko)

Psevdokoda particije

V tej vadnici je uporabljena psevdokoda particije:

algoritemska particija(pribl,nizka,visoko)je
pivot: =pribl[visoko]
jaz: =nizka
j: =visoko
naredi
naredi
++jaz
medtem(pribl[jaz] <pivot)
naredi
-j
medtem(pribl[j] >pivot)
če (jaz<j)
zamenjaj pr[jaz]z nasl[j]
medtem(jaz<j)
zamenjaj pr[jaz]z nasl[visoko]
vrnitevjaz

Na spodnji sliki hitrega razvrščanja se uporablja ta koda:

Ilustracija hitrega razvrščanja

Razmislite o naslednjem nerazvrščenem seznamu (nizu) abecednih črk:

Q W E R T Y U I O P

Po pregledu je razvrščen seznam:

E I O P Q R T U W Y

Razvrščeni seznam bo zdaj dokazan z uporabo zgornjega algoritma in segmentov psevdokode iz nerazvrščenega seznama:

Q W E R T Y U I O P

Prva vrtilna točka je določena iz arr [0] = Q, arr [4] = T in arr [9] = P ter je označena kot Q in postavljena skrajno desno na seznamu. Seznam s katerim koli razvrščanjem vrtilnih funkcij postane:

P V E R T Y U I O Q

Trenutni pivot je Q. Postopek vrtenja je naredil majhno razvrščanje in postavil P na prvo mesto. Nastali seznam je treba preurediti (razdeliti), tako da so vsi elementi na levi vrednosti manjši, nato pa so vrtišče in vsi elementi na desni strani vrtišča enaki ali večji od vrtilne točke. Računalnik s pregledom ne more narediti particije. Torej to počne z uporabo indeksov in zgornjega algoritma particij.

Nizki in visoki indeksi sta zdaj 0 in 9. Tako bo računalnik začel skenirati od indeksa 0, dokler ne doseže indeksa, katerega vrednost je enaka ali večja od vrtilne točke in se tam začasno ustavi. Skeniral bo tudi z višjega (desnega) konca, indeksa 9, ki se spušča, dokler ne doseže indeksa, katerega vrednost je manjša ali enaka vrtilni točki, in se tam začasno ustavi. To pomeni dva položaja zaustavitve. Če i, inkrementalna spremenljivka indeksa, od nizke še ni enaka ali večja od padajoče spremenljivke indeksa, j od visoke, se ti dve vrednosti zamenjata. V trenutni situaciji se je skeniranje z obeh koncev ustavilo pri W in O. Tako postane seznam:

P O E R T Y U I W Q

Vrtišče je še vedno Q. Skeniranje v nasprotnih smereh se nadaljuje in ustrezno ustavi. Če i še ni enak ali večji od j, se zamenjata dve vrednosti, pri katerih se skeniranje z obeh koncev ustavi. Tokrat se je skeniranje z obeh koncev ustavilo pri R in I. Torej, ureditev seznama postane:

P O E I T Y U R W Q

Vrtišče je še vedno Q. Skeniranje v nasprotnih smereh se nadaljuje in ustrezno ustavi. Če i še ni enak ali večji od j, se dve vrednosti, pri katerih se je skeniranje ustavilo, zamenjata. Tokrat se je skeniranje z obeh koncev ustavilo pri T za i in jaz za j. i in j sta se srečala ali prečkala. Torej zamenjave ne more biti. Seznam ostaja enak:

P O E I T Y U R W Q

Na tej točki mora biti vrtišče Q pri razvrščanju postavljeno v svoj končni položaj. To naredimo tako, da arr [i] zamenjamo z arr [visoko], zamenjamo T in Q. Seznam postane:

P O E I Q Y U R W T

Na tej točki je razdelitev celotnega seznama končana. Pivot = Q je odigral svojo vlogo. Zdaj obstajajo trije pod-seznami, in sicer:

P O E I Q Y U R W T

Delitev je delitev in osvajanje (razvrščanje) v paradigmi. Q je v pravilnem položaju za razvrščanje. Vsak element levo od Q je manjši od Q in vsak element desno od Q je večji od Q. Vendar levi seznam še vedno ni razvrščen; in pravi seznam še vedno ni razvrščen. Celotno funkcijo hitrega razvrščanja je treba poklicati rekurzivno, da lahko razvrstite levi in ​​desni pod-seznam. Ta odpoklic hitrega razvrščanja se mora nadaljevati; novi pod-seznami se bodo razvijali, dokler celotni izvirni seznam ni popolnoma razvrščen. Pri vsakem priklicu funkcije hitrega razvrščanja se najprej pregleda levi pod-seznam, preden se opravi ustrezen desni pod-seznam. Za vsak pod-seznam je treba pridobiti nov pivot.

Za pod-seznam:

P O E I

Določena je vrtišče (mediana) za P, O in I. Vrtilna točka bi bila O. Za ta pod-seznam in glede na celoten seznam je nov arr [nizko] arr [0], novi arr [visoko] pa je zadnji arr [i-1] = arr [ 4-1] = arr [3], kjer je i končni vrtilni indeks iz prejšnje particije. Po klicu funkcije pivot () se nova vrtilna vrednost, pivot = O. Ne zamenjujte med vrtilno funkcijo in vrtilno vrednostjo. Funkcija vrtenja lahko izvede majhno razvrščanje in postavi vrtilno enoto na skrajni desni del pod-seznama. Ta pod-seznam postane,

I P E O

Pri tej shemi se vrtilna enota po klicu funkcije vedno konča na desnem koncu pod-seznama ali seznama. Skeniranje z obeh koncev se začne od arr [0] in arr [3], dokler se i in j ne srečata ali prečkata. Primerjava je izvedena s pivot = O. Prvi postanki sta na točkah P in E. Zamenjata se in novi pod-seznam postane:

I E P O

Skeniranje z obeh koncev se nadaljuje, novi postanki pa sta pri P za i in pri E za j. Zdaj sva se srečala ali prečkala. Torej pod-seznam ostaja enak kot:

I E P O

Delitev pod-seznama ali seznama se konča, ko je vrtišče postavljeno v končni položaj. Tako se zamenjata novi vrednosti za arr [i] in arr [high]. To pomeni, da se P in O zamenjata. Novi pod-seznam postane:

I E O P

O je zdaj na svojem končnem mestu za celoten seznam. Njegova vloga pivot se je končala. Pod-seznam je trenutno razdeljen na še tri sezname, in sicer:

I E O P

Na tej točki je treba poklicati Quick Sort prvega desnega pod-seznama. Vendar se ne bo klical. Namesto tega bo zapisan in rezerviran, klican kasneje. Ker so se stavki funkcije particioniranja izvajali, je treba z vrha funkcije hitro poklicati Hitro razvrščanje za levi pod-seznam (po klicu pivot ()). Seznam bo poklican:

Jaz E

Začelo se bo z iskanjem mediane I in E. Tu je arr [nizko] = I, arr [sredi] = I in arr [visoko] = E. Zato je treba sredino, pivot, določiti z vrtilnim algoritmom kot , I. Vendar bo zgornja vrtilna psevdokoda določila vrtilno točko kot E. Ta napaka se pojavi tukaj, ker je zgornja psevdokoda namenjena trem elementom in ne dvema. V spodnji izvedbi je koda nekoliko prilagojena. Podnapis postane,

E jaz

Vrtilna enota se po klicu funkcije vedno konča na desnem koncu pod-seznama ali seznama. Skeniranje z obeh koncev se začne od arr [0] in arr [1] izključno, dokler se i in j ne srečata ali prečkata. Primerjava je izvedena s pivot = I. Prvi in ​​edini postanek sta na I in E: pri I za i in pri E za j. Zdaj sva se srečala ali prečkala. Torej, pod-seznam ostaja enak:

E jaz

Delitev pod-seznama ali seznama se konča, ko je vrtišče postavljeno v končni položaj. Tako se zamenjata novi vrednosti za arr [i] in arr [high]. Tu se zgodi, da je arr [i] = I in arr [visoko] = I. Torej se enaka vrednost zamenja sama s seboj. Novi pod-seznam postane:

E jaz

Zdaj sem na zadnjem mestu za celoten seznam. Njegova vloga pivot se je končala. Pod-seznam je zdaj razdeljen na še dva seznama, ki sta:

E jaz

Sedaj so bili pivoti Q, O in I. Pivoti se končajo na svojih končnih položajih. Podseznam posameznega elementa, na primer zgornji P, se prav tako konča na svojem končnem mestu.

Na tej točki je prvi levi podnapis popolnoma razvrščen. Postopek razvrščanja je zdaj na naslovu:

E I O P Q Y U R W T

Prvi desni podnapis:

Y U R W T

je treba še urediti.

Osvajanje prvega desnega pod-seznama
Ne pozabite, da je bil klic hitrega razvrščanja za prvi desni pod-seznam zabeležen in rezerviran, namesto da bi bil izveden. Na tej točki bo izvedena. Tako je novi arr [nizko] = arr [5] = arr [QPivotIndex+1], novi arr [visoko] pa ostane arr [9]. Podoben nabor dejavnosti, ki se je zgodil za prvi levi pod-seznam, se bo zgodil tukaj. Ta prvi desni podnapis je razvrščen na:

R T U W Y

Prvotni nerazvrščeni seznam je bil razvrščen na:

E I O P Q R T U W Y

Kodiranje Java

Dajanje algoritma v Javo pomeni le, da se vsi zgoraj navedeni segmenti psevdokode dajo v metode Java v en razred. Ne pozabite, da mora v razredu obstajati metoda main (), ki bo klicala funkcijo quicksort () z nerazvrščeno matriko.

Metoda pivot ()

Metoda Java pivot (), ki vrne vrednost pivot, mora biti:

ničnopivot(charpribl[], intnizka, intvisoko) {
intsredi= (nizka+visoko) / 2;
če (pribl[sredi] <pribl[nizka])
zamenjati(pribl,nizka,sredi);
če (pribl[visoko] <pribl[nizka])
zamenjati(pribl,nizka,visoko);
če ((visoko-nizka) > 2) {
če (pribl[sredi] <pribl[visoko])
zamenjati(pribl,sredi,visoko);
}
}

Metoda swap ()

Metoda swap () bi morala biti:

ničnozamenjati(charpribl[], intx, intin) {
chartemp=pribl[x];
pribl[x] =pribl[in];
pribl[in] =temp;
}

Metoda quicksort ()

Metoda quicksort () bi morala biti:

ničnohitro razvrščanje(charpribl[], intnizka, intvisoko) {
če (nizka<visoko) {
pivot(pribl,nizka,visoko);
intstr=predelna stena(pribl,nizka,visoko);
hitro razvrščanje(pribl,nizka,str- 1);
hitro razvrščanje(pribl,str+ 1,visoko);
}
}

Metoda particije ()

Metoda partition () bi morala biti:

intpredelna stena(charpribl[], intnizka, intvisoko) {
charpivot=pribl[visoko];
intjaz=nizka;
intj=visoko;
naredi {
naredi
++jaz;
medtem(pribl[jaz] <pivot);
naredi
-j;
medtem(pribl[j] >pivot);
če (jaz<j)
zamenjati(pribl,jaz,j);
}medtem(jaz<j);
zamenjati(pribl,jaz,visoko);
vrnitevjaz;
}

Glavna () metoda

Metoda main () je lahko:

javnostatična ničnoglavni(Vrvica[]args) {
charpribl[] = {'Q', 'IN', 'IN', 'R', 'T', 'IN', 'U', 'JAZ', 'ALI', 'P'};
Hitra razvrstitev v klasi= novRazred();
QuickSort.hitro razvrščanje(pribl, 0, 9);
Sistem.ven.println('Razvrščeni elementi:');
za(intjaz=0;jaz<10;jaz++) {
Sistem.ven.tiskanje(pribl[jaz]);Sistem.ven.tiskanje('');
}
Sistem.ven.println();
}

Vse zgoraj navedene metode lahko združimo v en razred.

Zaključek

Quick Sort je algoritem za razvrščanje, ki uporablja paradigmo loči in osvoji. Začne se z delitvijo nerazvrščenega seznama na dva ali tri pod-sezname. V tej vadnici je Quick Sort razdelil seznam na tri pod-sezname: levi pod-seznam, srednji seznam enega elementa in desni pod-seznam. Osvajanje v hitrem razvrščanju je deljenje seznama ali pod-seznama med razvrščanjem z uporabo vrtilne vrednosti. Ta vadnica je razložila eno izvedbo hitrega razvrščanja v računalniškem jeziku Java.

O avtorju

Krizantus Forcha

Odkritelj matematične integracije iz Prvih načel in sorodnih serij. Magisterij iz tehničnega izobraževanja, specializiran za elektroniko in računalniško programsko opremo. Diplomirana elektronika. Imam tudi znanje in izkušnje na magistrskem področju računalništva in telekomunikacij. Od 20.000 piscev sem bil 37. najboljši pisatelj na devarticles.com. Na teh področjih delam že več kot 10 let.

Ogled vseh objav

POVEZANE LINUX NAMIGNE OBJAVE