Predavanje 8 Algoritmi I Reavanje Problema

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 20

Algoritmi i reavanje problema

Upotreba raunara za reavanje nekog problema najee zahteva programiranje, odnosno formulisanje plana za precizno
definisane akcije, koje raunar treba da obavi da bi se dobilo reenje problema. Takav plan je algoritam.
Algoritmi su planovi za obavljanje akcija. Algoritmi nisu vezani samo za programiranje. Neki opti primeri algoritama bi
mogli biti:

objanjenje kako doi do odreene adrese

recept za pripremu nekog jela

vez

Ovi algoritmi zahtevaju razliit nivo tehnikog znanja da bi neko uspeo da ih izvri. Prvi algoritam se moe izraziti obinim
jezikom. Drugi algoritam trai da imate malo znanja iz kuvanja, dok bi trei traio iskustvo u itanju ema za vez.
Algoritmi se meusobno razlikuju i po nivou detalja koji su u njima dati. Programski jezici su metodi za predstavljanje
algoritama, kako ljudima tako i raunarima. Razliiti programski jezici mogu da podre razliit nivo detalja. Jezici nieg
nivoa algoritme predstavljaju sa previe detalja, tako da ih ljudi teko mogu ispratiti. Zbog toga se koriste jezici vieg nivoa,
a raunar moe da prevede algoritam izraen u ovakvom programskom jeziku u instrukcije koje procesor izvrava.

Raunari i reavanje problema


Programiranje je pre svega aktivnost koja se odnosi na reavanje problema. Matematiar Dord Polia je reavanje
problema podelio na etiri aktivnosti:
1.

Shvatanje problema: Ovaj prvi korak moe biti teak, ali je vrlo bitan. Bilo bi vrlo glupo traiti odgovor na
pitanje koje niste potpuno shvatili. Generalno, moraju se pronai dati podaci, ta je nepoznato (eljeni rezultat),
kao i veze izmeu datih podataka i onog to je nepoznato. Vrlo je vano biti siguran da su date informacije
dovoljne za reavanje problema.

2.

Smiljanje plana: Nakon to se shvati problem, neko mora smisliti plan akcija koje e taj problem reiti. Plan se
pravi kretanjem od podataka do rezultata, u skladu sa vezama koje izmeu njih postoje. Ako je problem trivijalan,
ovaj korak ne trai mnogo razmiljanja. Generalno se mogu pomenuti sledee tehnike:

Pronalaenje slinih, reenih problema

Preoblikovanje originalnog problema, tako da lii na poznati problem.

Skraivanje problema na manji problem, koji se moe reiti

Generalizacija problema

Pronalaenje postojeeg rada, koji moe pomoi u traenju reenja

3.

Izvrenje plana: Nakon to je definisan plan, njega bi se trebalo u potpunosti pridravati. Svaki element plana
treba da se proveri i primeni. Ako se zakljui da neki elementi plana nisu dobri, plan treba promeniti.

4.

Ocena: Na kraju treba ispitati rezultat, da biste bili sigurni da je on u redu i da je problem reen.

Kao to znamo uvek postoji vie naina da se rei isti problem. Kada se razliiti ljudi susretnu sa istim problemom,
verovatno je da e svaki od njih problem reiti na drugi nain. Ipak, da bi osoba bila efikasna, ona mora da prihvati
sistematski metod reavanja problema. Ako se problem reava pomou raunara, sistematinost je krucijalna. Ako nema
sistematinosti ovek se lako moe nai u situaciji da suvie kasno zakljui da je trebalo vie vremena da posveti planiranju.
Na bazi metoda za reavanje problema koji je ovde iznet moe se izvesti metod za reavanje problema u vie koraka. Ovaj
metod se moe prilagoditi stilu svakog pojedinca. Metod ima puno zajednikog sa ivotnim ciklusom softvera, odnosno
njegovim fazama.
Ti koraci su:
1.

Definisanje problema

2.

Projektovanje reenja

3.

Fino podeavanje reenja

4.

Razvoj strategije testiranja

5.

Kodiranje i testiranje programa

6.

Pisanje dokumentacije

7.

Odravanje programa

Definisanje problema
Prvi korak je da se problem potpuno shvati i razume. Inicijalni opis problema je obino maglovit. Mora se napraviti
precizan opis. Onaj ko iznosi problem (korisnik) i onaj ko taj problem reava (programer) moraju zajedno raditi da bi bili
sigurn da su oboje shvatili problem. Ovo bi trebalo da vodi do kompletne specifikacije problema, ukljuujui preciznu
definiciju ulaznih podataka (dati podaci), kao i eljenog izlaza (rezultata).

Projektovanje reenja
U ovom koraku treba definisati okvir reenja. Polazi se od originalnog problema, koji se deli na manje potprobleme.
Potprobleme je lake reiti poto su manji od originalnog problema. Njihova reenja e biti komponente krajnjeg reenja.
Isti metod "podeli pa vladaj" se primenjuje i na potprobleme, sve dok se ceo problem ne pretvori u plan sa precizno
definisanim koracima.
Objasnimo ovo detaljnije na primeru pripreme kolaa. Ovo nije raunarski problem, ali je dobar primer, da se shvati princip.
Recimo da domaica pravi kolae. Kolai su od testa, koje se puni nekim nadevom i na kraju se sve to preliva eerom u
prahu. Prvo se pripremi testo, koje se zatim oblikuje prema elji. Posle toga se testo pee 20 minuta. Zatim se stavlja nadev,
koji je prethodno pripremljen i na kraju se sve to pospe eerom u prahu.
Ceo problem se moe podeliti na tri potproblema. Pravljenje testa, priprema nadeva i zavrno pravljenje kolaa. Svaki od
potproblema se moe dalje deliti, dok ne to ne postanu ekstremno mali potproblemi. U toku ovog koraka nastaje dijagram
koji ilustruje strukturu reenja. Ovaj dijagram se naziva strukturnim dijagramom, poto pokazuje strukturne komponente
reenja, kao i veze izmeu komponenti.

Kompletno reenje

Komponenta

Priprema testa

potkomponenta

Recept za kolae

Priprema nadeva

Zavrna obrada

Punjenje

Stavljanje eera

Fino podeavanje reenja


Reenje koje se dobija u prethodnom koraku je na visokom nivou. Tu je krajnji zadatak razlaganje na nekoliko podzadataka,
ali nema indikacija kako bi se ti podzadaci izvrili. Opte reenje se mora dalje razlagati, odnosno moraju se dodati detalji.
Svaki pravougaonik sa strukturnog dijagrama se mora vezati uz precizan opis metoda za izvrenje tog zadatka. Precizan
opis metoda podrazumeva niz dobro definisanih koraka, koji kada se izvre zavravaju taj zadatak. Taj niz koraka se naziva

algoritmom. Algoritmi se obino daju u pseudokodu. Pseudokod je poseban jezik koji se koristi za opis onog to se radi sa
podacima. Ovaj jezik je nezavisan od konkretnog programskog jezika.
Recimo da bi se zadatak pripreme nadeva mogao predstaviti na sledei nain:

Stavljanje laga u mikser


