Objašnjeno brzo sortiranje u Javi

Quick Sort Java Explained



Brzo sortiranje, također napisano kao Quicksort, shema je za sortiranje popisa koja koristi paradigmu podijeli-pa-osvoji. Postoje različite sheme za brzo sortiranje, a sve koriste paradigmu podijeli pa osvoji. Prije nego objasni Brzo sortiranje, čitatelj mora znati konvenciju o prepolovljavanju popisa ili podpopisa i medijanu tri vrijednosti.

Prepolovljujuća konvencija

Kada je broj elemenata na popisu paran, prepolovljavanje popisa znači da je doslovna prva polovica popisa prva polovica, a doslovna druga polovica popisa druga polovica. Srednji (srednji) element cijelog popisa posljednji je element prvog popisa. To znači da je srednji indeks dužina / 2 - 1, jer brojanje indeksa počinje od nule. Duljina je broj elemenata na popisu. Na primjer, ako je broj elemenata 8, tada prva polovica popisa ima 4 elementa, a druga polovica popisa također ima 4 elementa. To je u redu. Budući da brojanje indeksa počinje od 0, srednji indeks je 3 = 8 /2 - 1.







Što je sa slučajem, kada je broj elemenata na popisu ili podpopisu neparan? Na početku je duljina još uvijek podijeljena s 2. Prema dogovoru, broj elemenata u prvoj polovici ove podjele je duljina / 2 + 1/2. Brojanje indeksa počinje od nule. Srednji indeks dan je duljinom / 2 - 1/2. To se konvencijom smatra srednjim rokom. Na primjer, ako je broj elemenata na popisu 5, tada je srednji indeks 2 = 5/2 - 1/2. Postoje tri elementa u prvoj polovici popisa i dva elementa u drugoj polovici. Srednji element cijele liste je treći element na indeksu 2, što je srednji indeks jer brojanje indeksa počinje od 0.



Podjela na ovaj način primjer je cjelobrojne aritmetike.



Medijan tri vrijednosti

Pitanje: Koja je medijana niza:





C B A

Riješenje:
Rasporedite popis uzlaznim redoslijedom:



A B C

Srednji pojam, B, je medijan. To je veličina koja se nalazi između druge dvije veličine.

Traženje medijane na popisu nije takva vrsta. Na primjer, na popisu od 19 nerazvrstanih elemenata može biti potrebna medijana za prvi, srednji i zadnji element. Ove tri vrijednosti ne moraju biti u rastućem redoslijedu; pa se njihovi indeksi moraju uzeti u obzir.

Uz Brzo sortiranje potrebna je medijana za cijeli popis i podpopise. Pseudokod za traženje medijane tri vrijednosti razmaknute na popisu (nizu) je:

sredinom: =(niska+visoko) / 2
akodol[sredinom] <dol[niska]
zamijeniti dol[niska]s arr[sredinom]
akodol[visoko] <dol[niska]
zamijeniti dol[niska]s arr[visoko]
akodol[sredinom] <dol[visoko]
zamijeniti dol[sredinom]s arr[visoko]
stožer: =dol[visoko]

Izraz arr znači niz. Ovaj segment koda traži medijanu i također vrši sortiranje. Ovaj segment koda izgleda jednostavno, ali može biti prilično zbunjujuće. Dakle, obratite pažnju na sljedeće objašnjenje:

Razvrstavanjem u ovom vodiču dobit ćete popis gdje je prva vrijednost najmanja vrijednost, a posljednja vrijednost najveća vrijednost. Uz abecedu, A je manje od Z.

Ovdje je zaokret rezultirajuća medijana. Niski je najniži indeks popisa ili podpopisa (ne nužno za najnižu vrijednost); visok je najviši indeks popisa ili podpopisa (ne nužno za najveću vrijednost), a srednji je konvencionalni srednji indeks (ne nužno za srednju vrijednost cijelog popisa).

Dakle, medijana koju treba dobiti je između vrijednosti najnižeg indeksa, vrijednosti srednjeg indeksa i vrijednosti najvišeg indeksa.

