You are on page 1of 4

//quicksort je glavna funkcija, ciji ce konacni rezultat biti kompletno ureden n

iz.
//Ulazni parametri su sam niz (input), indeks polaznog (donjeg) elementa
podniza kojeg treba sortirati (low) i indeks poslednjeg (gornjeg) elementa
//podniza kojeg treba sortirati (high).
public void quicksort(int[] input, int low, int high)
{
// Inicijalizacija prvog (donjeg) i poslednjeg (gornjeg) indeksa ops
ega elemenata koji su jednaki pivot elementu.
//Te dve vrednosti cemo smestiti u niz pivot_loc koji se sastoji od
dva elementa.
int[] pivot_loc = new int[2];
// Ovaj proces se ponavlja za sve nizove koji imaju vie od jednog ele
menta (ako je low=high, to znaci da niz ima samo jedan element)
if (low < high)
{
// Poziva se pomocna funkcija partition koja ce krenuti da razvr
stava niz u odnosu na pivot element.
// Kad ona zavri razvrstavanje vratice konacne pozicije (indekse)
prvog (donjeg) i poslednjeg (gornjeg) elementa cije su vrednosti
// jednake odabranom pivot elementu i te vrednosti ce biti smeten
e u niz pivot_loc.
// C# kod za ovu pomocnu funkciju se nalazi ispod glavne funkcij
e quicksort.
pivot_loc = partition(input, low, high);
// Poto su pronadene konacne pozicije prvog i poslednjeg elementa
koji su jednaki pivot elementu, niz delimo na dva podniza.
//Od pocetka niza, pa sve do lokacije prvog elementa iz grupe el
emenata jednakih pivot elementu (od low pa sve do pivot_loc[0]-1)
// nalaze se elementi koji su manji od pivota i sad i njih treba
na isti nacin sortirati. Takode, od lokacije
//poslednjeg elementa iz grupe elemenata jednakih pivot elementu
, pa sve do kraja niza, nalaze se elementi koji su veci od
//pivota (od pivot_loc[1]+1 do high), pa i njih treba na isti na
cin sortirati. Dakle, potrebno je rekurzivno pozvati
//istu ovu quicksort funkciju za oba ta podniza.
quicksort(input, low, pivot_loc[0] - 1);
quicksort(input, pivot_loc[1] + 1, high);
}
}
// --------------------------------------------------
// partition je pomocna funkcija ciji ce konacni rezultat biti razvrstan
jedan podniz u odnosu na pivot element, pri cemu ce svi
//elementi koji su jednaki pivot elementu biti grupisani uz pivot elemen
t. Ulazni parametri su podniz (input), indeks polaznog (donjeg) elementa
//podniza koji treba sortirati (low) i indeks poslednjeg (gornjeg) eleme
nta podniza kojeg treba sortirati (high). Izlaz su indeksi prvog i
//poslednjeg elementa iz grupe elemenata jednakih pivot elementu
private int[] partition(int[] input, int low, int high)
{
// Za pocetak, potrebno je inicijalizovati niz pivot_loc od dva elem
enta, u kojem ce biti sacuvani ti
//indeksi prvog i poslednjeg elementa iz grupe elemenata jednakih pi
vot elementu.
int[] pivot_loc = new int[2];
// Pivot element se proizvoljno odabira. U ovom primeru za pivot ele
ment je odabrana vrednost poslednjeg elementa u nizu (input[high]).
//Ko eli da odabere neki drugi element za pivot element, potrebno je
samo pre nastavka funkcije prebaciti taj element na poslednje mesto
//i sve je potom isto.
int pivot = input[high];
// Promenljiva i je interni brojac, njena pocetna vrednost je jednak
a indeksu donjeg elementa podniza (low), a njena konacna vrednost,
//po izlasku iz ove pomocne funkcije,
//predstavljace konacnu, sortiranu poziciju prvog elementa iz grupe
elemenata jednakih pivot elementu.
int i = low;
// Promenljiva k je interni brojac, njena pocetna vrednost je jednak
a indeksu gornjeg, poslednjeg elementa podniza (high),
//a pomocu njene konacne vrednosti dobice se konacna, sortirana pozi
cija poslednjeg elementa iz grupe elemenata jednakih pivot elementu.
//U pocetku, elementi koji su jednaki pivot elementu, bice smetani na
kraj podniza, uz sam pivot element, a potom ce
//biti svi zajedno prebaceni u opseg kojem pripadaju.
int k = high;
// Prolazimo kroz ceo podniz, od prvog elementa (low), do poslednjeg
elementa podniza koji ne pripada grupi elemenata koji su vec prethodno
//smeteni na kraj niza, uz pivot element (k).
for (int j = low; j < k; j++)
{
// U slucaju da je element do kojeg smo doli manji od pivot eleme
nta, potrebno je izvriti zamenu, odnosno taj element treba
//pomeriti na pocetak nesredenog dela niza.
//Ovaj deo koda je isti kao i kod 2-way algoritma.
if (input[j] < pivot)
{
// swap je funkcija koja vri zamenu elemenata niza na pozicij
ama i i j. C# kod za ovu pomocnu funkciju se nalazi ispod funkcije partition.
swap(input, i, j);
// Poto je izvrena zamena, inkrementiramo brojac i, odnosno po
meramo poziciju koja oznacava pocetak preostalog, nesredenog,
//dela niza za jedno mesto udesno.
i++;
}
// U slucaju da je element do kojeg smo doli jednak pivot element
u, potrebno je taj element smestiti na kraj niza, odnosno grupisati ga uz pivot
element i do
//tada pronadjene elemente jednake pivot elementu. Ovo je nov de
o koda, u odnosu na 2-way algoritam.
else if (input[j] == pivot)
{
// Vrimo zamenu mesta tog elementa sa poslednjim nesortiranim
elementom sa kraja niza, koji se nalazi uz do tada grupis
//ane elemente koji su jednaki pivot elementu. Taj poslednji
nesortirani element se nalazi na poziciji k-1, jer pozicija k
//oznacava prvi element iz grupe elemenata jednakih pivot el
ementu.
swap(input, j, k - 1);
// Poto je izvrena zamena, te je na kraj niza dodat jo jedan el
ement jednak pivot elementu, potrebno je brojac k pomeriti za
//jedno mesto unapred, da bi opet pokazivao
//na prvi element iz te grupe elemenata jednakih pivot eleme
ntu. Dakle, potrebno je dekrementirati brojac k.
k--;
// S obzirom da je sada na tekucu poziciju (j) ubacen posled
nji nesortirani element sa kraja niza, taj element jo uvek
//nije ispitan, te je potrebno vratiti brojac j za jedno mes
to u nazad da bi se u
//sledecem ciklusu for petlje ponovo ispitala ta pozicija.
j--;
}
}
// Po izlasku iz for petlje, proli smo kroz ceo niz, svi elementi su
razvrstani u odnosu na pivot element
//(i elemente koji su jednaki pivot elementu).
//Promenljiva i sada oznacava konacnu poziciju od koje treba smestit
i celu grupu elemenata jednakih pivot elementu.
//Promenljiva k oznacava prvi element iz grupe elemenata jednakih pi
vot elementu, dok se poslednji element te grupe nalazi na kraju niza.
//Dakle, od pocetka niza (low) do elementa sa indeksom i nalaze se e
lementi koji su manji od pivot elementa.
//Od indeksa i do indeksa k nalaze se elementi koji su veci od pivot
elementa,
//dok se od indeksa k do kraja niza (high) nalaze elementi koji su j
ednaki pivot elementu.
//Ukupan broj elemenata jednakih pivot elementu (ukljucujuci i sam p
ivot element) je stoga jednaka high-k+1.
//Ostaje samo da se cela ta grupa elemenata koji su jednaki pivot el
ementu prebace sa kraja niza na pozicije koje im pripadaju (pocev od indeksa i).