Stavljanje ostalih sastojaka
Izbor reima rada miskera
Pokretanje miksera
Zaustavljanje miksera
Vaenje nadeva iz miksera
Ukoliko neki od koraka nije dovoljno jasan postupak se moe ponovo primeniti, odnosno moe se vriti dalje ralanjivanje,
sve dok se ne dobije reenje koje je potpuno jasno i upotrebljivo.

Razvoj strategije testiranja


U prethodnom koraku je napravljen algoritam koji se koristi za pisanje programa koji odgovara reenju. Ovaj program e se
izvravati na raunaru i od njega se oekuje da proizvede ispravno reenje. Vrlo je bitno proveriti taj program u vie
razliitih situacija, sa razliitim kombinacijama ulaznih podataka, da bismo bili sigurni da su reenja u redu.
Svaki test predstavlja razliitu kombinaciju ulaznih podataka. Program se testira tako to se napravi niz sluajeva testiranja,
koji pokrivaju ne samo uobiajene ulazne podatke, ve i ekstremne vrednosti. Pored toga se koriste i specijalne kombinacije
ulaznih veliina, da bi se testirali konkretni aspekti programa.
Pogledajmo na primer, program za plate. Test sluajevi bi trebalo ukljuuju vrednosti koje pokrivaju ceo opseg plata,
ukljuujui i krajnje vrednosti, maksimalan broj radnih sati itd. Tipini test bi mogao da definie nadnicu za jedan sat, radne
sate i oekivane rezultate.

nadnica = $10.00 radniSati = 35 rezultat = $350.00


Sluajeve testiranja je najbolje napraviti pre pisanja programa, poto se oni mogu koristiti i za proveru algoritma, a i zato to
pritisak za to bri zavretak programa moe dovesti do gubitka objektivnosti, ako se testira u letu.

Kodiranje i testiranje programa


Algoritmi napisani u pseudokodu ne mogu da se izvre direktno na raunaru. Taj pseudokod mora prvo da se prevede u
programski jezik. To je proces kodiranja.
Nakon kodiranja algoritma, program mora da se testira. To se radi na osnovu strategije testiranja, koja je napravljena u
prethodnom koraku. Program mora da se izvri i za svaki sluaj testiranja mora da se proveri da li rezultat odgovara onome
to je predvieno. Ako ima razlike rezultat treba analizirati, da bi se pronala greka. Greka moe biti na jednom od etiri
mesta:

Kodiranje: Greka je nastala u prevoenju algoritma u programski jezik.

Algoritam: U algoritmu je postojala greka koja nije primeena.

Dizajn programa: Moda je dizajn programa lo, pa je to dovelo do greke.

Izraunavanje rezultata testiranja koji se oekuju: Moda je rezultat testiranja loe proraunat.

Nakon to se pronae greka, prave se revizije. Ovo se ponavlja sve dok program ne da oekivane rezultate za sve sluajeve
testiranja. Proces kodiranja i testiranja se jednim imenom naziva implementacijom.

Pisanje dokumentacije
Pisanje dokumentacije poinje sa prvim korakom u razvoju programa i nastavlja se tokom ivotnog ciklusa programa.
Dokumentacija mora da sadri sledee:

Objanjenje svih koraka i metoda.

Odluke vezane za dizajn programa.

Probleme koji su se javili tokom pisanja i testiranja programa.

Zavrna dokumentacija mora da sadri i odtampanu kopiju programa, tzv. listing. Taj listing treba da bude odtampan sa
odgovarajuim zaglavljem, tako da se lake prati. U programima treba da postoje komentari. Ti komentari su kasnije
naroito korisni, kada doe do promene programa.
Dokumentacija mora da sadri i odreene instrukcije za korisnika. Ako programe koriste ljudi koji nisu bliski sa
raunarima, mora postojati korisniko upustvo, koje bez tehnikih izraza, objanjava kako se program koristi, kako se
pripremaju ulazni podaci i kako se interpretiraju rezultati.

Odravanje programa
Odravanje programa nije direktno deo procesa implementacije. Tu spadaju sve aktivnosti koje se deavaju nakon to
program pone da se koristi. Termin odravanje, kada se primeni na programe, ima razliito znaenje od uobiajenog. Kue,
automobili ili drugi objekti imaju odravanje zato to se vremenom troe. Programi, meutim, nemaju fizike osobine, ve
samo logike, tako da se ne troe usled upotrebe.
Moe se desiti da program izvrite 100000 puta i da on radi dobro, a da se u sledeem prolazu desi greka. To moe dovesti
u zabludu da program nije dobar, ali se u sutini desilo da je program naiao na neke okolnosti koje nisu bile predviene.
Drugim reima, to znai da program nije bio testiran u tim okolnostima i da od poetka nije radio pod tim uslovima. U
ovom smislu odravanje programa se uglavnom odnosi na kompletiranje procesa implementacije.
Odravanje programa ukljuuje i poboljanja za koja se, tokom upotrebe programa, zakljui da su potrebna. Odravanje
programa ukljuuje:

eliminisanje greaka koje su naknadno otkrivene.

modifkaciju tekueg programa

dodavanje novih osobina u program

auriranje dokumentacije

Vrlo esto se deava da cena odravanja programa prevazie inicijalnu cenu koja je plaena za prvobitni razvoj.

Algoritmi
Definicija: Algoritam je precizan plan za obavljanje niza akcija, koje vode odreenom cilju.
Algoritmi mogu biti, na primer:

priprema doruka

izraunavanje srednje vrednosti

promena gume na automobilu

igranje jamba

Obratite panju na to da svaki od prethodno navedenih algoritama definie dve stvari:


1.

Akciju, koja se zadaje glagolima, kao to su "priprema", promena, igranje

2.

Podatke na kojima se akcija vri. To su imenice, kao to su doruak, guma na automobilu i sl.

Iz ovih primera treba da shvatite da se algoritmi ne koriste samo kod raunara, ve postoje u svakodnevnom ivotu.

Kriterijumi za algoritme
Algoritmi treba da zadovolje sledea etiri kriterijuma:
Kompletnost: Da bi algoritam bio kompletan, sve njegove akcije moraju biti egzaktno definisane. Pogledajmo na primer,
algoritam koji opisuje kako stii do nekog restorana.
1.

Krenite glavnom ulicom i na raskrsnici sa ulicom Kralja Aleksandra skrenite levo.

2.

Idite pravo jo jedan kilometar i biete ispred restorana.

Da li je ovo algoritam? Nije, poto uputstva nisu precizna. Na koju stranu glavne ulice treba krenuti. Ako ve poznajete tu
oblast onda moda i imate predstavu na koju stranu treba krenuti, ali ipak uputstva nisu precizna.

Nedvosmislenost: Skup instrukcija e biti nedvosmislen ako postoji samo jedan mogui nain da se one interpretiraju. Na
primer, ak i ako prihvatimo da su instrukcije za put do restorana dovoljno precizne, ipak postoji dvosmislenost o tome u
kom smeru krenuti. Mi ne smemo da pretpostavljamo neko lokalno znanje, jer, ako poznajemo taj kraj, onda i znamo kako
da doemo do restorana. Dvosmislenost se moe reiti probom. Moemo da probamo da idemo na jednu stranu, pa ako
pronaemo restoran onda i to treba dodati u algoritam.
Odreenost: Trea osobina kae da ako se prate instrukcije, onda je izvesno da e se postii eljeni rezultat. Pogledajmo
sledei algoritam, koji pokazuje kako postati milioner:
1.