U kodu se prvo dobiva konvencionalni srednji indeks. Na ovom početku popis nije razvrstan. Usporedba i neko preuređivanje u rastućem redoslijedu triju vrijednosti odvijat će se u isto vrijeme. Prva naredba if uspoređuje vrijednost najnižeg indeksa i vrijednosti srednjeg indeksa. Ako je vrijednost srednjeg indeksa manja od vrijednosti najnižeg indeksa, tada dvije vrijednosti mijenjaju pozicije. Time počinje sortiranje i mijenja se raspored vrijednosti na popisu ili podpopisu. Druga naredba if uspoređuje vrijednost najvišeg indeksa i vrijednosti najnižeg indeksa. Ako je vrijednost najvišeg indeksa manja od vrijednosti najnižeg indeksa, dvije vrijednosti mijenjaju pozicije. To nastavlja s nekim sortiranjem i promjenom rasporeda vrijednosti na popisu ili podpopisu. Treća naredba if uspoređuje vrijednost srednjeg indeksa i vrijednosti najvišeg indeksa. Ako je indeks najvišeg indeksa manji od srednjeg, dvije vrijednosti mijenjaju pozicije. Ovdje se može dogoditi i neko sortiranje ili preuređivanje. Ovaj treći if-uvjet nije poput prethodna dva.

Na kraju ove tri zamjene, srednja vrijednost tri predmetne vrijednosti bila bi A [visoka], čiji bi se izvorni sadržaj mogao promijeniti u segmentu koda. Na primjer, razmotrite nerazvrstani niz:

C B A

Već znamo da je medijana B. Međutim, to treba dokazati. Ovdje je cilj postići medijanu ove tri vrijednosti pomoću gornjeg segmenta koda. Prva naredba if uspoređuje B i C. Ako je B manji od C, tada se pozicije B i C moraju zamijeniti. B je manji od C, pa novi raspored postaje:

B C A

Primijetite, vrijednosti za najniži indeks i srednji indeks su se promijenile. Druga naredba if uspoređuje A i B. Ako je A manji od B, tada se pozicije A i B moraju zamijeniti. A je manje od B, pa novi raspored postaje:

A C B

Primijetite, vrijednosti za najveći indeks i najniži indeks su se promijenile. Treći if-iskaz uspoređuje C i B. Ako je C manji od B, tada se pozicije C i B moraju zamijeniti. C nije manji od B, pa se zamjena ne događa. Novi aranžman ostaje kao i prethodni, to jest:

A C B

B je medijana, koja je, A [visoka], i to je stožer. Dakle, zaokret se rađa na krajnjem kraju popisa ili podpopisa.

Funkcija zamjene

Još jedna značajka potrebna za brzo sortiranje je funkcija zamjene. Funkcija zamjene razmjenjuje vrijednosti dviju varijabli. Pseudokod za funkciju zamjene je:

definirati zamjenu(x,i)
temp: =x
x: =i
i: =temp

Ovdje se x i y odnose na stvarne vrijednosti, a ne na kopije.

Razvrstavanjem u ovom članku dobit ćete popis gdje je prva vrijednost najmanja vrijednost, a posljednja vrijednost najveća vrijednost.

Sadržaj članka

Algoritam za brzo sortiranje

Uobičajen način razvrstavanja nerazvrstanog popisa je razmatranje prve dvije vrijednosti. Ako nisu u redu, dovedite ih u red. Zatim razmotrite prve tri vrijednosti. Skenirajte prva dva da vidite gdje se nalazi treća vrijednost i postavite je na odgovarajući način. Zatim razmotrite prve četiri vrijednosti. Skenirajte prve tri vrijednosti da vidite gdje se četvrta vrijednost uklapa i prikladno je uklopite. Nastavite s ovim postupkom dok se cijeli popis ne sortira.

Ovaj postupak, poznat i kao brute-force sortiranje, u računalnom programiranju je prespor. Algoritam brzog sortiranja dolazi s mnogo bržim postupkom.

Koraci za algoritam za brzo sortiranje su sljedeći:

  1. Provjerite postoje li najmanje 2 broja za sortiranje na nerazvrstanom popisu.
  2. Dobijte procijenjenu središnju vrijednost za popis, koja se naziva zaokretna. Medijana, kako je gore opisano, jedan je od načina dobivanja zaokreta. Različiti načini dolaze sa svojim prednostima i nedostacima. - Vidimo se kasnije.
  3. Podijelite popis na particije. To znači da postavite zaokret na popis. Na taj su način svi elementi s lijeve strane manji od zaokretne vrijednosti, a svi elementi s desne strane veći su ili jednaki zaokretnoj vrijednosti. Postoje različiti načini podjele. Svaka metoda podjele ima svoje prednosti i nedostatke. Podjela se dijeli u paradigmi zavadi pa vladaj.
  4. Ponavljajte korake 1, 2 i 3 rekurzivno za nove parove podpopisa koji se pojavljuju sve dok se cijeli popis ne sortira. Ovo osvaja u paradigmi zavadi pa vladaj.