//Definiemo promenljivu m u kojoj cemo zapamtiti taj ukupan broj elem
enata jednakih pivot elementu.
int m;
if ((k - 1) < (high - k + 1))
{
m = k - 1;
}
else
{
m = high - k + 1;
}
for (int p = 0; p < m; p++)
{
swap(input, i + p, high - m + 1 + p);
}
// U for petlji vrimo zamenu tih elemenata, pocev od toga to cemo elem
ent sa pozicije k (prvi element iz grupe elemenata jednakih pivot elementu)
//dovesti na poziciju i. I tako za svih m elemenata iz te grupe.
for (int p = 0; p < m; p++)
{
swap(input, i + p, k + p);
}
// Funkcija, kao rezultat svog izvravanja, vraca konacne pozicije prv
og i poslednjeg elementa iz grupe elemenata jednakih pivot elementu.
//Prvi element iz te grupe se nalazi na poziciji i, dok se poslednji
element iz te grupe nalazi na poziciji i+m-1,
//odnosno, poto je m=high-k+1, to je u stvari pozicija i+high-k. Te d
ve vrednosti se vracaju u formi niza pivot_loc koji se sastoji od dva elementa.
pivot_loc[0] = i;
pivot_loc[1] = i + high - k;
return pivot_loc;

}

// --------------------------------------------------
// swap je pomocna funkcija koja vri zamenu dva elementa niza. Ulazni par
ametri su sam niz (array) i indeksi elemenata cije pozicije treba zameniti (a i
b).
private void swap(int[] array, int a, int b)
{
// pomocna promenljiva temp, pomocu koje se vri zamena
int temp;
temp = array[a];
array[a] = array[b];
array[b] = temp;
}

You might also like