Uzmite sav svoj novac iz banke i promenite ga u metalne novie.

2.

Idite u kockarnicu.

3.

Igrajte na mainama sve dok ne dobijete milion dinara.

Jasno je da ovaj algoritam nee uvek dovesti do eljenog rezultata, da postanete milioner. Mnogo je verovatnije da ete
izgubiti sav novac. Poenta je da ne moemo biti sigurni kakav e biti rezultat. Na taj nain skup instrukcija nije odreen, pa
samim tim ni instrukcije ne predstavljaju algoritam.
Konanost:Ova osobina kae da se instrukcije moraju zavriti nakon odreenog broja koraka."Algoritam" kojim se postaje
milioner i ovde ne zadovoljava. Moe se desiti da nikad ne dobijete milion dinara, ali ni da izgubite sav novac. Drugim
reima, ako sledite instrukcije moe se desiti da zavrite igrajui na automatima zauvek.
Konanost se ne odnosi samo na zavretak nakon odreenog broja koraka, ve i na to da instrukcije treba da koriste konaan
broj promenljivih da se dobije eljeni rezultat.

Osobine koje bi algoritmi trebalo da imaju


I kada algoritam zadovolji kriterijume koje smo pomenuli (preciznost, nedvosmislenost, odreenost, konanost), moe se
desiti da nije pogodan da se koristi kod reenja problema putem raunara. Poeljni atributi, koje jedan algoritam treba da
ima su:
Optost: Algoritam treba da reava klasu problema, a ne samo jedan problem. Na primer, algoritam koji trai srednju
vrednost od etiri zadate vrednosti, generalno nije tako koristan kao ona koji izraunava srednju vrednost za proizvoljan
broj vrednosti.
Dobra struktura: Ovaj atribut se odnosi na konstrukciju algoritma. Algoritam sa dobrom strukturom treba da se pravi
preko dobrih blokova, koji omoguavaju da se algoritam:

lako objasni

lako razume

lako testira

lako menja

Blokovi od kojih je algoritam sastavljen treba da budu tako napravljeni da se mogu lako zameniti boljom verzijom, bez
nekih velikih promena.
Efikasnost: Brzina izvrenja algoritma je esto vana osobina, isto kao i njegova veliina i kompaktnost. Inicijalno ovi
atributi nisu toliko bitni. Prvo se mora napraviti algoritam sa dobrom strukturom koji nas vodi do eljenog reenja, pod svim
uslovima. Tek nakon toga moemo poboljavati efikasnost algoritma.
Lakoa upotrebe: Ova osobina se odnosi na udobnost i lakou sa kojom korisnici algoritam mogu da primene na svoje
podatke. Ponekad ono to omoguava da korisnik lake razume algoritam, vodi ka tekoama za programera (i obrnuto).

Predstavljanje algoritama
Da bi se iskoristili na pravi nain, algoritmi se moraju predstaviti tako da ih razumemo. Postoji vie naina za predstavljanje
algoritama.
Verbalno predstavljanje: Kod ovakvog predstavljanja se algoritmi izraavaju u nekom od jezika koji ljudi koriste
(svakodnevni jezik). Pogledajmo na primer, algoritam koji opisuje kako se izraunava nedeljna plata nekog slubenika.

Ako slubenik ima manje (ili jednako) od 40 radnih sati u toku nedelje,
onda se njegova plata rauna kao broja radnih sati puta cena po satu

(100 din). Ako je radio vie od 40 sati, onda se za svaki sat preko te
brojke, cena rada poveava i iznosi 150 din.
Ako je broj radnih sati, na primer, 25, onda se plata rauna mnoenjem broja radnih sati (25) i cene rada (100 din.) to daje
2500. Ako je broj radnih sati 50, onda je plata sastavljena iz dva dela. Jedan deo je plata za uobiajenih 40 radnih sati i
iznosi (40 x 100 ) 4000 din. Radni sati preko 40 se plaaju posebno i ta suma je u ovom sluaju (50 - 40) x 150 = 1500 din.
Ukupna suma je zbir ove dve sume i iznosi 5500 din. To je znai finalni izlaz algoritma.
Predstavljanje pomou dijagrama toka: Kod ovog naina se algoritam predstavlja grafiki preko simbola, koji su spojeni
strelicama. Ovde se koriste sledei simboli:

Zaobljeni pravougaonici oznaavaju poetak i kraj

Obini pravougaonici oznaavaju akcije

Rombovi oznaavaju odluke koje se donose. Oni sadre i uslove koji odreuju kojim putem se tok nastavlja.

Grafika forma omoguava ljudima da lake prate redosled akcija, odnosno tok kontrole. Sledea slika prikazuje algoritam
koji smo prethodno verbalno opisali. Obratite panju na to da je plaanje osnovne sume za 40 radnih sati prikazano kao
40x100, a ne kao suma 400. Ako bismo prikazali broj 400, onda bismo sakrili dve komponente dijagrama. U tom sluaju bi
se 400 pojavio kao neki magini broj, a algoritam bi tei za razumevanje.

Poetak

Ulazni sati

Tano

Netano
Sati <= 40

plata = 100 x40 + 150


x(sati-40)

plata = 100 x sati

plata

kraj

Grafikoni: Ovde je u pitanju predstavljanje algoritama preko dijagrama. Ono ljudima moe pomoi da bolje shvate
izvrenje algoritma. Grafikon na sledeoj slici pokazuje kako cena radnog sata zavisi od broja radnih sati. Ukupna suma
koja se plaa za neki broj radnih sati je oseneni deo. Na primer, ako je broj radnih sati 50, ukupna plata odgovara
osenenom delu koji se sastoji od tri mala pravougaonika oznaena sa a, b i c. Ukupna plata je onda:
PLATA = 100 x 40 + 100 x 10 + 50 x 10 = 5 500.
Plata

150
100
50

20

40

50

radni sati

Dijagrami toka podataka: Ovi dijagrami predstavljaju algoritme kao "crne kutije", tako da ne moete da vidite ta se
unutra deava. Prikazani su samo ulazni i izlazni podaci, kao to se moe videti na sledeoj slici. U ovom sluaju podatak
(50 sati) ulazi u pravougaonik za izraunavanje plate, iz kojeg na dnu izlazi izraunata plata (5500). Ovi dijgrami sakrivaju
detalje algoritma, ali su korisni kada treba opisati interakciju i tok podataka izmeu algoritama.
Dijagrami toka podataka pokazuju ta se deava, dok dijagrami kontrole toka pokazuju kako se to deava.

Sati
50 sati
Algoritam
5500
Plata
Pseudokod: Pseudokod predstavlja meavinu matematike, logike i prirodnog jezika. Algoritam iz prethodnih primera bi se
mogao izraziti ovako:

Input brojRadnihSati
If brojRadnihSati > 40
Set Plata to Nadnica x 40 + 1.5 x Nadnica x (brojRadnihSati - 40)
Else
Set Plata to Nadnica x 40