Pseudokod za brzo sortiranje je:

brzi sortiranje algoritma(dol,niska,visoko)je
akoniska<visoko onda
stožer(niska,visoko)
str: =pregrada(dol,niska,visoko)
brzo sortiranje(dol,niska,str- 1)
brzo sortiranje(dol,str+ 1,visoko)

Pseudokod particije

Pseudokod particije koji se koristi u ovom vodiču je:

particija algoritma(dol,niska,visoko)je
stožer: =dol[visoko]
i: =niska
j: =visoko
čini
čini
++i
dok(dol[i] <stožer)
čini
-j
dok(dol[j] >stožer)
ako (i<j)
zamijeniti dol[i]s arr[j]
dok(i<j)
zamijeniti dol[i]s arr[visoko]
povrataki

Na donjoj ilustraciji brzog sortiranja koristi se ovaj kôd:

Ilustracija brzog sortiranja

Razmotrite sljedeći nerazvrstani popis (niz) abecednih slova:

Q W E R T Y U I O P

Pregledom je sortirani popis:

E I O P Q R T U W Y

Sortirani popis sada će se dokazati, koristeći gornji algoritam i segmente pseudokoda, s nerazvrstanog popisa:

Q W E R T Y U I O P

Prvi zaokret određen je iz arr [0] = Q, arr [4] = T i arr [9] = P, te je identificiran kao Q i postavljen krajnje desno na popisu. Dakle, popis s bilo kojim sortiranjem zaokretnih funkcija postaje:

P W E R T Y U I O Q

Trenutni zaokret je Q. Postupak zaokreta napravio je malo sortiranje i stavio P na prvo mjesto. Rezultirajući popis mora se preurediti (podijeliti), tako da su svi elementi s lijeve strane manje vrijednosti, tada su zaokret i svi elementi desno od zaokreta jednaki ili veći od zaokreta. Računalo ne može izvršiti particioniranje pregledom. Dakle, radi pomoću indeksa i gornjeg algoritma particije.

Niski i visoki indeksi sada su 0 i 9. Dakle, računalo će početi skenirati od indeksa 0 dok ne dosegne indeks čija je vrijednost jednaka ili veća od zaokreta i privremeno se tu zaustavlja. Također će skenirati s visokog (desnog) kraja, indeksa 9, koji se spušta, sve dok ne dosegne indeks čija je vrijednost manja ili jednaka zaokretu i tu se privremeno zaustavi. To znači dva zaustavna položaja. Ako i, inkrementalna varijabla indeksa, od niske još nije jednaka ili veća od opadajuće varijable indeksa, j od visoke, tada se ove dvije vrijednosti zamjenjuju. U trenutnoj situaciji, skeniranje s oba kraja zaustavilo se na W i O. Dakle, popis postaje:

P O E R T Y U I W Q

Zaokret je i dalje Q. Skeniranje u suprotnim smjerovima nastavlja se i zaustavlja u skladu s tim. Ako i još nije jednak ili veći od j, tada se zamjenjuju dvije vrijednosti pri kojima je skeniranje s oba kraja zaustavljeno. Ovaj put, skeniranje s oba kraja zaustavilo se na R i I. Dakle, raspored popisa postaje:

P O E I T Y U R W Q

Zaokret je i dalje Q. Skeniranje u suprotnim smjerovima nastavlja se i zaustavlja u skladu s tim. Ako i još nije jednak ili veći od j, tada se zamjenjuju dvije vrijednosti na kojima je skeniranje prestalo. Ovaj put, skeniranje s oba kraja zaustavilo se na T za i, a ja za j. ja i j smo se sreli ili prešli. Dakle, ne može doći do zamjene. Popis ostaje isti kao:

P O E I T Y U R W Q

U ovom trenutku stožer Q mora biti postavljen na krajnji položaj pri sortiranju. To se postiže zamjenom arr [i] s arr [visoko], zamjenom T i Q. Popis postaje:

P O E I Q Y U R W T

U ovom trenutku, podjela za cijeli popis je završena. Zaokret = Q odigrao je svoju ulogu. Sada postoje tri podpopisa, a to su:

P O E I Q Y U R W T