Analiza algoritama
Ako reavanje nekog problema poverite razliitim ljudima, verovatno ete dobiti onoliko razliitih reenja koliko ljudi to
bude radilo. Ako se to prenese na oblast programiranja, verovatno e svako imati svoj algoritam. Postavlja se pitanje kako
izabrati pravi algoritam. Koje su to mere koje ukazuju da je jedan algoritam bolji od drugog.
Ako su u pitanju algoritmi koji su poznati u literaturi, onda se u literaturi mogu nai i podaci o tome koji je od tih
algoritama najbolji. Sa druge strane, ako su u pitanju novi problemi, odnosno novi algoritmi, treba na umu imati neke
osnovne napomene.
Problemi koji se reavaju obino imaju svoju "prirodnu veliinu". To je najee koliina podataka koji treba da se obrade.
Ova veliina se obino oznaava sa N. Kod analize algoritama bismo voleli da znamo resurse koji su korieni (najee
vreme koje je proteklo) u funkciji od N.
esto smo kod analize zainteresovani za srednje vreme koje bi proteklo dok program analizira podatke. To srednje vreme je
sredina vremena potrebnog za obradu tipinih ulaznih podataka i vremena potrebnog za obradu najgore kombinacije ulaznih
podataka.
Ve smo pomenuli da veina algoritama ima primarni parametar N, obino broj podataka koji se obrauju, koji
najznaajnije utie na vreme izvrenja algoritma. Taj parametar moe biti stepen polinoma, veliina datoteke koja se sortira
ili pretrauje, broj vorova u grafu itd. Veina osnovnih algoritama ima vreme izvrenja proporcionalno jednoj od sledeih
funkcija:

1 - Veina instrukcija se u veini programa izvrava jednom ili samo nekoliko puta. Ako su sve instrukcije u
programu takve, onda se kae da je vreme izvrenja konstantno. Oigledno je da je to situacija kojoj treba teiti
kod kreiranja algoritma.

log N - Ako je vreme izvrenja programa logaritamska funkcija, onda program postaje pomalo sporiji, kako N
raste. Ovakvo vreme izvrenja se obino javlja u programima kod kojih se veliki problem reava razlaganjem na

manje, tako to se veliina deli nekim konstantnim brojem. Ta konstanta se moe smatrati manjom od neke
ogromne brojke. Osnova algoritma utie na konstantu, ali ne toliko puno. Ako je N hiljadu logN je 3 (ako je
osnova 10), a ako se N povea na 1 000 000 logN se duplira. Kad god se N povea na N2 logN se duplira. Kad god
se N duplira, logN se povea za neku konstantu.

N - Ovo se deava kada je vreme izvrenja programa linearno. Ovo je generalno sluaj kada se odreeno, kratko
vreme, troi na obradu svakog ulaznog elementa. Ako je N milion onda je takvo i vreme izvrenja. Kad god se N
duplira isto se deava i sa vremenom izvrenja. Ovo je optimalno reenje za algoritam koji treba da obradi N ulaza
(ili proizvede N izlaza).

N logN Ovakvo reenje se javlja kod algoritama koji problem reavaju podelom na manje probleme, pri emu se ti
potproblemi reavaju nezavisno, a na kraju se ti rezultati kombinuju u jedan. Ovakvi algoritmi se oznaavaju sa "N
log N". Ako je N milion, onda je N log N moda 20 miliona. Kada se N duplira vreme izvrenja se povea vie od
dva puta (ali ne mnogo vie).

N2 - Ako je vreme izvrenja algoritma kvadratno, onda je on pogodan samo za reavanje relativno malih problema.
Kvadratno vreme izvrenja se javlja kod algoritama koji obrauju sve parove ulaznih podataka (moda u dvostruko
ugnedenoj petlji). Ako je N hiljadu, onda je vreme izvrenja milion. Kad god se N duplira vreme izvrenja se
uetvorostrui.

N3 - Ovaj algoritam je slian sa prethodnim. Razlika je u tome da se obrauju trojke podataka (trostruko
ugnedenoj petlji). Vreme izvrenja je kubno. Ovaj algoritam je takoe praktian samo za male probleme. Ako je
N hiljadu vreme izvrenja je milijarda. Kad god se N duplira, vreme izvrenja se povea osam puta.

2N - Ponekad se koriste i algoritmi sa eksponencijalnim vremenom izvrenja. Ako je N dvadeset, vreme izvrenja
je milion. Kad god se N povea dva puta, vreme izvrenja poraste na kvadrat.

Aritmetiki algoritmi
Algoritmi za obavljanje elementarnih matematikih operacija, kao to su sabiranje, mnoenje i deljenje imaju dugaku
istoriju i datiraju jo od arapskog matematiara al-Khowdirzmija, pa se ak ide i dalje u prolost, do starih grka i vavilonaca.
Raunari imaju ugraene mogunosti za aritmetike operacije nad celim i realnim brojevima, tako da tu i nema svrhe
posezati za algoritmima. Algoritmi dolaze u obzir kada se ove operacije obavljaju nad sloenijim matematikim objektima,
kao to su polinomi ili matrice.

Polinomi
Pretpostavimo da elimo da napiemo program koji sabira dva polinoma, odnosno elimo da se obavi izraunavanje tipa:

(1+ 2x - 3x3 ) + (2 -x) = 3 + x - 3x3


Uopteno se moe rei da elimo da napravimo program koji e biti u stanju da izrauna r(x) = p(x) + q(x), gde su p i q
polinomi sa N koeficijenata. Sledei program je jednostavna implementacija sabiranja polinoma:

public double[] sabiranje(double[] p, double[] q){


double[] r;
int duzina = p.length;
r = new double[duzina];
for(int i = 0; i < duzina; i++){
r[i] = p[i] + q[i];
}
return r;
}
U ovom programu se polinom p(x) = p0 + p1x + ... + pn-1xN-1 predstavlja preko niza p, sa N elemenata, gde je p[j] = pj, itd.
Polinom N-1 -og stepena se definie sa N koeficijenata. Ulaz u metod su nizovi p i q. Izlaz je niz r, koji predstavlja zbir ovih
polinoma.
Program za sabiranje polinoma je trivijalan, kad se jednom izabere nain predstavljanja polinoma. Same operacije se posle
lako kodiraju.
Ovaj program i algoritam je lako preurediti tako da se ostvari mnoenje polinoma. Dovoljno je promeniti petlju koja obavlja
sabiranje:

public double[] mnozenje(double[] p, double[] q){


double[] r;
int duzina = p.length;
r = new double[2*duzina - 1];
for(int i = 0; i < duzina; i++){
for(int j = 0; j < duzina; j++){
r[i+j] = r[i+j] + p[i] * q[j];
}
}
return r;
}
Naravno da se mora promeniti i deklaracija za r, tako da ovaj niz moe da primi dva puta vie koeficijenata. Svaki od N
koeficijenata iz p se mnoi svakim od N koeficijenata iz q. Jasno je da je ovo kvadratni algoritam.

Matrice
Algoritmi za obavljanje osnovnih aritmetikih operacija nad matricama su slini sa onima za polinome, mada malo
komplikovaniji. Pretpostavimo da elimo da naemo sumu dve matrice:

Program izgleda ovako:

public int[][]sabiranjeMatrica(int[][] p, int[][] q){


int[][] r = new int[p.length][p.length];
for(int i = 0; i < p.length; i++){
for(int j = 0; j < p[i].length; j++){
r[i][j] = p[i][j] + q[i][j];
}
}
return r;
}
Mnoenje matrica je komplikovanija operacija. U ovom sluaju je potrebno sabrati proizvode odgovarajuih elemenata. To
znai da se element sa indeksom ij dobija sabiranjem proizvoda i-te vrste matrice p sa j-om kolonom matrice q, odnosno p[i,
1]*q[1, j]+p[i, 2]*q[2, j]+... p[i, N-l]*q[N-1, j]. Program je:

public int[][]mnozenjeMatrica(int[][] p, int[][] q){


int[][] r = new int[p.length][q[0].length];
for(int i = 0; i < p.length; i++){
for(int j = 0; j < p[i].length; j++){
int t = 0;
for(int k = 0; k < p.length; k++){
t = t + p[i][k]*q[k][j];
}
r[i][j] = t;
}
}
return r;
}
Svaki od N2 elemenata u rezultujuoj matrici se dobija preko N mnoenja, tako da je za mnoenje dveju matrica dimenzija
N potrebno oko N3 operacija. Ovo nije ba pravi kubni algoritam, poto je broj podataka N2.

Sortiranje
Sortiranje je proces koji se izuzetno esto javlja u raunarskim programima. Sortiranje je proces ureivanja stavki koje ine
neki skup, prema nekom kriterijumu (numerikom, po abecedi). Stavke koje se sortiraju mogu biti male, poput brojeva,
slova ili nizova karaktera, ali i veliki zapisi, poput zapisa iz bibliotekih kataloga, kada svaki zapis sadri mnotvo
informacija o knjizi. Stavke se obino sortiraju prema rastuim ili opadajuim vrednstima nekog polja, koje se naziva
kljuem za sortiranje. Ovo polje moe biti numeriko ili alfabetsko.
Obino se stavke koje se sortiraju nalaze u nizu.
Proces sortiranja se moe odvijati sa tri razliite strategije. Strategije emo objasniti na primeru brojeva koji se sortiraju po
opadajuem nizu.

Sortiranje sa kopiranjem
Kod ovog metoda se sortiraju lanovi niza A, koji se sa novim redosledom kopiraju u drugi niz B. Ovaj metod troi vie
memorijskog prostora, poto je potreban jo jedan niz iste veliine kao poetni, u koji e se smestiti rezultat. Ovde je vano
napomenuti da originalni niz posle procesa sortiranja ostaje nepromenjen.
Opti metod

A1

Primer

A2

A3

...

An

21

12

54

A1

A2

A3

Sortiranje i kopiranje

B1

B2

B3

...

B1 > B2 > B3 > >

48

...

An

Sortiranje niza A u niz B

Bn

Bn

B1

54

B2

52

B3

48

...

Bn

Sortirane stavke
niza A

12

Sortiranje sa rangiranjem
Kod ovog sortiranja se generie drugi niz R koji sadri rang svake sortirane stavke. Rang predstavlja poziciju odreene
stavke u originalnom nizu. Ako pogledamo narednu sliku, videemo da je najvea vrednost u nizu A, 90. To znai da prvi
lan niza R ukazuje na broj 90, tako to sadri poziciju broja 90 u originalnom nizu A. U ovom sluaju to je 3. Kao i kod
sortiranja sa kopiranjem i ovaj metod uva originalnni niz i zahteva drugi niz. Taj drugi niz najee ne trai isti prostor kao
originalni, poto je u pitanju niz celih brojeva. Njegovi elementi nisu celi zapisi iz prvobitnog niza.

10

A1

A2

A3

...

An

23

11

A1

A2

90

47

...

An

Sortiranje i rangiranje

R1

R2

R3

...

Sortira se A, a rang se
prikazuje u R
Rn

Ako je Ai > Aj onda se i u nizu R


prikazuje pre j

R1

R2

18

R3

Pozicija sortiranih stavki

Rn

...

11

22

Sortiranje na licu mesta


Ovo sortiranje se ponekad naziva i sortiranje sa brisanjem, poto se u ovom sluaju koristi samo jedan niz. Ureene
vrednosti se posle sortiranja ponovo stavljaju u originalni niz A. Kod ovakvog sortiranja se postie uteda na prostoru, poto
je potreban samo jedan niz.

A1

A2

A3

...

An

11

45

99

A1
A

A2

A3

Sortiranje na mestu

A1

A2

A3

...

78

...

Sortiraju se i briu
vrednosti u A
An

A1 > A2 > A3 > ... > An

A1

A2

A3

99

78

69

...

An

Sortirane
stavke

11

Metodi sortiranja
Kod svake od tri osnovne strategije soortiranja, koje smo pomenuli postoji vie razliitih algoritama za sortiranje. Svi ti
algoritmi se mogu svrstati je etiri kategorije.

Sortiranje sa prebrojavanjem, gde se deava prebrojavanje i poreenje

Sortiranje sa zamenom, gde parovi stavki menjaju mesta

Sortiranje sa selekcijom, gde se biraju ekstremne vrednosti

Sortiranje sa umetanjem, gde se deava premetanje i umetanje vrednosti

U daljem tekstu emo objasniti svaki od ovih metoda. Radi pojednostavljenja emo sortirati pozitivne cele brojeve, koji se
meusobno razlikuju. Vrednosti treba da se postave u opadajui niz.
Ovi algoritmi se vrlo lako mogu modifikovati, ako elite da sortirate nizove karaktera, po redosledu u abecedi. Algoritme
emo ilustrovati na nizu od 9 brojeva, od 1 do 9. Originalan niz je:

8, 5, 4, 9, 1, 7, 6, 3, 2

11

Sortiranje sa prebrojavanjem
Ovo je jedan od najjednostavnijih metoda sortiranja. Kod ovog metoda se pronalazi rang svih vrednosti u nizu. Najvea
vrednost ima rang 1, dok najmanja ima rang N (ako su sve vrednosti razliite).
Na gornjem levom delu naredne slike je prikazan originalan niz A, pre sortiranja. Rang neke vrednosti X se pronalazi
poreenjem te vrednosti sa svim vrednostima u nizu od N elemenata, kao i brojanjem vrednosti koje su vee ili jednake od
vrednosti X. Za najveu vrednost postoji samo jedna vrednost koja je vea ili jednaka od nje (to je ona sama), tako da je
njen rang 1. Za drugu najveu vrednost postoje dve vrednosti koje su vee ili jednake od nje, tako da ona ima rang 2 itd. Za
najmanju od N vrednosti postoji N vrednosti koje su vee ili jednake od nje, tako da ona ima rang N.
P o sto je sa m o d v a
e le m e n ta n iz a
k o ja su v e a ili
je d n a k a 8
P rv i p ro la z : ra n ig ra n je A (1 )
Pre
A (i)

K a k o se m e n ja ra n g z a p rv i e le m en t (8 )
C=

1
C=

1
C=

1
C=

2
C=

2
C=

2
C=

C=

2
C=

P o sle p rv o g p ro laz a v red n o st 8 im a ra n g 2

R ang
R (i)

P o sle R (i)
2

7
8

P o sle p ro la z a

Prvi prolaz je prikazan u gornjem delu slike. U prvom prolazu se uzima vrednost 8 i poredi sa ostalim vrednostima u nizu
(ukljuujui i nju samu). Svaki put kad se pronae vrednost koja je vea ili jednaka od 8, broja se poveava za 1.
1.