Particija je podjela i osvajanje (sortiranje) u paradigmi. Q je na svom ispravnom položaju za sortiranje. Svaki element lijevo od Q manji je od Q, a svaki element desno od Q veći je od Q. Međutim, lijevi popis još uvijek nije sortiran; a desni popis još uvijek nije razvrstan. Cijela funkcija brzog sortiranja mora se pozvati rekurzivno kako bi se poredali lijevi i desni podpopis. Ovo opoziv Brzog sortiranja mora se nastaviti; novi podpopisi će se razvijati sve dok se cijeli izvorni popis potpuno ne sortira. Za svako pozivanje funkcije brzog razvrstavanja najprije se prati lijevi podpopis prije nego se pristupi odgovarajućem desnom podpopisu. Za svaki podpopis mora se dobiti novi zaokret.

Za podpopis:

P O E I

Određen je zaokret (medijan) za P, O i I. Zaokret bi bio O. Za ovaj podpopis, a koji se odnosi na potpuni popis, novi arr [nisko] je arr [0], a novi arr [visoko] posljednji je arr [i-1] = arr [ 4-1] = arr [3], gdje je i konačni pivot indeks iz prethodne particije. Nakon što je pozvana funkcija pivot (), nova zaokretna vrijednost, pivot = O. Nemojte miješati funkciju zaokretanja i zaokretnu vrijednost. Zaokretna funkcija može izvršiti malo sortiranje i postaviti zaokret na krajnju desnu stranu podpopisa. Ovaj podpopis postaje,

I P E O

S ovom shemom, zaokret uvijek završava na desnom kraju podpopisa ili popisa nakon poziva funkcije. Skeniranje s oba kraja počinje od arr [0] i arr [3] sve dok se i i j ne susretnu ili križaju. Usporedba se vrši s pivot = O. Prva stajališta su na P i E. Zamjenjuju se, a novi podpopis postaje:

I E P O

Skeniranje s oba kraja se nastavlja, a nova stajališta su na P za i i na E za j. Sada smo se ja i j sreli ili ukrstili. Dakle, podpopis ostaje isti kao:

I E P O

Particioniranje podpopisa ili popisa završava kada je zaokret stavljen na krajnji položaj. Dakle, zamjenjuju se nove vrijednosti za arr [i] i arr [high]. To jest, P i O se zamjenjuju. Novi podpopis postaje:

I E O P

O je sada na svom konačnom mjestu za cijeli popis. Njegova je uloga stožerne prestala. Podpopis je trenutno podijeljen na još tri popisa, a to su:

I E O P

U ovom trenutku potrebno je pozvati Brzo sortiranje prvog desnog podpopisa. Međutim, neće se zvati. Umjesto toga, bit će zabilježeno i rezervirano, što će se kasnije nazvati. Kako su se izvršavali izrazi funkcije particioniranja, s vrha funkcije, sada se mora pozvati Brzo sortiranje za lijevi podpopis (nakon što je pozvan pivot ()). Pozvat će se na popis:

I E

Započet će traženjem medijane I i E. Ovdje je arr [nisko] = I, arr [usred] = I i arr [visoko] = E. Dakle, medijan, zaokret, treba odrediti zaokretnim algoritmom kao , I. Međutim, gornji zaokretni pseudokod će odrediti zaokret kao E. Ova se pogreška javlja ovdje jer je gornji pseudokod namijenjen za tri elementa, a ne za dva. U donjoj implementaciji postoji određena prilagodba koda. Podpopis postaje,

E ja

Zaokret uvijek završava na desnom kraju podpopisa ili popisa nakon poziva funkcije. Skeniranje s oba kraja počinje isključivo od arr [0] i arr [1] sve dok se i i j ne susretnu ili križaju. Usporedba se vrši s pivot = I. Prva i jedina zaustavljanja su na I i E: na I za i i na E za j. Sada smo se ja i j sreli ili prešli. Dakle, podpopis ostaje isti kao:

E ja

Particioniranje podpopisa ili popisa završava kada je zaokret stavljen na krajnji položaj. Dakle, zamjenjuju se nove vrijednosti za arr [i] i arr [high]. Ovdje se događa da je arr [i] = I i arr [visoko] = I. Dakle, ista vrijednost zamjenjuje se sama sa sobom. Novi podpopis postaje:

E ja

Sada sam na konačnom mjestu za cijeli popis. Njegova je uloga stožerne prestala. Podpopis je sada podijeljen na još dva popisa, a to su:

E ja

Sada su zaokreti do sada bili Q, O i I. Pivoti završavaju na svojim konačnim pozicijama. Podpopis pojedinačnih elemenata, poput gore navedenog P, također završava na svom konačnom mjestu.