U naem sluaju se uzima 8, poredi sa prvom vrednou 8 i broja dobija vrednost 1.

2.

Kada se naie na 9 broja dobija vrednost 2.

Ovim se odreuje da prva vrednost 8 ima rang 2, poto su samo dve vrednosti vee ili jednake sa njom. Na donjem delu
slike je prikazan rezultat svakog prolaza. Ukupno ima 9 prolaza (N=9).
Sada moemo da ponemo sa razvojem algoritma. Proces emo poeti odozgo nadole. Prvo emo definisati grubi okvir
algoritma.

12

Pseudo kod ovog algoritma izgleda ovako:

CountSort(A, Rang)
for prolaz=1 do brojStavki po 1
broji vrednosti vee ili jednake od A[prolaz]
podeava Rang[prolaz] na prebrojane vrednosti
kraj

Akcija za
svaki prolaz

Ako sada razloimo korake koje smo dali u prethodnoj petlji, to izgleda ovako:

CountSort(A, Rang)
for prolaz=1 do brojStavki po 1
Vrednost se podeava na A[prolaz]
Brojac se podeava na 0
for indeks=1 do brojStavki po 1
if A[indeks] >= Vrednost
poveaj Brojac za 1
Podesi Rang[prolaz] na Brojac
Kraj

Akcija za
svaki prolaz

1.

Tokom svakog prolaza se selektuje vrednost.

2.

Ta vrednost se zatim poredi sa svim lanovima niza. U promenljivu brojac se smesta broj elemenata koji su vei ili
jednaki sa promenljivom vrednost.

3.

brojac koji se dobije na kraju se smeta u niz Rang.

Obratite panju na to da su sve vrednosti u ovom primeru razliite, tako da se dobijaju razliite vrednosti za rang, koje se
kreu od 1 do N. Ako bi se neke vrednosti ponavljale, onda bi se i neki rangovi ponavljal, dok neki rang ne bi imao
odgovarajuu vrednost. Na primer, ako bismo u prethodnom primeru, promenili element 8 na 9, postojala bi dva elementa
koja imaju rang 2, a nijedan ne bi imao rang 1.

Analiza algoritma
Kad god pravite algoritam trebalo bi da uradite dve stvari:
1.

Da proverite da li radi

2.

Da izvrite analizu da biste videli koliko dobro radi

Performanse algoritma se mogu meriti na vie naina. Najee se analiza vri na osnovu vremena izvrenja i prostora koji
je potreban za izvrenje.
Vreme izvrenja je direktno povezano sa brojem operacija koje se moraju obaviti. U naem primeru se spoljanja petlja
ponavlja N puta, dok se u svakom od tih prolaza unitranja petlja ponavlja N puta. Ukupan broj prolaza je prema tome N x
N. Poto u naem primeru imamo 9 elemenata, to e biti 81 prolaz. Svaki prolaz znai jedno poreenje, tako da e biti
ukupno 81 poreenje.
Ako izvrite dalju analizu zakljuiete da dupliranje veliine niz (od 9 na 18) nee jednostavno duplirati broj poreenja, ve
e taj broj kvadratno porasti (od 81 na 324). Ovaj kvadratni rast rezultuje vrlo sporim algoritmom, posebno ako su u pitanju
dugaki nizovi.
Na osnovu podele koju smo dali, moe se zakljuiti da ovaj algoritam pripada kategoriji kvadratnih algoritama.
Sa stanovita efikasne upotrebe memorijskog prostora, ovaj algoritam nije ba najefikasniji. Kao to ste videli potreban je
drugi niz koji uva rang koji se dodeljuje pojedinim elementima niza. U sluaju da originalni niz ima velike elemente
(zapise), onda je u poreenju sa njim prostor potreban za dodatni niz mali, jer se u taj niz smetaju celi brojevi. U naem
sluaju je dodatni niz iste veliine, kao i poetni, poto oba niza sadre cele brojeve.

Sortiranje sa zamenom
Kod ove familije algoritama postoji veliki broj varijacija na istu temu. Mi emo ovde predstaviti algoritam poznat kao
mehurasto sortiranje (bubble sort).

13

Ovaj algoritam se sastoji od poreenja susednih vrednosti u nizu koji se sortira i zameni mesta, ako vrednosti nisu sreene.
Na gornjem delu naredne slike je prikazan prvi prolaz kroz niz. U to prolazu se vri poreenje svih susednih stavki. Nakon
prvog prolaza se moe rei da je niz malo vie sortiran. Primetiete da je najvea vrednost (originalno na mestu 4) sada
dola na prvu poziciju, gde i treba da bude.

Prvi prolaz
Pre
A[i]

Posle prvog prolaza, najvea vrednost 9 skae na prvu poziciju

Posle
A[i]

Posle prolaza
U ovoj fazi su sve vrednosti ve
sortirane. Ostali prolazi su nepotrebni.
U donjem delu slike su prikazani rezultati svakog prolaza. Kao to se vidi posle prvog prolaza je najvea vrednost (9), dola
na svoje mesto na poetak niza. Nakon drugog prolaza je druga najvea vrednost (8) dola na drugu poziciju. Ovo se
nastavlja sve dok se niz ne porea.
Primetiete da je posle etvrtog prolaza niz ve sortiran, ali se algoritam nastavlja. Razlog je taj to u je u najgorem
scenariju potrebno N-1 prolaz, za sortiranje N vrednosti. Ovo moete proveriti na primeru niza koji je ve ureen po
rastuim vrednostima (A[9] = 9, A[8] = 8 itd).
Da pogledamo sada kako izgleda algoritam. Poeemo sa najoptijom verzijom:

BubleSort(A, veliina)
for prolaz+1 do veliina-1 po 1
najveu vrednost vadi na vrh
Kraj
Sada treba da razloimo akciju u petlji. Tu treba da proemo kroz parove susednih vrednosti, da ih uporedimo i zamenimo
im mesta ako je potrebno. Sledea verzija izgleda ovako:

14

BubleSort(A, veliina)
for prolaz=1 do veliina-1 po 1
for indeks=veliina-1 do po -1
Poredi susedne vrednosti i menja im mesta ako je potrebno
Kraj
Kompletan algoritam dobijamo specifikacijom detalja poreenja i zamene.

BubleSort(A, veliina)
for prolaz=1 do veliina-1 po 1
for indeks=veliina-1 do po -1
if A[indeks] < A[indeks+1)
zameni A[indeks] i A[indeks+1]
Kraj

Analiza algoritma
Iz koda koji smo napravili moe se videti da ovaj algoritam zahteva (N-1) prolaza (u naem sluaju 8). U svakom od tih
prolaza se deava ukupno (N-1) poreenja, to je ukupno (N-1) x (N-1) poreenja. U naem primeru imamo 9 elemenata
koje elimo da sortiramo to znai da je potrebno 64 poreenja. Ve sada je ovaj algoritm bolji od prethodnog sa
prebrojavanjem, ali se on moe dodatno poboljati.
Postoji vie naina da se pobolja ovaj algoritam. Najlake poboljanje se moe dobiti ako se primeti da svaki prolaz moe
biti krai za jedno poreenje. Razlog je to je na kraju svakog prolaza jedan element postavljen na svoju finalnu poziciju,
tako da ga vie ne treba uzimati u obzir. To znai da emo u prvom prolazu i dalje imati 8 poreenja, ali nam zato u prolazu
2 treba samo sedam poreenja, poto je jedan element (9) ve na svojoj finalnoj poziciji. U treem prolazu nam treba est
poreenja itd. Ukupan broj poreenja u ovom primeru je:

C = (8 + 7 + 6 + 5 + 4 + 3 + 2 + 1) = 36
to je manje od polovine poreenja u prethodnom algoritmu sa prebrojavanjem.
Sada moemo generalizovati rezultat za N vrednosti. Broj poreenja za poboljani algoritam sa zamenom je:

C = ( N 1) + ( N 2) + (N 3)++3 + 2 + 1
ili

C=

N ( N 1)
2

Da uporedimo sada novi poboljani algoritam sa zamenom i prethodni sa prebrojavanjem. Kod sortiranja sa prebrojavanjem
je bilo potrebno N2 poreenja. Kod poboljanog algoritma sa zamenom je potrebno N(N-1)/2 poreenja.
Ako sortiramo velike nizove, gde je N veoma vliki broj, moemo da primetimo sledee:

Sortiranje sa prebrojavanjem trai N2 poreenja.

Poboljani algoritam sa zamenom trai polovinu poreenja.

U skladu sa ovim moemo rei da je sortiranje sa zamenom skoro dva puta bre od sortiranja sa prebrojavanjem, ali da oba
sortiranja pripadaju kvadratnim algoritmima.

Sortiranje sa selekcijom
Ovaj algoritam se zasniva na izboru ekstremnih vrednosti, bilo da je u pitanju minimalna, bilo maksimalna vrednost.
Algoritam bi, na primer, mogao poeti odreivanjem maksimalne vrednosti u nizu koji se sortira. Ta vrednost se obeleava,
stavlja u drugi niz i brie iz originalnog. Proces se zatim ponavlja na originalnom nizu. Ponovo se bira maksimalna
vrednost, ona se zapisuje i izbacuje. Na taj nain se originalni niz polako prazni, a drugi niz, rezultat, polako puni. Ciklus se
ponavlja sve dok se svih N vrednosti iz niza ne zapiu.

15

Prvi prolaz
Pre
A[i]

Pokazuje kako se pronalazi


maksimum M iz niza A

Posle
A[i]

Posle prvog prolaza


Maksimum
B[i]

Posle
B[i]

Posle prolaza
Gornji deo prethodne slike prikazuje prvi prolaz kroz niz celih brojeva. Prva maksimalna vrednost koja se pronalazi je 9. To
je izlaz i ona se smeta u drugi niz. Njena vrednost se zamenjuje nulom.
U donjem delu slike se vidi rezultujui niz B nakon svakog prolaza. Obratite panju na to da se prvobitni niz A polako
unitava, odnosno postaje niz sa nulama.
U algoritmu emo imati N prolaza kroz glavnu petlju. Svaki prolaz se odnosi na pronalaenje jedne vrednosti.
Pseudo kod u najoptijem sluaju izgleda ovako:

SelectSort(Tabela, Veliina, Rezultat)


for prolaz=1 do veliina po 1
Podesi vrednost za Maksimum
upotrebi Maksimum
eliminii Maksimum
Kraj
Sada moemo da definiemo detalje algoritma. Tokom svakog prolaza se pronalazi maksimalna vrednost, ona se smeta u
drugi niz i onda eliminie iz originalnog niza.

16

SelectSort(Tabela, Veliina, Rezultat)


for prolaz=1 do veliina po 1
Podesi Maksimum na 0
for indeks=1 do veliina po 1
Uporedi Maksimum i Tabela[indeks]
Auriraj Maksimum i Poziciju ako je potrebno
podesi Rezultat[prolaz] na Maksimum
Podesi Tabela[pozicija] na 0
Kraj

Pronalaenje
maksimuma u A

Sada moemo da napravimo zavrni oblik algoritma. Promenljiva maksimum se poredi sa svakom vrednou u nizu i
aurira u skladu sa pozicijom.

SelectSort(Tabela, Veliina, Rezultat)


for prolaz=1 do veliina po 1
Podesi Maksimum na 0
for indeks=1 do Veliina po 1
if Maksimum < Tabela[indeks]
Podesi maksimum na Tabela[indeks]
Podesi poziciju na indeks
podesi Rezultat[prolaz] na Maksimum
Podesi Tabela[pozicija] na 0
Kraj

Pronalaenje
maksimuma u A

Sortiranje sa zamenom koje smo ovde pokazali radi samo sa pozitivnim celim brojevima, poto se izbaene vrednosti
zamenjuju nulom. Ako podaci sadre i negativne vrednosti, morali bismo da modifikujemo algoritam, tako da obrisanim
elementima dodeljuje najmanju negativnu vrednost (iz niza).

Analiza algoritma
Analizom ovog algoritma moemo zakljuiti da postoji N prolaza i da se u svakom prolazu ispituje N elemenata iz tabele. U
skladu sa tim postoji N2 poreenja, to je slino sa prvim algoritmom za sortiranje koji smo radili (sortiranje sa
prebrojavanjem). Kod ove verzije za uvanje sortiranih vrednosti koristi drugi niz, to je reenje koje nije ekonomino u
pogledu memorijskog prostora.
Ovaj algoritam se moe poboljati na nekoliko naina:
Prvo bismo mogli da incijalnu vrednost promenljive maksimum podesimo na prvu vrednost iz niza i tako broj poreenja
smanjima na N-1.
Mogli bismo i da iskombinujemo selekciju sa zamenom, kao to smo pokazali u narednom primeru. Umesto da prvi
pronaeni maksimum smetamo u drugi niz, moemo ga zameniti sa prvim elementom u nizu. Nakon toga se pronalazi
maksimum ostatka niza i menja sa drugim elementom niza. Ovo se nastavlja sve dok se ne sortira ceo niz.
Ovakvo sortiranje se obavlja samo u originalnom nizu. Tokom sortiranja moemo smatrati da je taj niz podeljen na dva
dela. Jedan deo je sortiran i on je inicijalno prazan, a drugi je niz koji nije sortiran. Sortirani deo raste, sve dok ne obuhvati
ceo niz.

Sortiranje sa umetanjem
Kod ovog metoda se takoe jedan po jedan element iz originalnog niza A prebacuje u sortirani niz B. Pri tome se postojei
elementi u sortiranom nizu B pomeraju da bi se napravilo mesto za novi element. Ovo je slino sa reanjem karata u
preferansu ili bridu. Igrai karte najee slau prema bojama i po veliini. Odreena karta se prebacuje na njeno mesto u
nizu, a ostale se pomeraju za po jedno mesto.

17

Peti prolaz
Poetak
B[i]

Kraj
B[i]

posle petog prolaza

prolaz

Kod za ovaj algoritam (u Javi) izgleda ovako:

public void insertionSort(int[]a,int[]b)


{
int in, out;
b[0] = a[0];
for(out=1; out<nElems; out++) {
long temp = a[out];
// proverava se ovaj element
in = out;
// pomeranje poinje od elementa out
while(in>0 && b[in-1] <= temp){ // sve dok je neki manji
b[in] = b[in-1];
// element se pomera udeso
--in;
// ide se jednu poziciju u levo
}
b[in] = temp;
// oznaeni element se ubacuje
}
}