U ovom je trenutku prvi lijevi podpopis potpuno sređen. Postupak razvrstavanja sada je na:

E I O P Q Y U R W T

Prvi desni podpopis:

Y U R W T

još treba srediti.

Osvajanje prvog desnog podpopisa
Upamtite da je poziv za brzo sortiranje za prvi desni podpopis zabilježen i rezerviran umjesto izvršenja. U ovom će se trenutku izvršiti. I tako, novi arr [nisko] = arr [5] = arr [QPivotIndex+1], a novi arr [visoko] ostaje arr [9]. Sličan skup aktivnosti koji se dogodio za prvi lijevi podpopis dogodit će se ovdje. I ovaj prvi desni podpopis sortiran je prema:

R T U W Y

Izvorni nesortirani popis razvrstan je na:

E I O P Q R T U W Y

Java kodiranje

Stavljanje algoritma u Javu samo je stavljanje svih gore navedenih segmenata pseudokoda u Java metode u jednu klasu. Ne zaboravite da u klasi mora postojati metoda main () koja će pozvati funkciju quicksort () s nerazvrstanim nizom.

Metoda pivot ()

Java pivot () metoda koja vraća vrijednost, pivot, trebala bi biti:

poništitistožer(chardol[], intniska, intvisoko) {
intsredinom= (niska+visoko) / 2;
ako (dol[sredinom] <dol[niska])
zamijeniti(dol,niska,sredinom);
ako (dol[visoko] <dol[niska])
zamijeniti(dol,niska,visoko);
ako ((visoko-niska) > 2) {
ako (dol[sredinom] <dol[visoko])
zamijeniti(dol,sredinom,visoko);
}
}

Metoda swap ()

Metoda swap () trebala bi biti:

poništitizamijeniti(chardol[], intx, inti) {
chartemp=dol[x];
dol[x] =dol[i];
dol[i] =temp;
}

Metoda quicksort ()

Metoda quicksort () trebala bi biti:

poništitibrzo sortiranje(chardol[], intniska, intvisoko) {
ako (niska<visoko) {
stožer(dol,niska,visoko);
intstr=pregrada(dol,niska,visoko);
brzo sortiranje(dol,niska,str- 1);
brzo sortiranje(dol,str+ 1,visoko);
}
}

Metoda particije ()

Metoda partition () trebala bi biti:

intpregrada(chardol[], intniska, intvisoko) {
charstožer=dol[visoko];
inti=niska;
intj=visoko;
čini {
čini
++i;
dok(dol[i] <stožer);
čini
-j;
dok(dol[j] >stožer);
ako (i<j)
zamijeniti(dol,i,j);
}dok(i<j);
zamijeniti(dol,i,visoko);
povrataki;
}

Glavna () metoda

Metoda main () može biti:

javnoststatički poništitiglavni(Niz[]args) {
chardol[] = {'Q', 'U', 'I', 'R', 'T', 'I', 'U', 'Ja', 'ILI', 'P'};
QuickSort klase= noviRazred();
QuickSort.brzo sortiranje(dol, 0, 9);
Sustav.van.println('Razvrstani elementi:');
za(inti=0;i<10;i++) {
Sustav.van.ispisati(dol[i]);Sustav.van.ispisati('');
}
Sustav.van.println();
}

Sve gore navedene metode mogu se svrstati u jednu klasu.

Zaključak

Brzo sortiranje je algoritam za sortiranje koji koristi paradigmu podijeli pa osvoji. Započinje dijeljenjem nerazvrstanog popisa na dva ili tri podpopisa. U ovom vodiču Quick Sort je popis podijelio na tri podpopisa: lijevi podpopis, srednji popis jednog elementa i desni podpopis. Osvajanje u Quick Sort-u je dijeljenje popisa ili pod-popisa dok ih sortirate, koristeći zaokretnu vrijednost. Ovaj vodič je objasnio jednu implementaciju brzog sortiranja u Java računalnom jeziku.

O autoru

Krizantus forcha

Otkrivač matematičke integracije iz Prvih načela i srodnih serija. Magistrirao tehničko obrazovanje, specijaliziran za elektroniku i računalni softver. Diplomirana elektronika. Također imam znanje i iskustvo na magisteriju iz računarstva i telekomunikacija. Od 20.000 pisaca, bio sam 37. najbolji pisac na devarticles.com. Na ovim poljima radim više od 10 godina.

Pogledajte sve postove

POVEZANI LINUX SAVJETI