18

Analiza algoritma
U prvom prolazu ovog algoritma se poredi maksimalno jedan element. U drugom prolazu se porede maksimalno dva
elementa itd., sve do maksimalnog broja poreenja N-1 u poslednjem prolazu. Ukupno je to

1 + 2 + 3 + ... + N-1 = N*(N-1)/2


Poto se u svakom prolazu ipak ne porede svi elementi, odnosno nemamo maksimalan broj poreenja, to se moe uzeti
srednja vrednost, odnosno maksimalan broj poreenja se moe podeliti sa 2, to daje:

N*(N-1)/4
Pored poreenja imamo i kopiranje. Broj kopiranja je priblino isti kao broj poreenja. Sa druge strane proces kopiranja ne
uzima toliko vremena kao zamena, tako da je ovaj algoritam bri u odnosu na sortiranje sa zamenom.
U svakom sluaju, kao i prethodni algoritmi za sortiranje i ovaj algoritam pripada klasi kvadratnih algoritama.
Sortiranje sa umetanjem mnogo bolje radi ako su u pitanju podaci koji su ve sortirani ili delimino sortirani. Ako su podaci
ureeni, onda uslov u while petlji nikad nije taan, tako da se sve svodi na spoljanju petlju, koja se izvrava N-1 puta. U
ovom sluaju ovo postaje algoritam sa vremenom izvrenja N. Ako su podaci skoro sortirani, onda je i ovo algoritam sa
vremenom izvrenja skoro N.
Sa druge strane, ako su podaci ureeni po inverznom redosledu, onda se vri svako mogue poreenje i kopiranje, tako da se
ovaj algoritam izvrava slino kao prethodni.
Iz ove analize se moe zakljuiti da sortiranje sa umetanjem treba koristiti kod problema kod kojih su elementi ve
delimino ureeni.

Algoritam Quicksort (brzo sortiranje)


Ovo je algoritam koji se u praksi verovatno najvie koristi. Osnovni algoritam je 1960 godine razvio Hoare, a od tada je on
doiveo mnoge implementacije i poboljanja. Ovaj algoritam je popularan zato ti nije teak za implementaciju, radi
generalno sortiranje (radi dobro u razliitim situacijama) i zauzima manje resursa nego mnogi drugi metodi sortiranja.
Dobre osobine ovog algoritma su da se sortiranje vri na licu mesta (koristi se samo mali pomoni stek), da zahteva NlogN
operacija. Ovo vreme je srednje vreme potrebno za sortiranje N elemenata.
Nedostaci ovog algoritma su da je rekurzivan (implementacija postaje komplikovana ako se ne moe da koristi rekurzija),
da postoji najgori sluaj kada je potrebno N2 operacija, kao i da je vrlo krhak (mala greka u implementaciji moe ostati
neprimeena i moe dovesti da se u nekim sluajevima algoritam ne ponaa kako treba).
Ovaj algoritam radi na principu podele niza. Niz koji se sortira se deli na dva dela, a onda se svaki deo nezavisno sortira.
Tana podela zavisi od inicijalnog rasporeda elemenata u nizu.
Globalni program izgleda ovako:

static void quicksort(int[] a, int lev, int des){


if (des <= lev) return;
int i = podela(a, lev, des);
quicksort(a, lev, i-1);
quicksort(a, i+1, des);
}
Ako niz ima jedan ili nijedan element ne deava se nita. Ako niz ima vie elemenata, niz se obrauje pomou procedure
podela. Ova procedura postavlja element a[i] na poziciju izmeu lev i des (ukljuujui i njih), a ostalim elementima menja
mesta u skladu sa sortiranjem i njihovim vrednostima.
Podela se implementira na sledei nain. Prvo se proizvoljno izabere element a[r], koji e podeliti niz. To je element koji e
se postaviti na svoju krajnju poziciju. Nakon toga se pretrauje niz, poevi od levog kraja sve dok se ne nae element koji
je vei od elementa podele. Niz se pretrauje i sa desne strane sve dok se ne nae element koji je manji od elementa podele.
Elementi koji su zaustavili pretraivanje oigledno nisu na mestima na kojima bi trebalo da se nau u sortiranom nizu. Zbog
toga se njima menjaju mesta. Proces se nastavlja i dalje, ime se osigurava da levo od levog indeksa nema elemenata koji su
manji od elementa podele, a desno od desnog indeksa nema elemenata koji su vei od elementa podele.
Ovo se moe predstaviti sledeim dijagramom:

19

vee ili jednako v

manje ili jednako v

Na dijagramu v predstavlja vrednost elementa podele, i je levi indeks, a j je desni indeks. Kao to se vidi sa dijagrama,
najbolje je pretravanej zaustaviti kada su elementi vei ili jednaki ili manji ili jdenaki vrednosti v. Kada se indeksi i i j
ukrste, pretraivanje se prekida, a a[r] menja mesto sa krajnjim levim elementom desnog dela (element na koji ukazuje levi
indeks i).
Procedura podele izgleda ovako:

private static int podela(int[] a, int lev, int des) {


int i = lev - 1;
int j = des;
while(true) {
while (a[++i] > a[des]) // trazi se element sa leve strane
//kojem se menja mesto
;
// a[des] je uslov petlje
while (a[des] > a[--j])
trazi se element sa desne strane
//kojem se menja mesto
if (j == lev) break;
// ne prelaziti granice
if (i >= j) break;
// provera da li se indeksi ukrtaju
int swap = a[i];
a[i] = a[j];
a[j] = swap;

// dva elementa menjaju mesta

}
int swap = a[i];
a[i] = a[des]; // element podele menja mesto
a[des] = swap;
return i;
}
Prva while petlja je implementirana kao beskonana petlja. Izlaz iz ove petlje se ostvaruje preko iskaza break, koji se poziva
ako su se indeksi ukrstili. Promenljiva i slui za brojanje sa leve strane i prva unutranja while petlja trai prvu manju
vrednost od poetka. Promenljiva j slui za brojanje sa desne strane, a druga unutranja while petlja trai prvu veu vrednost
od kraja. U svakom prolazu se pronaenim elementima menjaju mesta.
Kada se indeksi ukrste podela se zavrava zamenom elementa koji je sluio za podelu sa krajnjim levim elementom, desnog
dela (menjaju mesta a[des] i a[i]).

Analiza algoritma
Osnovni quicksort algoritam ima ograniene mogunosti. Za neka sortiranja koja se mogu javiti u praksi on moe postati
prilino neefikasan. Na primer, ako se primeni na niz veliine N, koji je ve sortiran, onda e se desiti N poziva programa,
pri emu se u svakom prolazu brie samo po jedan element.
Ovaj algoritam u najgorem sluaju koristi N2/2 poreenja. To je sluaj kada je niz ve sortiran. Ovakvo ponaanje znai da
ovaj algoritam ne samo da trai vie vremena u ovom sluaju, ve raste i memorijski prostor potreban za rukovanje
rekurzijom, to kod velikih nizova moe biti problem.
Najbolji sluaj kod ovog algoritma je kada svaka faza podele podeli niz tano na pola. Na taj nain bi se dobio broj
poreenja od priblino N log N.
Generalno se moe rei da u najveem broju sluajeva algoritam quicksort koristi 2 N log N poreenja.

20

You might also like