You are on page 1of 265

UNIVERZITET SINGIDUNUM

Dejan ivkovi

U VOD U ALGOR IT ME I
S T RUKT URE P ODATAK A

Prvo izdanje

Beograd, 2010.

UVOD U ALGIORITME I STRUKTURE PODATAKA

Autor:
Prof. dr Dejan ivkovi
Recenzent:
Prof. dr Dragan Cvetkovi
Izdava:
UNIVERZITET SINGIDUNUM
Beograd, Danijelova 32
www.singidunum.ac.rs

Za izdavaa:
Prof. dr Milovan Stanii
Tehnika obrada:
Dejan ivkovi
Dizajn korica:
Dragan Cvetkovi
Godina izdanja:
2010.

Tira:
240 primeraka
tampa:
Mladost Grup
Loznica
ISBN: 978-86-7912-239-1

Predgovor

Oblast algoritama i struktura podataka potvrdila je svoje mesto u ra


cunarstvu zbog prakti ne vanosti i teorijske elegancije. Sa jedne strane,
c
prakti ari mogu da neposredno koriste dobre algoritme i ekasne strukc
ture podataka u sloenim programskim projektima. Sa druge strane, za
istraiva e su algoritmi vaan alat kojim se meri stepen sloenosti nekog
c
ra unarskog problema. Algoritmi i strukture podataka se nalaze u centru
c
svih metodologija koje se koriste u radu sa savremenim ra unarima. Mada
c
na prvi pogled moda tako ne izgleda, neka napredna metodologija sigurno
se temelji na sosticiranim algoritmima i strukturama podataka.

Cilj ove knjige je da citaocima predstavi osnove ove fascinantne oblasti


ra unarstva. Radi toga se u knjizi prevashodno razmatraju neke od najoc
snovnijih metoda i paradigmi za dizajniranje i analiziranje struktura podataka i algoritama. Pri tome je pokuano da se naglasak stavi na idejama
i lakem razumevanju koncepata, a ne na implementacionim detaljima.
Ova knjiga je primarno zamiljena kao fakultetski udbenik za prvo
upoznavanje sa algoritmima i strukturama podataka na prvoj ili drugoj
godini studija ra unarstva. Razumevanje materijala iz knjige zahteva bac

zi no predznanje iz ra unarstva i matematike. Konkretnije, od citalaca


c
c
se o ekuje da imaju iskustva u pisanju programa na nekom programskom
c

jeziku vieg nivoa kao to su Pascal, C ili Java. Pretpostavlja se i da citaoci


poznaju osnovne matemati ke koncepte u koje spadaju skupovi, funkcije i
c
indukcija.
U knjizi se nalazi preko 150 slika i tabela koje slue za ilustraciju
materijala. Algoritmi u tekstu su navedeni na jednostavnom pseudo jeziku

tako da citaoci ne moraju da u i novi programski jezik da bi razumeli


c
kako algoritmi rade. Dodatno, na kraju svakog poglavlja se nalazi vie

zadataka cija teina ide u rasponu od prostih vebi za utvrdivanje izloenog

materijala pa do kreativnih problema. Ovi zadaci se smatraju integralnim

delom knjige i citaoci treba bar da pokuaju da ih ree.

ii

Predgovor

Zahvalnost. Najdublju zahvalnost dugujem svima koji su mi pomogli u


pripremi ove knjige. Zahvaljujem se mnogim kolegama i studentima koji
su koristili radne verzije knjige i odgovorili na moj zahtev da predloe neka
poboljanja i otkriju neizbene greke.

Na kraju, bio bih veoma zahvalan citaocima na njihovom miljenju o


knjizi. Svi komentari i pronadene greke mogu se poslati elektronskom

potom na adresu dzivkovic@singidunum.ac.rs.

D EJAN IVKOVI C
Beograd, Srbija
januar 2010.

Sadraj

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

1
2
4
8
10
15

Dizajn i analiza algoritama


2.1 Dizajn algoritama . . . . .
2.2 Analiza algoritama . . . .
2.3 Primeri algoritama . . . .
Zadaci . . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

17
18
21
28
40

Vreme izvravanja algoritma


3.1 Asimptotsko vreme izvravanja . . . . . . . . . . . . . . . . . .
3.2 Asimptotska notacija . . . . . . . . . . . . . . . . . . . . . . . .
Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

43
43
54
66

Osnovne strukture podataka


4.1 Opte napomene . . . . . . .
4.2 Nizovi . . . . . . . . . . . . .
4.3 Liste . . . . . . . . . . . . . .
4.4 Stekovi . . . . . . . . . . . .

4.5 Redovi za cekanje . . . . . .


Zadaci . . . . . . . . . . . . . . . .

Uvod
1.1 Podaci . . . . . . .
1.2 Algoritmi . . . . .
1.3 Ra unarski model
c
1.4 Zapis algoritama .
Zadaci . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

71
. 71
. 73
. 88
. 96
. 98
. 101

Rekurzivni algoritmi
5.1 Iterativni i rekurzivni algoritmi
5.2 Analiza rekurzivnih algoritama .
5.3 Rekurentne jedna ine . . . . . . .
c
Zadaci . . . . . . . . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

107
108
116
128
140

iv
6

Sadraj
Stabla
6.1 Korenska stabla . . . . .
6.2 Binarna stabla . . . . . .
6.3 Binarna stabla pretrage
6.4 Binarni hipovi . . . . . .
6.5 Primene stabala . . . . .
Zadaci . . . . . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

145
145
151
155
165
174
181

Grafovi
7.1 Osnovni pojmovi i denicije
7.2 Predstavljanje grafova . . .
7.3 Obilazak grafa . . . . . . . .
7.4 Obilazak usmerenog grafa .
Zadaci . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

185
186
191
194
209
218

Teinski grafovi
8.1 Osnovni pojmovi . . . . . . . . . . . .
8.2 Minimalno povezuju e stablo . . . .
c

8.3 Najkra i putevi od jednog cvora . . .


c

8.4 Najkra i putevi izmedu svih cvorova


c

Zadaci . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

223
224
225
236
243
247

.
.
.
.
.
.

Literatura

251

Indeks

253

G LAVA

1
Uvod

Fundamentalni predmet izu avanja u ra unarstvu su strukture podac


c

taka i algoritmi koji ih obraduju. To je posledica cinjenice to, pojednosta


vljeno re eno, rad ve ine ra unarskih sistema svodi se u sutini na smetac
c
c
nje podataka u memoriji ra unara i manipulisanje podacima iz memorije
c
bitnim za konkretan domen primene. Zbog toga u primenjenim oblastima
ra unarstva, medu koje spadaju operativni sistemi, baze podataka, ra uc
c

narska graka, veta ka inteligencija i druge, izu avaju se zapravo pitanja


c
c
ekasnog smetanja podataka i njihovog manipulisanja koja su vana za
odgovaraju u oblast primene ra unara.
c
c
U ovoj knjizi medutim, smetanje podataka i njihovo manipulisanje

posmatra se iz vrlo opteg ugla, uglavnom bez neke konkretne interpretacije podataka na umu. U najoptijem smislu, termin struktura podataka
koristi se za na in organizacije odredenih podataka u programu, a termin
c

algoritam za postupak obrade podataka. Strukture podataka i algoritmi su


medusobno tesno povezani gradivni elementi od kojih se sastoje program
ski sistemi. Zato se ti delovi obi no zajedni ki predstavljaju u literaturi sa
c
c
ve im ili manjim naglaskom na jedan od njih.
c
U uvodnom poglavlju se podrobnije deniu koncepti strukture podataka i algoritma, kao i model ra unara i jezik koji slue za njihovo interc
pretiranje i izraavanje.

Uvod

1.1 Podaci
Manipulisanje podacima je glavna svrha rada softverskih sistema i zato
je neophodno na samom po etku razjasniti sam pojam podataka. U stvari,
c

u ovom kontekstu se cesto koriste termini tip podataka (ili samo kratko
tip), apstraktni tip podataka i struktura podataka, koji sli no zvu e i
c
c
zato je korisno ukazati na njihove speci nosti.
c
Pod tipom podataka se podrazumeva skup nekih vrednosti zajedno sa
skupom operacija koje su dozvoljene nad tim vrednostima. Tako logi ki tip
c
true i false, a dozvoljene operacije
podataka sadri samo dve vrednosti
nad njima su uobi ajene logi ke operacije negacije, konjunkcije, disjunkcije
c
c
i tako dalje. Sli no, tip podataka pod imenom string sadri vrednosti koje
c
predstavljaju niske znakova, a dozvoljene operacije nad njima su spajanje
dve niske, odredivanje duina jedne niske, poredenje dve niske i tako dalje.

Svaki programski jezik obezbeduje neke primitivne tipove podataka

cije vrednosti imaju atomi nu prirodu, odnosno ne sastoje se od manjih


c
delova. Ovi ugradeni tipovi podataka se razlikuju od jezika do jezika, ali

ve ina njih obezbeduje celobrojni, realni, logi ki i znakovni tip podataka.


c
c

Svaki programski jezik sadri i pravila za konstruisanje sloenih tipova


podataka polaze i od primitivnih, koji se takode razlikuju od jezika do
c

jezika.
Apstraktni tipovi podataka su generalizacije primitivnih tipova podataka i rezultat su primene vanog nau nog principa apstrakcije u ra uc
c
narstvu. Naime, iskustvo je pokazalo da se uspena i ekasna realizacija
svakog softverskog sistema kojim se reava sloeni problem ne moe sprovesti bez podele takvog problema na manje celine koje se mogu nezavisno
reavati. Ali ni ova dekompozicija sloenog problema nije dovoljna, ve
c
se za reavanje manjih problema moraju zanemariti mnogobrojni nevani
detalji koji ne uti u na celokupno reenje. Ovim pristupom apstrakcije
c
problema se znatno smanjuje sloenost razvoja i odravanja velikih softverskih sistema.
Apstrakcija problema obi no ima dva aspekta: proceduralnu apstrakc
ciju i apstrakciju podataka. Proceduralnom apstrakcijom se obezbeduje

razdvajanje onoga to neki modul radi od programskog na ina na koji se ta


c
funkcionalnost postie. Apstrakcijom podataka se obezbeduje razdvajanje

logi ke slike informacija koje se obraduju od njihove zi ke realizacije u


c
c

ra unaru. Apstrakcija problema omogu ava dakle postupan pristup rec


c
avanju sloenog problema, jer se softverski sistem moe izgraditi deo po

1.1. Podaci

deo zanemarivanjem mnogih implementacionih detalja o kojma se ne mora


voditi ra una.
c
Apstrakcija podataka podrazumeva logi ki opis kako kolekcije podac
taka tako i operacija koje se mogu primeniti nad tim podacima. Apstrakcija
podataka omogu ava programeru da se skocentrie samo na to kako se
c
podaci koriste radi reenja konkretnog problema. To je zna ajno olakanje,
c
jer programer ne mora da se istovremeno bavi na inom predstavljanja i
c
manipulisanja tih podataka u memoriji.
Denisanje logi kog modela podataka i njegova realizacija na ra unaru
c
c
obuhvata slede e elemente:
c
(1) na in na koji su entiteti problema modelirani kao apstraktni matec
mati ki objekti;
c
(2) skup dozvoljenih operacija koji je denisan nad ovim matemati kim
c
objektima;
(3) na in na koji su ovi matemati ki objekti predstavljeni u memoriji
c
c
ra unara;
c
(4) algoritme koji se koriste za programsku realizaciju dozvoljenih operacija nad ovim matemati kim objektima.
c
Obratite panju na to da su (1) i (2) matemati ki elementi koji odreduju
c

prirodu podataka za dati problem, odnosno ta su sutinski podaci i kako


se obraduju. S druge strane, (3) i (4) su programski elementi koji odreduju

kako su ti podaci implementirani u ra unaru. Pojam apstraktnog tipa


c
podataka (ili ATP) obuhvata elemente (1) i (2), odnosno odreduje domen

matemati ki denisanih objekata i skupa operacija koje se mogu primeniti


c
na objekte iz tog domena. S druge strane, pojam strukture podataka sadri
elemente (3) i (4) kojima se odreduje kako su ovi apstraktni matemati ki
c

objekti programski implementirani u ra unaru. Prema tome, za razliku od


c
struktura podataka, apstraktni tipovi podataka su nezavisni od implemen
tacije, pa cak i od programskog jezika.
Na primer, razmotrimo program za simuliranje rada nekog restorana.
Ako restoran na meniju ima jelo ranji e, onda bi jedan od modula proc
grama verovatno morao da simulira stavljanje komada mesa na icu ranji a za posluivanje gosta i skidanje komada mesa sa ice prilikom konc
zumiranja. Stavljanje komada mesa na icu ranji a i njihovo skidanje sa
c
ice moe se opisati apstraktnim modelom koji se naziva stek.
c
Stek je apstraktni tip podataka koji ima samo jednu pristupnu ta ku
vrh steka. Pri tome, novi podaci se uvek dodaju na vrh steka, a stari podaci

Uvod

u steku se mogu dobiti i skinuti samo sa vrha steka. Ako komade mesa
apstrahujemo kao podatke i icu ranji a kao stek, primetimo da postupak
c
rada sa podacima u steku ta no odgovara na inu na koji se postupa sa
c
c
komadima mesa na ici ranji a: dodaju se na vrh ice i odatle se skidaju.
c
Naravno, stek kao logi ki model podataka nije karakteristi an samo za
c
c
banalan primer ranji a, pa vanost steka proizilazi iz toga to se moe
c
prepoznati u mnogim drugim primenama.
S druge strane, stek kao struktura podataka posmatra se sa stanovita
programske realizacije njegove apstraktne organizacije podataka. Pitanja
na koja treba odgovoriti u tom slu aju su, recimo, da li je stek bolje realizoc
vati pomo u niza ili povezane liste, kolika je ekasnost operacija dodavanja
c
i uklanjanja podataka iz steka u pojedinim slu ajevima i tako dalje.
c
Apstraktni tip podataka denie interfejs izmedu programera i poda
taka i zaokruuje neki model podataka u smislu da je implementacija tog
modela lokalizovana u jednom delu programa. To je od velike prakti ne
c
vanosti, jer ako elimo da promenimo realizaciju odgovaraju e strukture
c
podataka, najpre znamo gde to treba u initi. Takode znamo da ako promec

nimo jedan mali deo programa, time ne emo izazvati teko uo ljive greke
c
c
u nekom drugom delu koji nema veze sa odgovaraju im tipom podataka.
c
Na kraju, sa podacima apstraktnog tipa moemo raditi kao da su primitivnog tipa i ne obra ati panju na njihovu konkretnu realizaciju.
c
Apstraktni tipovi podataka imaju dva poeljna svojstva, generalizaciju
i enkapsulaciju, koje nam omogu avaju da ispunimo vaan cilj softverskog
c
inenjerstva viekratnu upotrebljivost. Naime, poto implementiramo
apstraktni tip podataka, moemo ga koristiti u razli itim programima.
c
Moemo dakle zaklju iti da podaci u ra unarstvu imaju dva pojavna
c
c
oblika: logi ki i zi ki. Njihov logi ki oblik se odreduje denicijom apc
c
c

straktnog tipa podataka, dok se zi ki oblik dobija implementacijom odgoc


varaju e strukture podataka. Ovo zapaanje je ilustrovano na slici 1.1.
c

1.2 Algoritmi
Spomenuli smo da su algoritmi u tesnoj vezi sa strukturama podataka
i da se koriste za programsku realizaciju dozvoljenih operacija nekog apstraktnog tipa podataka. To je ipak samo jedna speci na primena alc
goritama, a da bismo ih posmatrali optije, moramo po i od ra unarskih
c
c
problema koje algoritmi reavaju.

1.2. Algoritmi

Tip podataka
ATP:
skup podataka

skup operacija

Struktura podataka:

logi ka forma
c

memorijska reprezentacija
algoritamska reprezentacija

zi ka forma
c

c
c
S LIKA 1.1: Logi ka i zi ka forma podataka.

Pod (ra unarskim) problemom se podrazumeva zadatak koji treba izc


vriti na ra unaru. Takav zadatak se opisuje preciznom specikacijom
c
eljenog ulazno-izlaznog odnosa kojim se izraava priroda problema. Na
primer, problem sortiranja niza brojeva moe se opisati na slede i na in:
c
c
ulaz je niz brojeva u proizvoljnom redosledu, a izlaz je niz istih brojeva koji
su preuredeni tako da se pojavljuju u rastu em redosledu od najmanjeg
c

do najve eg. Jo jedan primer je problem vra anja kusura: ulaz je neki
c
c
nov ani iznos i apoeni metalnih nov i a, a izlaz je najmanji broj tih nov i a
c
cc
cc
kojima se dati iznos moe potpuno usitniti.
Kod mnogih problema nije dovoljno na ovaj neformalan na in denisati
c
njihov ulazno-izlazni odnos koji se trai. Na primer, kod problema sortiranja kako smo ga naveli, nije jasno da li neki brojevi u ulaznom nizu mogu
biti jednaki i kako onda jednaki brojevi treba da budu poredani u izlaznom

nizu. Zato se u optem slu aju koristi formalniji, matemati ki aparat, o


c
c
kome govorimo u nastavku, kako bi se otklonila svaka dvosmislenost. Iako
taj na in ne emo posebno naglaavati u ovoj knjizi, jer se koristi opiran
c
c
prikaz svakog problema, treba znati da je u praksi to dominantan na in
c
zbog svoje konciznosti i preciznosti.
Formalno, ra unarski problem se zadaje ulaznim parametrima i odc

govaraju im izlaznim parametrima, pri cemu obe vrste parametara zac


dovoljavaju odredene uslove kojima se denie sm problem. Instanca

Uvod

problema se sastoji od valjanih konkretnih vrednosti za ulazne parametre


problema, a reenje instance problema se sastoji od odgovaraju ih vrednosti
c
izlaznih parametara za date ulazne vrednosti. Na primer, jedna instanca
problema sortiranja je niz [23, 17, 8, 20, 15], a reenje te instance je niz
[8, 15, 17, 20, 23].
Standardni format za denisanje problema se sastoji od dva dela koji
odreduju njegove ulazne i izlazne parametre. Oba dela se izraavaju po
mo u pogodnih matemati kih objekata, kao to su brojevi, skupovi, funkc
c

cije i tako dalje, pri cemu ulazni deo predstavlja generi ku instancu proc
blema i izlazni deo predstavlja generi ko reenje ove generi ke instance
c
c
problema. Na primer, problem vra anja kusura moemo formalno denic
sati u obliku u kojem se trai da bude zadovoljen ovaj ulazno-izlazni odnos:
Ulaz: Pozitivan ceo broj k (broj metalnih nov i a), niz od k pozitivnih
cc
c
cc
celih brojeva [c 1, . . ., c k ] (pojednina ni apoeni nov i a) i pozitivan
ceo broj a (nov ani iznos).
c
c
Izlaz: Niz od k nenegativnih celih brojeva [b 1 , . . ., b k ] (pojednina ni brojevi nov i a sitnine) tako da su zadovoljena dva uslova:
cc
1. a =
2.

k
i =1 b i c i

k
i =1 b i

(sitnina je ispravna za dati nov ani iznos), i


c

je minimalno (zbir nov i a sitnine je najmanji).


cc

Jedna instanca problema vra anja kusura je specikacija konkretnih


c
vrednosti za ulazne parametre ovog problema, odnosno za broj k, za niz od

k elemenata i za broj a. Na primer, k = 4, niz [1, 5, 10, 25] od cetiri elementa


c
i a = 17 predstavljaju jednu instancu problema vra anja kusura. Reenje

ove instance problema vra anja kusura je niz [2, 1, 1, 0] od cetiri elementa,
c
jer je 17 = 2 1 + 1 5 + 1 10 + 0 25 i zbir 2 + 1 + 1 + 0 = 4 odreduje najmanji

mogu i broj nov i a datih apoena za usitnjavanje iznosa od 17 nov anih


c
cc
c
jedinica.
Sada kada znamo ta su ra unarski problemi moemo preciznije goc
voriti o algoritmima, jer oni reavaju te probleme. Pre svega, algoritam
je ta no denisana ra unarska procedura koja pretpostavlja neke podatke
c
c
kao ulaz i proizvodi neke podatke kao izlaz. Ovo prvenstveno zna i da se
c
algoritam sastoji od jasne i nedvosmislene specikacije niza koraka koji se
mogu mehani ki izvriti na ra unaru (slika 1.2).
c
c
Za dobru intuitivnu sliku algoritma moe posluiti analogija sa kuhinjskim receptom za neko jelo: ba kao to se kuhinjski recept sastoji
od niza prostijih koraka koje izvrava kuvar, tako se algoritam sastoji od
niza ra unarskih koraka koje izvrava ra unar. Ulazni podaci za recept su
c
c

1.2. Algoritmi

potrebni sastojci za kuvanje, a dobijeni izlaz posle izvravanja recepta je


spremljeno jelo.

Algoritam

ulaz

algoritamski
koraci

izlaz
S LIKA 1.2: Pojednostavljena slika algoritma.
Drugo, algoritam reava neki problem ukoliko se na ulazu algoritma
pretpostavlja ulaz tog problema i na izlazu algoritma se dobija reenje tog
problema za svaku instancu problema. Na primer, algoritam koji reava
problem sortiranja na ulazu dobija neureden niz brojeva i kao rezultat na

izlazu proizvodi niz istih brojeva u rastu em redosledu.


c
Algoritam za neki problem je dakle precizno naveden niz instrukcija
koje ra unar treba da izvri radi reavanja tog problema, odnosno radi
c
transformisanja svake instance problema u njeno reenje. Naravno, jedan
problem moe imati vie algoritama koji ga reavaju.
Na osnovu svega do sada re enog moemo sumirati glavne odlike svac
kog algoritma:
Algoritam mora biti postupak koji se sastoji od kona no mnogo koc
raka koji se mogu izvriti na ra unaru.
c
Algoritam mora biti postupak po kojem je nedvosmisleno odreden

svaki slede i korak za izvravanje.


c
Algoritam mora biti ispravan (korektan) postupak. To prvenstveno
zna i da se za svaku instancu problema na ulazu algoritma mora
c
dobiti njeno odgovaraju e reenje na izlazu algoritma. Ali to obuc
emo podrazumevati da je ispunjen, da za ulaz
hvata i uslov, koji c
algoritma koji nije instanca problema, izlaz algoritma nije bitan, ali
se izvravanje algoritma mora zavriti u svakom slu aju.
c

Uvod

Kreativni proces pisanja algoritama kojim se dolazi do nedvosmislenih


instrukcija od kojih se sastoji jedan algoritam naziva se dizajn algoritma.

Za ovaj proces ne postoji carobna formula koja se moe primeniti u optem


slu aju, ve se od dizajnera sloenog algoritma zahteva i doza lucidnosti.
c
c
Ipak, postoje standardni metodi koje moemo koristiti da bismo algoritamski reili mnoge tipove problema. Tu spadaju algoritamske paradigme
kao to su rekurzivni algoritmi, pohlepni algoritmi, algoritmi dinami kog
c
programiranja, randomizirani algoritmi i tako dalje.
U postupku analize algoritma se kvantitativno odreduje upotreba ra

cunarskih resursa nekog algoritma. Najskuplji resursi koje obi no elimo


c
da minimizujemo su vreme izvravanja i memorijski zahtevi nekog algoritma, i prema tome govorimo o njegovoj vremenskoj i memorijskoj sloenosti. Ovde treba obratiti panju na to da mera veli ine resursa koje
c
neki algoritam koristi umnogome zavisi od modela ra unara na kojem se
c
algoritam izvrava. U ovoj knjizi se kre emo isklju ivo u granicama modela
c
c
sekvencijalnih maina modeli paralelnih ra unara i paralelni algoritmi
c
zasluuju posebnu knjigu.

1.3 Racunarski model


Ono to je ostalo nedore eno iz prethodne diskusije o algoritmima jesu
c

ra unarske instrukcije (ili koraci) koje cine algoritam. Iako je to, nadamo
c

se, intuitivno jasno citaocima koji imaju programersko iskustvo, radi ve e


c
jasno e potrebno je ipak neto vie re i o tome koje nam instrukcije ta no
c
c
c
stoje na raspolaganju kada piemo neki algoritam. Drugim re ima, poc
trebno je malo detaljnije opisati model ra unara na kojem se izvravaju
c
algoritmi o kojima smo govorili u prethodnom odeljku.
Uopteno govore i, ra unarski modeli su pojednostavljeni opisi stvarc
c
nih ra unara kojima se zanemaruje njihova puna sloenost, osim nekoliko
c
svojstava za koje se smatra da najbolje odslikavaju fenomen koji se izu ava.
c
Poto je merenje ra unarskih resursa (vreme i prostor) koje algoritmi koric
ste jedan od predmeta naeg izu avanja, to zna i da najpre treba precizno
c
c
formulisati model ra unarske maine na kojoj se algoritmi izvravaju i dec
nisati primitivne operacije koje se koriste prilikom izvravanja. Medutim,

ne emo i i u toliko detalja za opis formalnog ra unarskog modela, ve cemo


c
c
c
c
u nastavku samo neformalno opisati glavne odlike ra unarskog modela sa
c

kojim radimo. To je dovoljno za nau svrhu, jer ce nas interesovati asimptotske performanse algoritama, odnosno njihova ekasnost za veliki broj


1.3. Racunarski model

ulaznih podataka. Pored toga, ta ni ra unarski modeli su zaista potrebni


c
c
za dokazivanje donjih granica sloenosti algoritama. Poto se time ne emo
c
baviti u ovoj knjizi, nema potrebe da komplikujemo izlaganje nepotrebnim
detaljima.
Osnovna pretpostavka je da koristimo ra unarski model koji predstac
vlja idealizovan realan ra unar sa jednim procesorom. Ne postavljamo
c
nikakvu gornju granicu na veli inu memorije takvog ra unara, ali pretpoc
c
stavljamo da programi koji se na njemu izvravaju ne mogu da modikuju
sami sebe. Sa druge strane, u ovom modelu ne postoji memorijska hijerarhija, na primer ke ili virtualna memorija, kao kod pravih ra unara.
c
Ta an repertoar instrukcija ovog modela ra unara nije posebno bitan,
c
c
pod uslovom da je skup tih instrukcija sli an onom koji se moe na i kod
c
c
pravih ra unara. Zato pretpostavljamo da postoje aritmeti ke operacije (za
c
c
sabiranje, oduzimanje, mnoenje, deljenje, deljenje sa ostatkom, celobrojni
deo broja), logi ke operacije (i, ili, negacija), ulazno-izlazne operacije ( itac
c
nje, pisanje), operacije za premetanje podataka (kopiranje iz memorije u
procesor i obratno), operacije za pomeranje bitova podataka levo ili desno
za mali broj pozicija, kao i upravlja ke operacije (za uslovno i bezuslovno
c
grananje, poziv i povratak iz potprocedure). Ove operacije rade nad svojim

operandima koji su smeteni u memorijskim re ima cije se adrese odreduju


c

kori enjem direktnih ili indirektnih ema adresiranja.


c
Model ra unara koji se koristi je generi ki jednoprocesorski ra unar sa
c
c
c
proizvoljnim pristupom memoriji. Ova maina se popularno naziva RAM
(skra enica od engl. random-access machine) i rad sa njom je vrlo sli an
c
c
radu sa pravim ra unarima na mainskom jeziku. Drugim re ima, podrac
c

zumeva se da ce algoritmi biti realizovani u obliku mainskih programa


koji se izvravaju na RAM-u.
Osnovni podaci kojima se manipulie u RAM-u su brojevi celobrojnog
tipa i oni sa pokretnim zarezom. Dodatno pretpostavljamo da postoji gra
nica veli ine memorijske re i tako da brojevi koji se cuvaju u njima ne
c
c
mogu rasti neograni eno. Na primer, ako je veli ina memorijske re i jedc
c
c
naka w bita, tada u naem modelu moemo predstaviti cele brojeve koji
su manji ili jednaki 2w1 po apsolutnoj vrednosti. Brojevi sa pokretnim
zarezom su predstavljeni u standardnom IEEE formatu.
U sekvencijalnom modelu RAM-a se instrukcije izvravaju jedna za
drugom bez paralelizma. Zato pre nego to moemo analizirati sloenost
nekog algoritma, moramo znati i vreme koje je potrebno za izvravanje
svake instrukcije, kao i to koliki memorijski prostor zauzima svaki ope
rand. U tu svrhu cemo koristiti jedini ni model sloenosti, u kojem se svaka
c

10

Uvod

instrukcija izvrava za jednu jedinicu vremena i svaki operand zauzima


jednu jedinicu memorijskog prostora.
Ovaj model je odgovaraju i ako se moe pretpostaviti da se svaki broj
c
koji se pojavljuje u programu moe smestiti u jednu memorijsku re . Ako
c
program izra unava vrlo velike brojeve, koji se ne mogu realisti no uzeti
c
c
kao operandi mainskih instrukcija, a jedini ni model sloenosti se koristi
c
sa nepanjom ili zlom namerom, poznato je da moemo dobiti lanu sliku
o ekasnosti programa. Ali, ako se jedini ni model sloenosti primenjuje u
c
svom duhu (na primer, rad sa velikim brojevima se deli u vie jednostavnijih koraka i ne koriste se nerealisti no mo ne instrukcije), tada je analiza
c
c
sloenosti u ovom modelu umnogome jednostavnija i precizno odraava
eksperimentalne rezultate.
Ukratko, u dizajnu i analizi algoritama i struktura podataka vodimo
se time kako rade pravi ra unari. Naime, naem idealizovanom ra unaru
c
c
ne elimo da damo nerealisti no velike mogu nosti. S druge strane, voleli
c
c
bismo da nam on omogu uje komforan rad bar sa nizovima podataka sa
c

proizvoljnim pristupom, kao i sa osnovnim operacijama ciji su operandi


srednje veliki brojevi.

1.4 Zapis algoritama


Slede e pitanje koje se postavlja u vezi sa algoritmima je notacija koja
c

se koristi za opis postupka koji cini neki algoritam. Da bismo precizno


izrazili korake od kojih se sastoji neki algoritam, moemo koristiti, po redosledu rastu e preciznosti, prirodan jezik, pseudo jezik i pravi programski
c
jezik. Naalost, lako a izraavanja ide u obrnutom redosledu.
c

Algoritamski postupak cesto obuhvata komplikovane ideje, pa bismo


za opis algoritama eleli da koristimo zapis koji je prirodniji i laki za

razumevanje nego to je to odgovaraju i mainski program za RAM, ili cak


c
i ra unarski program na programskom jeziku visokog nivoa. Zbog toga,
c
jedini uslov za zapis algoritama je da specikacija odgovaraju eg postupka
c
obezbeduje precizan niz instrukcija koje ra unar treba da izvri. To zna i
c
c

da, u principu, moemo koristiti obi an jezik za algoritamske korake. Ali


c
u sloenijim slu ajevima, da bismo nedvosmisleno izrazili algoritamske
c
korake, potrebno je ipak koristiti i programske konstrukcije.
Obratite panju na to da pojam algoritma nije isto to i konkretniji
pojam ra unarskog programa. Ra unarski program se izvrava na pravom
c
c

1.4. Zapis algoritama

11

ra unaru, pa se zato pie na nekom programskom jeziku potuju i njec


c
gova striktna pravila. Znamo da su tu vani svako slovo, svaka zapeta
i svaki simbol, tako da nemamo pravo na greku prilikom pisanja ako
ho emo da napisani program izvrimo na ra unaru. Za algoritme nam
c
c
ne treba takav apsolutni formalizam na kraju krajeva, algoritmi se ne
izvravaju na pravim i glupim ra unarima. Algoritmi se mogu zamisliti
c
da se izvravaju na jednoj vrsti idealizovanog ra unara sa neograni enom
c
c
memorijom. Oni su u stvari matemati ki objekti koji se mogu analizirati
c
da bi se prepoznali sutinski delovi sloenih problema. Stoga, vrlo je bitno
da moemo apstrahovati nevane detalje programskog jezika. Jo jedna
razlika izmedu algoritama i pravih programa je da nam kod algoritama

nisu bitna pitanja softverskog inenjerstva. Na primer, da bi se sutina


algoritama prenela to jasnije i jezgrovitije, obrada greaka kod algoritama
se obi no zanemaruje.
c
Algoritmi su obi no mali po veli ini ili se sastoje od kratkih delova
c
c
naredbi proetih tekstom koji objanjava glavne ideje ili naglaava klju ne
c
ta ke. Ovo je uglavnom prvi korak za reavanje problema na ra unaru
c
c
poto sitni, nevani detalji programskih jezika mogu samo da smetaju za
dobijanje prave slike problema. Ovo ne zna i da algoritam sme da sadri
c
bilo kakve dvosmislenosti u vezi sa vrstom naredbi koje treba izvriti ili
sa njihovim ta nim redosledom izvravanja. To samo zna i da moemo biti
c
c
nemarni da li neki znak dolazi ovde ili onde, ako to ne e zbuniti onoga koji
c
pokuava da razume algoritam. Pored toga, neki elementi koji su formalno
neophodni kod ra unarskih programa, na primer, tipovi podataka, obi no
c
c
se podrazumevaju iz konteksta bez navodenja.

Zbog ovih razloga se algoritmi naj e e neformalno izraavaju na psec c


udo jeziku koji sadri elemente kako prirodnog tako i programskog jezika.

U stvari, u ovoj knjizi se cesto obi nim jezikom najpre opisuje glavna ideja
c
algoritma, a zatim se prelazi na pseudo jezik da bi se pojasnili neki klju ni
c
detalji algoritma.
Pseudo jezik koji koristimo u ovoj knjizi za zapis algoritama sadri

elemente programskih jezika C, Pascal i Java, tako da citalac koji je programirao na ovim jezicima ne e imati nikakvih problema da razume napisane
c
algoritme. U tom pseudo jeziku se koriste uobi ajeni koncepti programskih
c
jezika kao to su promenljive, izrazi, uslovi, naredbe i procedure. Ovde ne
cemo pokuavati da damo precizne denicije sintakse i semantike pseudo
jezika koji se koristi u knjizi, poto to nije potrebno za nau svrhu i svakako
prevazilazi namenu ove knjige. Umesto toga, u nastavku navodimo samo
kratak spisak konvencija u kori enom pseudo jeziku:
c

12

Uvod

1. Osnovni tipovi podataka su celi brojevi, realni brojevi sa pokretnim


c
c
zarezom, logi ki tip sa vrednostima true (ta no) i false (neta no), znac
kovi i pokaziva i. Dodatni tipovi podataka kao to su stringovi, liste,
c

redovi za cekanje i grafovi se uvode po potrebi.


2. Promenljive i (sloeni) tipovi podataka se ne deklariu formalno, ve se
c
njihovo zna enje uzima na osnovu njihovog imena ili iz konteksta.
c
3. Komentari se navode iza simbola dve kose crte (//).
4. Naredbe petlje (ciklusa) for-do, while-do i repeat-until, kao i nac
redbe grananja if-then-else i case, imaju uobi ajenu interpretaciju.
Promenljiva broja a u for petlji zadrava svoju vrednost nakon zavrc
etka petlje. Klauzula else u if naredbi nije naravno obavezna.
5. Svaka naredba se zavrava ta kom-zapetom (;). Jedan red algoritma
c
moe sadrati vie kratkih naredbi.
6. Sve promenljive su lokalne za algoritam u kome se koriste. Isto ime za
dve razli ite promenljive se nikad ne koristi. Globalne promenljive su
c
uvek eksplicitno naglaene i koriste se samo kada su potrebne. Podrazumeva se da one postoje u odgovaraju em spoljanjem okruenju.
c
7. Operator dodeljivanja se ozna ava simbolom za jednakost (=). Na pric
mer, izrazom x = e se promenljivoj x dodeljuje vrednost izraza e.
8. Nizovi elemenata su indeksirani od 1 do broja tih elemenata, a rad sa
elementima niza se zapisuje navode i ime niza i indeks eljenog elec
menta u (uglastim) srednjim zagradama. Na primer, a[i] ozna ava i-ti
c
element a i niza a.
9. Logi ki operatori konjunkcije, disjunkcije i negacije se ozna avaju simc
c
c
c
bolima &&, || i !. Logi ki izrazi u kojima u estvuju ovi operatori se
uvek navode sa svim zagradama. Ti izrazi se skra eno izra unavaju
c
c
sleva na desno. To jest, da bi se izra unala vrednost izraza p && q,
c
c
najpre se izra unava p. Ako je vrednost za p jednaka neta no, vrednost
c
c
c
za q se ne izra unava poto vrednost izraza p && q mora biti neta no.
c
c
Sli no, za izraz p || q se izra unava q samo ako je izra unata vrednost
c
c
c
za p jednaka neta no, jer u svim ostalim slu ajevima vrednost izraza p
c
c
c
c
|| q mora biti ta no. Logi ki izrazi koji se izra unavaju na ovaj na in
omogu avaju nam da ispravno koristimo uslove kao to je (i <= n) &&
c

c
c
(a[i] == 0) cak i u slu aju kada indeks i premauje veli inu n niza a.
10. Blokovska struktura sloenih naredbi nazna ava se jedino uvla enjem.
c
c
Ovaj na in isticanja logi ke strukture kratkih algoritama umesto uoc
c
bi ajenih simbola za ograni avanje bloka naredbi (na primer, { i } ili
c
c

begin i end), zapravo doprinosi boljoj citljivosti.

1.4. Zapis algoritama

13

11. Neformalne naredbe sa elementima obi nog jezika koriste se svuda gde
c

takve naredbe cine algoritam razumljivijim od ekvivalentnog niza programskih naredbi. Na primer, naredba
for (svaki vor v grafa G ) do
c

mnogo je izraajnija od njene detaljnije, ali irelevantne programske realizacije.


12. Zaglavlje algoritma po inje slubenom re ju algorithm, a iza nje se
c
c
navodi ime algoritma. Za imena algoritama se koriste engleski nazivi,
jer je to uobi ajeno u stru noj literaturi.
c
c
13. Algoritmi se koriste na dva na ina. Jedan na in je kao funkcija koja daje
c
c
jedan rezultat. U tom slu aju poslednja izvrena naredba u algoritmu
c
mora biti naredba return iza koje sledi neki izraz. Naredba return
dovodi do izra unavanja tog izraza i do kraja izvravanja algoritma.
c
Rezultat algoritma je vrednost izra unatog izraza. Drugi na in koric
c
enja algoritma je kao potprogram. U ovom slu aju naredba return
c
c
nije obavezna, a izvravanje poslednje naredbe ujedno predstavlja kraj
izvravanja algoritma.
14. Algoritam moe komunicirati sa drugim algoritmima pomo u globalnih
c
promenljivih i navodenjem parametara algoritma. Ulazni (ili ulazno/i
zlazni) parametri se piu u zaglavlju algoritma iza imena algoritma u
zagradama, a izlazni parametri se piu iza naredbe return. U pozivu
algoritma se navode stvarni argumenti umesto njegovih parametara
koji se prenose na transparentan na in kojim se ispravno tretiraju forc
malni ulazni, ulazno/izlazni i izlazni parametri algoritma. Argumenti
sloenih tipova podataka se prenose samo po referenci, odnosno pozvani
algoritam dobija pokaziva na stvarni argument.
c
15. Podrazumeva se da je rekurzija omogu ena.
c
Da bismo prakti no ilustrovali neki od ovih elemenata pseudo jezika
c
koji koristimo, u nastavku navodimo algoritme za dva jednostavna problema.

Primer: zamena vrednosti dve promenljive


Za date dve promenljive, problem je zameniti njihove vrednosti tako da
nova vrednost svake promenljive bude stara vrednost druge promenljive.
Ako ne znamo nita o tipu vrednosti datih promenljivih, potrebna nam

je pomo na promenljiva koja slui za privremeno cuvanje stare vrednosti


c

14

Uvod

jedne od promenljivih, pre nego to u tu promenljivu upiemo vrednost


druge promenljive. Na pseudo jeziku se ovaj postupak izraava preciznije
na slede i na in:
c
c
// Ulaz: promenljive x i y sa svojim vrednostima
// Izlaz: promenljive x i y sa zamenjenim vrednostima
algorithm swap(x, y)
z = x;
x = y;
y = z;
return x, y;

Algoritam swap slui prvenstveno za ilustraciju zapisa na pseudo jeziku, jer je njegov postupak za reenje problema zamene vrednosti dve
promenljive o igledan.
c

Primer: najveci element niza


Ako je dat niz a od n neuredenih brojeva a 1, a 2 , . . ., a n , problem je na i
c

indeks (prvog) najve eg elementa tog niza. Prirodno reenje je da po etno


c
c
pretpostavimo da je prvi element niza najve i. Zatim proveravamo sve
c
ostale elemente tako to redom ispitujemo aktuelni element da li je ve i
c
od najve eg elementa nadenog do tada. Ako je to slu aj, taj aktuelni elec
c

ment postaje najve i od onih ispitanih do sada; u suprotnom slu aju, nije
c
c
potrebno nita dodatno uraditi.
// Ulaz: niz a, broj elemenata n niza a
// Izlaz: indeks najveeg elementa niza a
c
algorithm max(a, n)
m = a[1];
j = 1;

// najvei element naen do sada


c
d
// indeks najveeg elementa
c

i = 2;
// proveriti ostale elemente niza
while (i <= n) do
if (m < a[i]) then // naen vei element od privremeno najveeg
d
c
c
m = a[i];
// zapamtiti vei element
c
j = i;
// ... i njegov indeks
i = i + 1; // prei na sledei element niza
c
c
return j;

// vratiti indeks najveeg elementa


c

Primetimo da se postupak algoritma max zasniva na induktivnom rezoc


novanju: ako znamo da je element a j najve i u podnizu a 1 , . . ., a i , da bismo

1.4. Zapis algoritama

15

nali najve i element u podnizu a 1 , . . ., a i , a i+1 duem za jedan element,


c
neophodno je i dovoljno samo uporediti elemente a j i a i+1 . U algoritmu
se upravo ovo radi za i = 1, . . ., n, tako da se na kraju ispravno odreduje

najve i element niza a.


c

Zadaci
1. Problem pretrage niza je:
Ulaz: Broj n, niz a od n neuredenih brojeva a 1 , a 2, . . ., a n , broj x.

Izlaz: Indeks niza k takav da je x = a k ili 0 ukoliko se broj x ne nalazi


u nizu a.
a) Navedite nekoliko instanci problema pretrage i odgovaraju a reec
nja.
b) Napiite iterativni algoritam kojim se broj x trai u nizu a ispitivanjem tog niza od njegovog po etka.
c
2. Problem preostalog dela kredita je:
Ulaz: Ukupan iznos kredita (principal) p, godinja kamatna stopa k
c
(na primer, k = 0.08 ozna ava kamatnu stopu od 8%), iznos mese ne rate za kredit r, broj meseci m.
c
Izlaz: Iznos neotpla enog kredita p m posle m meseci.
c
a) Navedite nekoliko instanci problema preostalog dela kredita i odgovaraju a reenja.
c
b) Napiite iterativni algoritam za izra unavanje p m ukoliko su date
c
vrednosti za p, k, r i m. (Savet: Svakog meseca, iznos kredita se
pove ava usled zara unavanja mese ne kamate i smanjuje usled
c
c
c
otplate mese ne rate. Ako uvedemo oznaku a = 1 + k/12 i stavimo
c
p 0 = p, pokaite da je posle m = 1, 2, . . . meseci preostali deo kredita
p m = a p m1 r.)

G LAVA

2
Dizajn i analiza algoritama

Prilikom pisanja algoritama se mora obratiti posebna panja na njihova dva aspekta: ispravnost i ekasnost. Kod dizajna algoritama se
obra a posebna panja na prvo pitanje ispravnosti (korektnosti) algoric
tama. To je naro ito vano za sloene algoritme kod kojih njihova ispravc
nost nije o igledna, ve zahteva paljiv matemati ki dokaz. Cilj analize
c
c
c
algoritama su kvantitativne ocene ekasnosti algoritama. To je takode

vano pitanje, jer je cak i ispravan algoritam beskorisan ukoliko njegovo


izvravanje traje neprakti no dugo ili zauzima veliku koli inu memorije.
c
c
Ekasnost algoritma je mera veli ine ra unarskih resursa, obi no su
c
c
c
to vreme i memorija, koje algoritam koristi tokom svog izvravanja. Intuitivno, ta veli ina ra unarskih resursa umnogome zavisi od koli ine i
c
c
c
strukture ulaznih podataka za algoritam. Na primer, ako uzmemo analogiju algoritama i kuhinjskih recepata, jasno je da izvravanje recepta za
pravljenje pica zahteva vie vremena i posuda kada se to radi za 10 osoba

nego za dve osobe. Prema tome, da bismo odredili ekasnost algoritma,


treba da odredimo ra unarske resurse koje algoritam koristi tokom izvrac
vanja kao funkciju veli ine ulaza. Sa druge strane, ova funkcija je obi no
c
c
vrlo komplikovana, pa da bismo pojednostavili njenu analizu moemo uzeti
maksimalno mogu e vreme izvravanja (ili memorijsku zauzetost) za sve
c
ulaze algoritma iste veli ine. U knjizi se obi no bavimo ovim ocenama u
c
c

najgorem slu aju, mada cemo na odgovaraju im mestima pominjati i druge


c
c
vidove mere performansi algoritama.
Drugi aspekti dobrih algoritama su takode vani. Tu naro ito spadaju
c

jednostavnost i jasno a. Jednostavni algoritmi su poeljni zato to ih je


c

18

Dizajn i analiza algoritama

lake pretvoriti u ra unarske programe, jer dobijeni programi tada najvec


rovatnije nemaju skrivenih greaka koje se manifestuju tek u proizvodnom
okruenju. Naravno, algoritam je bolji ukoliko je lako razumljiv onome

ko cita njegov opis na pseudo jeziku. Naalost, u praksi ovaj zahtev za

ekasnim i jednostavnim algoritmima je cesto kontradiktoran, pa moramo


prona i balans izmedu njih kada piemo algoritme.
c

U vrlo optim crtama, postupak dobijanja dobrih algoritama za ve inu


c
problema obuhvata ova tri koraka:
1. Najpre se eleminiu svi nevani i remetila ki detalji prakti nog proc
c

blema koji se reava, kako bi se dobio ra unarski problem u to cistic


jem obliku. To obi no zna i da se problem predstavlja u apstraktnim
c
c
terminima prostih matemati kih pojmova kao to su skupovi, funkcije,
c
grafovi i sli no.
c
2. Poto je problem jasno matemati ki denisan, pie se algoritam koji ga
c
reava i dokazuje se njegova ispravnost. Ovo se ve im delom izvodi uz
c
pomo poznatih algoritamskih paradigmi i matemati kih alata.
c
c
3. Na kraju se sprovodi analiza algoritma da bi se ustanovila njegova ekasnost. Pri tome se, poto ocena ekasnosti algoritma moe biti vrlo
komplikovana, primenjuju odredene tehnike kojima se znatno pojedno

stavljuje analiza. O ovome ce biti vie re i u ostalom delu knjige.


c

Naravno, ovi koraci nisu potpuno nezavisni jedan od drugog i cesto


se medusobno prepli u. Isto tako, za prostije probleme nisu potrebni svi
c

koraci ovog postupka u svojoj punoj optosti.

2.1

Dizajn algoritama

Dizajn dobrih algoritama za sloene probleme zahteva od programera


visok stepen obrazovanja, intuicije i iskustva. Vrhunski programeri moraju dobro poznavati, izmedu ostalog, domen problema koji se reava, ra

cunarstvo i matematiku. Cak ni ova svestranost programera ne garantuje


uspeh, jer je dizajn algoritama kreativan proces za koji ne postoji unapred
propisan ablon. Ali sve ovo ipak nije toliko crno, jer se za reavanje razli ic
tih klasa problema mogu primeniti neki standardni metodi koji obezbeduju

dobre algoritme. U ove opte algoritamske paradigme spadaju rekurzivni


metod, pohlepni metod, dinami ko programiranje i randomizacija.
c

Za dobre algoritme ne postoji carobna formula, ali bez obzira na to kako


se dolazi do nekog algoritma, prvi i najvaniji uslov koji dobijeni algoritam

2.1. Dizajn algoritama

19

mora da zadovolji jeste da ispravno reava dati problem. Na putu dokazivanja ispravnosti algoritma postoje mnoge prepreke, kako prakti ne tako i
c

teorijske. to se ti e prakti nih teko a, one su u vezi sa cinjenicom da se


c
c
c
ve ina programa pie tako da zadovoljavaju neke neformalne specikacije,
c
koje su i same nepotpune ili protivre ne. Prepreke na teorijskoj strani su
c
to to, uprkos brojnim pokuajima da se formalno denie zna enje proc
grama, nije se iskristalisao opte prihva eni formalizam kojim se pokazuje
c
ispravnost netrivijalnih algoritama.
U svakom slu aju, za skoro sve algoritme je potrebno ista i i pokazati
c
c
njihove bitne odlike. Za jednostavne algoritme je obi no dovoljno kratko
c
objanjenje njihovih glavnih odlika. Odlike o kojima je re su naj e e
c
c c
formalna tvrdenja koje odslikavaju na in na koji konkretan algoritam radi.
c

Onaj ko pie algoritam bi bar trebao da ima u vidu te odlike, iako je moda
neprakti no da se one dokazuju u svim detaljima. Te odlike treba da slue
c
i kao odreden vodi u kreativnom procesu pisanja nekog algoritma.
c

Primer: najveci zajednicki delilac


Da bismo prethodnu diskusiju ilustrovali jednim prostim primerom,
razmotrimo problem izra unavanja najve eg zajedni kog delioca dva poc
c
c
zitivna cela broja x i y. Najve i zajedni ki delilac za par pozitivnih celih
c
c
brojeva x i y ozna ava se sa nzd(x, y) i predstavlja najve i ceo broj koji
c
c
bez ostatka deli oba broja x i y. To jest, najve i zajedni ki delilac je broj
c
c
d = nzd(x, y) koji deli i x i y bez ostatka, pa x = md i y = nd za neke brojeve
c
m, n N,1 i svaki drugi takav zajedni ki delilac brojeva x i y je manji od d.
Da li je ovo dobra denicija? Drugim re ima, da li svaki par pozitivnih
c
celih brojeva ima najve i zajedni ki delilac? Jasno je da svaki par pozic
c
tivnih celih brojeva ima broj 1 za zajedni kog delioca, a najve i broj koji
c
c
istovremeno moe da deli x i y bez ostataka je onaj broj koji je minimum
od x i y. Dakle, nzd(x, y) uvek postoji i lei negde u intervalu izmedu 1 i

min{ x, y}.
Ovo zapaanje moemo iskoristiti za postupak kojim se trai nzd(x, y)
tako to se redom proveravaju svi potencijalni kandidati za najve i zac
jedni ki delilac brojeva x i y. Ovi kandidati su uzastopni celi brojevi od
c
broja jedan do minimuma brojeva x i y. Pri tome se ti brojevi proveravaju
obrnutim redom da li je neki od njih zajedni ki delilac za x i y, sve dok se ne
c
otkrije prvi zajedni ki delilac. Poto se provera obavlja obrnutim redom od
c
1 U ovoj knjizi sa N ozna avamo skup {0,1,2,... } nenegativnih celih brojeva.
c

20

Dizajn i analiza algoritama

najve e do najmanje mogu nosti, prvi nadeni zajedni ki delilac bi e ujedno


c
c
c
c

i najve i.
c
// Ulaz: pozitivni celi brojevi x i y
// Izlaz: nzd(x, y)
algorithm gcd(x, y)
d = min{x,y};
while ((x % d != 0) || (y % d != 0)) do
d = d - 1;
return d;

Iako je ispravnost algoritma gcd nadamo se o igledna, pokuajmo da na


c
formalniji na in pokaemo da taj algoritam ispravno izra unava nzd(x, y).
c
c
U ovom konkretnom slu aju je formalni dokaz koji je izloen u nastavku
c
verovatno suvie detaljan, ali pokazuje sve principe koje treba slediti u
optem slu aju.
c
Pre svega, klju ni korak u dokazivanju ispravnosti iterativnih algoc
ritama (kao to je gcd) jeste pokazati da petlje zadovoljavaju odredene

uslove. Neophodan uslov za svaku petlju je da njen izlazni uslov bude zadovoljen u jednom trenutku kako bi se izvravanje petlje sigurno zavrilo.

Druga vrsta uslova su oni cija se ta nost ne menja izvravanjem petlje.


c
Takav jedan uslov se naziva invarijanta petlje i predstavlja formalni iskaz

koji je ta an pre svake iteracije petlje. To zna i da ce invarijanta petlje biti


c
c
ta na nakon izvravanja poslednje iteracije petlje (ili pre prve neizvrene
c

iteracije), odnosno ona ce biti ta na nakon zavretka rada cele petlje. Prec
poznati pravu invarijantu petlje je vana vetina, jer znaju i invarijantu
c
petlje i izlazni uslov petlje obi no moemo zaklju iti neto korisno o ispravc
c
nosti samog algoritma.
Da bismo pokazali da se invarijanta petlje ne menja izvravanjem pe
tlje, moramo pokazati dve cinjenice o invarijanti petlje:
1. Invarijanta petlje je ta na pre prve iteracije petlje.
c
2. Ako je invarijanta petlje ta na pre neke iteracije petlje, ona ostaje
c
ta na i nakon izvravanja te iteracije petlje (to jest, pre izvravanja
c
slede e iteracije).
c
Prema tome, u konkretnom slu aju algoritma gcd pokaimo najpre da
c
c
se while petlja sigurno zavrava, odnosno da nije beskona na. Primetimo
da se izlaznim uslovom te petlje proverava da li d nije delilac broja x ili
broja y bez ostatka. Ako je to slu aj, telo petlje se ponavlja; u suprotnom
c

2.2. Analiza algoritama

21

slu aju, petlja se zavrava. Da bismo videli zato ce izlazni uslov napoc
sletku postati neta an, primetimo da je po etno d = min{ x, y}, a da se d
c
c

u svakoj iteraciji smanjuje za 1. Ovim uzastopnim smanjivanjem ce d u

najgorem slu aju postati jednako 1, izlazni uslov ce onda biti neta an poto
c
c

je istovremeno x % 1 = 0 i y % 1 = 0, pa ce se petlja tada zavriti.


Sada jo moramo pokazati ta nost izra unavanja nzd(x, y) u algoritmu
c
c
gcd. Odgovaraju a invarijanta while petlje je uslov d nzd(x, y). Jasno je
c

da je ovaj uslov zadovoljen pre prve iteracije te petlje, jer d po etno dobija
c
vrednost min{ x, y} i uvek je min{ x, y} nzd(x, y). Dalje, treba pokazati da

ako ovaj uslov vai pre neke iteracije, on ce vaiti i posle izvravanja te
iteracije. Zato pretpostavimo da je vrednost promenljive d ve a ili jednaka
c
vrednosti nzd(x, y) pre neke iteracije, i pretpostavimo da je ta iteracija
while petlje izvrena. To zna i da je izlazni uslov petlje bio ta an i da se
c
c
vrednost promenljive d smanjila za 1. Poto je izlazni uslov bio ta an, stara
c
vrednost promeljive d nije bila delilac oba broja x i y, pa zato stara vrednost
promeljive d nije jednaka nzd(x, y) nego je striktno ve a od nzd(x, y). Poto
c
je nova vrednost promenljive d za jedan manja od njene stare vrednosti,
moemo zaklju iti da je nova vrednost promenljive d opet ve a ili jednaka
c
c
vrednosti nzd(x, y) pre slede e iteracije. Ovim je dokazano da d nzd(x, y)
c
predstavlja invarijantni uslov while petlje u algoritmu gcd.
Na kraju, ispitajmo koji uslov vai kada se while petlja zavri. Iz
uslova prekida te petlje vidimo da se ona zavrava kada je vrednost promenljive d delilac oba broja x i y. Poto je nzd(x, y) najve i delilac oba broja
c
x i y, sledi da nakon zavretka while petlje vai d nzd(x, y). Ali poto
nakon zavretka while petlje vai i invarijanta petlje d nzd(x, y), sledi
c
da mora biti d = nzd(x, y). Poto se ova vrednost promeljive d vra a kao
c
rezultat algoritma gcd, to pokazuje da ovaj algoritam ispravno izra unava
nzd(x, y).

2.2

Analiza algoritama

Poto smo napisali algoritam za dati problem i pokazali da je algoritam


ispravan, slede i vaan korak je odredivanje veli ine ra unarskih resursa
c
c
c

koje taj algoritam koristi tokom izvravanja. Ovaj zadatak ocene ekasnosti nekog algoritma se naziva analiza algoritma. To ne treba shvatiti
kao nezavisan i odvojen proces od dizajna algoritma, ve se oni medusobno
c

proimaju i podjednako doprinose krajnjem cilju dobijanja ispravnih, ekasnih i elegantnih algoritama.

22

Dizajn i analiza algoritama

Dva najvrednija ra unarska resursa koje svaki algoritam treba da tedi


c
su vreme i memorija. Neki algoritam kome trebaju meseci da bi zavrio
svoj rad ili koji koristi nekoliko gigabajta radne memorije nije ba mnogo
koristan, iako je moda potpuno ispravan. Mogu i su i drugi kriterijumi za
c
ekasnost algoritama kao to su, na primer, koli ina mrenog saobra aja
c
c
u toku rada ili koli ina podataka koji se dvosmerno prenose na diskove.
c
Medutim, u ovoj knjizi skoro ekskluzivno prou avamo vremensku sloenost
c

algoritama memorijski zahtevi bi e pomenuti samo ako nisu u normalc


nim granicama. Drugim re ima, ekasnost algoritma identikujemo sa
c
duinom njegovog vremena izvravanja.
Kako moemo odrediti vreme izvravanja nekog algoritma? Dva glavna
na ina da se to uradi su empirijski i analiti ki. Empirijski na in podrac
c
c
zumeva da se prosto izmeri stvarno vreme rada odgovaraju eg programa
c
na ra unaru. Analiti ko odredivanje vremena izvravanja zasniva se na
c
c

teorijskoj analizi rada algoritma i prebrojavanju jedini nih instrukcija koje


c
se izvravaju tokom rada algoritma.
Dobre strane empirijskog pristupa su da se to moe relativno lako uraditi i da se dobijaju ta ni vremenski rezultati. Ali nedostaci ovog pristupa
c
su ozbiljniji i odnose prevagu, pa se zato ovaj pristup retko primenjuje u
praksi. Pre svega, empirijsko merenje se moe primeniti samo na program
napisan u celosti, jer je uticaj pojedinih delova na ukupno vreme teko
proceniti. Moda jo gore, empirijski izmereno vreme rada programa vai
samo za poseban slu aj ulaznih podataka i za jedan konkretan ra unar
c
c
pod odredenim programskim reimom rada. Na osnovu jednog merenja ne

moe se neto optije zaklju iti o vremenu izvravanja istog algoritma za


c

razli ite ulazne podatke, niti o tome kakvo ce vreme izvravanja biti na
c
nekom drugom ra unaru koji radi pod druga ijim okruenjem.
c
c
Osnovna ideja analiti kog pristupa je jednostavna: analizirati kako
c

radi algoritam korak po korak i na osnovu toga zaklju iti koliko ce biti
c
vreme njegovog izvravanja. Ovo je lako re i, ali postoje mnoge prepreke
c
na putu teorijske analize algoritama. O tome vie govorimo odmah u na
stavku, a za sada samo skre emo panju na cinjenicu koju treba stalno
c
imati na umu: sloenost analize se savladuje pojednostavljivanjem glavnih

ciljeva. Zbog toga se, naravno, ne dobija apsolutno precizna ocena vremena
izvravanja, ali je ona dovoljno dobra da steknemo optu sliku o ekasnosti
algoritama.
Vreme izvravanja nekog algoritma skoro uvek zavisi od broja ulac
znih podataka koje treba obraditi. Tako, prirodno je o ekivati da sortiranje 10 000 brojeva zahteva vie vremena nego sortiranje samo 10 brojeva.

2.2. Analiza algoritama

23

Vreme izvravanja algoritma je dakle funkcija veli ine ulaznih podataka.


c
Algoritmi za razli ite probleme mogu imati razli ite numeri ke forme velic
c
c

cine ulaza. Na primer, za problem sortiranja niza brojeva, veli ina ulaza je
c

broj clanova niza koje treba sortirati; za mnoenje dva velika cela broja x i
y, veli ina ulaza je broj cifara broja x plus broj cifara broja y; za grafovske
c

probleme, veli ina ulaza je broj cvorova ili broj grana grafa. Sre om, forma
c
c
veli ine ulaza za konkretan problem je obi no o igledna iz same prirode
c
c
c
problema.
Kako bi se veli ina ulaza obuhvatila analizom algoritma, najpre se
c
ulazni podaci algoritma grupiu prema njihovom broju koji se predstavlja
pozitivnim celim brojem n. Zatim se vreme izvravanja algoritma za ulaz
veli ine n izraava pomo u neke funkcije T(n). Drugim re ima, za svaki
c
c
c
pozitivan ceo broj n, vrednost T(n) daje broj vremenskih jedinica koliko
traje izvravanje algoritma za svaki njegov ulaz veli ine n. Na slici 2.1 je
c
ilustrovan ovaj pristup.

ulaz

T(n)

izlaz

S LIKA 2.1: Vreme izvravanja T(n) algoritma A je funkcija veli ine


c
ulaznih podataka n.

Medutim, ta no vreme izvravanja algoritma za neki konkretni ulaz,


c

pored njegove veli ine n, zavisi i od drugih faktora kao to su brzina proc
cesora ra unara ili struktura samih ulaznih podataka. Zato da bismo poc
jednostavili analizu i da bi denicija funkcije T(n) imala smisla, pretpostavljamo da se sve osnovne instrukcije algoritma izvravaju za jednu vremensku jedinicu i uzimamo najgori slu aj ulaznih podataka. Onda da bismo
c
dobili funkciju vremena izvravanja T(n) nekog algoritma treba da prosto

prebrojimo osnovne instrukcije koje ce se u algoritmu izvriti u najgorem

24

Dizajn i analiza algoritama

slu aju. Preciznije, funkciju T(n) za vreme izvravanja u najgorem slu aju
c
c
nekog algoritma deniemo da bude maksimalno vreme izvravanja tog
algoritma za sve ulaze veli ine n. Ova funkcija se naziva i vremenska
c
sloenost u najgorem slu aju. Potuju i tradiciju da se najgori slu aj podc
c
c

razumeva, ako nije druga ije naglaeno skoro uvek cemo koristiti kra e
c
c
termine vreme izvravanja i vremenska sloenost algoritma.

Jedini na instrukcija algoritma je osnovna ra unarska operacija cije je


c
c
vreme izvravanja konstantno. Ovo konstantno vreme moe biti razli ito
c
za razli ite vrste osnovnih instrukcija, ali je bitno da ono zavisi samo od
c
modela ra unara na kome se podrazumeva izvravanje osnovnih instrukc
cija, a ne i od veli ine podataka u algoritmu.
c
U stvari, analiza algoritama se dalje pojednostavljuje time to se uzima
da se svaka jedini na instrukcija izvrava za jednu vremensku jedinicu.
c
Apsolutna vrednost vremenske jedinice nije bitna (da li mikrosekunda,
nanosekunda, . . .), jer se kasnije pokazuje da nas zapravo interesuje samo
asimptotsko ponaanje vremena izvravanja, odnosno njegova brzina rasta u obliku neke konstante pomnoene prostom funkcijom veli ine ulaza.
c
Prema tome, za analizu algoritma je vaan samo ukupan broj jedini nih
c
instrukcija koje se izvravaju, a ne njihovo apsolutno ukupno vreme izvravanja.
Tipi ne jedini ne instrukcije algoritama su:
c
c
dodela vrednosti promenljivoj;
poredenje vrednosti dve promenljive;

aritmeti ke operacije;
c
logi ke operacije;
c
ulazno/izlazne operacije.
Jedno upozorenje: ove instrukcije se ponekad ne mogu smatrati jedini nim instrukcijama u algoritmu. Na primer, neka aritmeti ka operac
c
cija koja izgleda naivno kao to je to na primer sabiranje, nije jedini na
c
instrukcija ukoliko je veli ina operanada aritmeti ke operacije velika. U
c
c
c
c
tom slu aju, vreme potrebno za njeno izvravanje se pove ava sa veli inom
c
njenih operanada, pa se ne moe ograni iti nekom konstantom nezavisnom
c

od veli ine podataka. Imaju i ovo na umu, ipak cemo prethodne instrukcije
c
c
smatrati jedini nim sem ako to nije realisti no za dati problem.
c
c
Prethodnu diskusiju o analizi algoritama moemo preto iti u prakti ni
c
c
postupak za odredivanje vremenske sloenosti algoritama ukoliko prime
timo da je najgori slu aj izvravanja algoritma onaj u kojem se izvrava
c
najve i broj jedini nih instrukcija. Kao jednostavan primer, razmotrimo
c
c

2.2. Analiza algoritama

25

A1:
1
2
3
4
5

n = 5;
repeat
read(m);
n = n - 1;
until ((m == 0) || (n == 0));

A2:
1
2
3
4
5

read(n);
repeat
read(m);
n = n - 1;
until ((m == 0) || (n == 0));

Mada se ovi fragmenti razlikuju samo u prvom redu, u fragmentu A1 se


c
izvrava pet iteracija repeat petlje u najgorem slu aju, dok se u fragmentu
A2 izvrava n iteracija iste petlje u najgorem slu aju. To sledi otuda to se
c
izvravanje repeat petlje zavrava kada se ispuni jedan od uslova (m ==
c
0) ili (n == 0). Prvi uslov nikad ne e biti ispunjen ukoliko promenljiva m
ne dobije vrednost 0 u tre em redu, pre nego to se vrednost promenljive
c

n umanji do 0 ponavljanjem naredbe u cetvrtom redu. To je dakle najgori


slu aj za broj iteracija repeat petlje, jer ispunjenost prvog uslova moe
c
samo da smanji taj broj iteracija.
Analiza najgoreg slu aja vremena izvravanja algoritma je vana iz
c
dva razloga. Prvo, time se dobijaju garantovane performanse algoritma,
jer najgori slu aj odreduje gornju granicu vremena izvravanja za svaki
c

skup ulaznih podataka date veli ine. Drugo, najgori slu aj je mnogo laki
c
c
za analizu ( esto i jedino mogu i) nego drugi kriterijumi ekasnosti algoric
c
tama.
Prebrojavanje broja jedini nih instrukcija u najgorem slu aju izvrac
c
vanja algoritma kako bi se dobilo vreme izvravanja tog algoritma moe
se umnogome pojednostaviti ako znamo vremenske relacije tipi nih algoc
ritamskih konstrukcija. Naime, vreme izvravanja sloenijih konstrukcija moemo izvesti na osnovu vremena izvravanja njihovih sastavnih
delova. U tabeli 2.1 su sumirana vremena izvravanja osnovnih algori
c
tamskih konstrukcija, pri cemu je sa T B ozna eno vreme izvravanja (u
najgorem slu aju) bloka naredbi B. Tom tabelom nije obuhva ena rekurc
c

zija, poto ce o njoj biti vie re i u poglavlju 5.


c
U tabele 2.1 je o igledno da je vreme izvravanja serije dva bloka nac
redbi jednako zbiru vremena izvravanja pojedinih blokova. Isto tako,
jasno je da je vreme izvravanja alternative dva bloka naredbi jednako
duem vremenu izvravanja jednog od ta dva bloka, jer se posmatra najgori
slu aj izvravanja.
c
Najvanije pravilo u ovoj tabeli jeste da je vreme izvravanja petlje
jednako vremenu izvravanja naredbi u telu petlje pomnoenim sa najve-

26

Dizajn i analiza algoritama

Konstrukcija
Naredba serije S:
P; Q;
Naredba grananja S:
if C then P; else Q;

Vreme izvravanja
T S = T P + TQ
T S = T C + max{T P , TQ }

Naredba petlje S:
(1) while C do P;
(2) repeat P; until C;

TS = n TP
n najve i broj iteracija petlje
c

(3) for i = j to k do P;
T ABELA 2.1: Vremenska sloenost osnovnih algoritamskih konstrukcija.

cim mogu im brojem iteracija petlje. (Obratite panju na to da ovde radi


c
jednostavnosti nismo uzeli u obzir vreme potrebno za proveru uslova prekida rada petlji.) Ovo se odnosi i na ugnjedene petlje: vreme izvravanja

naredbi unutar grupe ugnjedenih petlji jednako je vremenu izvravanja

naredbi u telu najunutranjije petlje pomnoeno sa proizvodom broja iteracija svih petlji. Na primer, posmatrajmo ovaj algoritamski fragment:
1
2
3
4

for i = 1 to n do
for j = 1 to n do
if (i < j) then
swap(a[i,j], a[j,i]);

// jedinina instrukcija
c

Pod pretpostavkom da je naredba swap() u cetvrtom redu jedna od


jedini nih instrukcija i uzimaju i najgori slu aj da je uslov if naredbe uvek
c
c
c
ispunjen, vreme izvravanja ovog fragmenta je:
T(n) = n n (1 + 1) = 2n2 .
U ovom izrazu za funkciju T(n) na desnoj strani imamo proizvod n n poto
je broj iteracija spoljanje i unutranje petlje jednak n, dok faktor (1 + 1)
obuhvata vreme za jedno izvravanje tela unutranje petlje u redovima
3 i 4. Naime, to izvravanje se sastoji od provere ispunjenosti uslova if
naredbe i izvravanja jedini ne instrukcije swap.
c
Iako u ovoj knjizi koristimo isklju ivo vreme izvravanja u najgorem
c
slu aju, mogu i su i drugi pristupi za odredivanje ekasnosti algoritama.
c
c

2.2. Analiza algoritama

27

Jedan od njih je probabilisti ka analiza srednjeg vremena izvravanja nec


kog algoritma. Prose no vreme izvravanja je funkcija Tp (n) koja daje sredc
nju vrednost vremena izvravanja algoritma za slu ajne ulazne podatke
c
veli ine n. Prose no vreme izvravanja je realisti nija mera performansi
c
c
c

algoritma u praksi, ali je cesto to mnogo tee odrediti nego vreme izvravanja u najgorem slu aju. Razlog za to je da moramo znati raspodelu
c
verovatno e slu ajnih ulaznih podataka, to je teko zamislivo u praksi.
c
c
Ali da bismo ipak mogli lake izvesti matemati ka izra unavanja, obi no
c
c
c
pretpostavljamo da su svi ulazi veli ine n jednako verovatni, to u nekom
c
konkretnom slu aju moda i nije pravo stanje stvari.
c
Probabilisti ku analizu deterministi kih algoritama treba razlikovati
c
c
od analize takozvanih randomiziranih algoritama. Randomizirani algoritmi su po svojoj prirodi slu ajni jer se u toku njihovog izvravanja doc
nose slu ajne odluke. Njihovo vreme izvravanja zavisi od slu ajnih ishoda
c
c
tih odluka i zato predstavlja slu ajnu vrednost. Za randomizirane algoc

ritme se odreduje o ekivano vreme izvravanja, pri cemu se matemati ko


c
c

o ekivanje izra unava u odnosu na slu ajne odluke tokom izvravanja.


c
c
c
Sasvim druga iji pristup je ocena ekasnosti algoritma u odnosu na
c
ekasnost drugih algoritama koji reavaju isti problem. Ovaj metod se
sastoji u tome da se formira mala kolekcija tipi nih ulaznih podataka koji
c
se nazivaju ben mark podaci. Ben mark podaci se dakle smatraju reprec
c

zentativnim za sve ulazne podatke, odnosno podrazumeva se da ce algoritam koji ima dobre performanse za ben mark podatke imati isto tako
c
dobre performanse za sve ulazne podatke. Kako je na cilj analiti ka ocena
c
c
ekasnosti algoritama, a ben mark analiza je u sutini empirijski metod,
o tome vie ne emo govoriti u ovoj knjizi.
c
Na osnovu nadenog vremena izvravanja nekog algoritma moemo po
kuati da odgovorimo i na tri dodatna pitanja:
1. Kako moemo re i da li je neki algoritam dobar?
c
2. Kako znamo da li je neki algoritam optimalan?
3. Zato nam je uopte potreban ekasan algoritam zar ne moemo
prosto kupiti bri ra unar?
c
Da bismo odgovorili na prvo pitanje, lako moemo uporediti vreme izvravanja posmatranog algoritma sa vremenima izvravanja postoje ih algoc
ritama koji reavaju isti problem. Ako to poredenje ide u prilog posmatra
nom algoritmu, moemo kvantitativno zaklju iti da je on dobar algoritam
c
za neki problem.

28

Dizajn i analiza algoritama

Na drugo pitanje je teko odgovoriti u optem slu aju. To je zato to


c
iako za bilo koja dva algoritma moemo re i koji je bolji ako uporedimo
c
njihova vremena izvravanja, ipak ne moemo re i da li je onaj bolji algoric
tam zaista i najbolji mogu i. Drugim re ima, moramo nekako znati donju
c
c
granicu vremena izvravanja svih algoritama za konkretan problem. To
zna i da za dati problem ne samo poznati algoritmi, nego i oni koji jo
c
nisu otkriveni, moraju se izvravati za vreme koje je ve e od neke granice.
c
Odredivanje ovakvih dobrih granica nije lak zadatak i time se ne emo
c

baviti u ovoj knjizi.


Tre e pitanje obi no postavljaju neuki ljudi koji misle se novcem moe
c
c
sve kupiti. Pored toga to su intelektualno izazovniji, ekasni algoritmi

ce se skoro uvek bre izvravati na sporijem ra unaru nego loi algoritmi


c

na super ra unaru za dovoljno velike ulazne podatke, u ta cemo se i sami


c
uveriti. U stvari, instance problema ne moraju da postanu toliko velike

pre nego to bri algoritmi postanu superiorniji, cak i kada se izvravaju


na obi nom personalnom ra unaru.
c
c

2.3 Primeri algoritama


Da bismo bolje razumeli sutinu dizajna i analize algoritama, u ovom

odeljku cemo prethodnu diskusiju o tome potkrepiti konkretnim, reprezen


tativnim primerima. Ti primeri za citaoce imaju nesumnjivu prakti nu
c
vrednost u sticanju neophodne rutine, ali oni imaju i pedagoku vrednost
jer uspostavljaju osnove dizajna i analize algoritama na koje se oslanjaju
ostali delovi ove knjige.

Primer: najmanji element niza


Problem najmanjeg elementa niza je sli an problemu najve eg elementa
c
c
niza iz odeljka 1.4: za dati niz a od n neuredenih brojeva a 1 , a 2, . . ., a n treba

na i indeks (prvog) najmanjeg elementa tog niza. Algoritam min za ovaj


c
problem je zato jednostavna modikacija algoritma max kojim se nalazi
indeks najve eg elementa niza. Naime, za nalaenje globalno najmanjeg
c
elementa niza, svi elementi niza se redom proveravaju da li su manji od
najmanjeg elementa koji je naden do odgovaraju eg trenutka provere.
c

// Ulaz: niz a, broj elemenata n niza a


// Izlaz: indeks najmanjeg elementa niza a
algorithm min(a, n)

2.3. Primeri algoritama

m = a[1];
j = 1;

29

// najmanji element naen do sada


d
// indeks najmanjeg elementa

i = 2;
// proveriti ostale elemente niza
while (i <= n) do
if (m > a[i]) then // naen manji element od privremeno najmanjeg
d
m = a[i];
// zapamtiti manji element
j = i;
// ... i njegov indeks
i = i + 1; // prei na sledei element niza
c
c
return j;

// vratiti indeks najmanjeg elementa

Analizu jednostavnog algoritma min nije teko izvriti. Poto broj iteracija tela while petlje iznosi n 1, a telo te pelje se sastoji od if naredbe
i naredbe dodele, vreme izvravanja algoritma min je:
T(n) = 1 + 1 + 1 + (n 1)(3 + 1) + 1
= 4 + 4(n 1)
= 4n .

U ovom izrazu za funkciju T(n) u prvom redu, prve tri jedinice u zbiru su
vremena izvravanja prve tri naredbe dodele u algoritmu min, faktor (3 + 1)
predstavlja vreme jednog izvravanja tela while petlje (provera uslova i
dve naredbe dodele u if naredbi, kao i naredba dodela na kraju tela petlje),
a poslednjom jedinicom je obuhva eno vreme izvravanja return naredbe.
c
U izrazu 4n za funkciju T(n) vremena izvravanja algoritma min se
veli ina ulaza n (tj. broj elemenata ulaznog niza) pojavljuje na prvi stepen.
c
Zato za taj algoritam kaemo da je linearni algoritam. Primetimo jo da
je vreme izvravanja algoritma max iz odeljka 1.4 takode T(n) = 4n, jer su

c
algoritmi min i max prakti no isti.

Primer: maksimalna suma podniza

Problem maksimalne sume podniza se cesto pojavljuje u ra unarskoj


c
biologiji prilikom analize DNA ili proteinskih sekvenci. Taj problem je
ra unarski interesantan poto postoje mnogi algoritmi razli ite ekasnosti
c
c

za njegovo reenje. U ovom odeljku cemo opisati samo najsporiji, kvadratni


algoritam za njegovo o igledno reenje na osnovu denicije problema. Bri,
c
linearni algoritmi zahtevaju dublji uvid u prirodu problema i sloenije algoritamske tehnike o kojima se govori u nastavku knjige.

30

Dizajn i analiza algoritama

Ali pre denicije samog problema, potrebno je precizirati ta smatramo


podnizom nekog niza. Za niz a od n brojeva a 1 , a 2, . . ., a n , neprekidni podniz
niza a je drugi niz koji se sastoji od nula ili vie uzastopnih elemenata niza
a. Na primer, ako je
a = [2, 1, 1, 3, 4, 6, 7, 2, 3, 5] ,
onda su [1, 3, 4, 6, 7] i [1] neprekidni podnizovi, dok niz [2, 1, 3] to nije.
Poto nas u ovom odeljku interesuju samo podnizovi koji se sastoje od uzastopnih elemenata, radi jednostavnosti izraavanja umesto termina ne
prekidni podniz cesto koristimo kao sinonim kra i izraz podniz.
c
Ako je dat (neprekidni) podniz a i , . . ., a j niza a, suma tog podniza koju
c
ozna avamo S i, j jeste obi an zbir svih elemenata podniza:
c
j

S i, j = a i + a i+1 + + a j =

ak .
k= i

Obratite panju na to da se prazan niz duine nula smatra neprekidnim


podnizom svakog niza, pa po deniciji uzimamo da je suma praznog podniza jednaka nuli.
Problem maksimalne sume (neprekidnog) podniza sastoji se u tome da
se odredi najve a suma svih neprekidnih podnizova datog niza. (Optije,
c
potrebno je odrediti i sm neprekidni podniz koji ima najve u sumu.) Na
c

primer, citaoci mogu proveriti da reenje problema maksimalne sume podniza za prethodni niz
a = [2, 1, 1, 3, 4, 6, 7, 2, 3, 5] ,
iznosi 8, to je zbir elemenata podniza [7, 2, 3].
Elementi datog niza mogu biti pozitivni, negativni i nule. Ako dati niz
sadri samo pozitivne brojeve, reenje problema maksimalne sume podniza
takvog niza je o igledno zbir svih elemenata niza. Ako niz sadri samo
c
negativne brojeve, neprekidni podniz koji ima najve u sumu je prazan
c
podniz i reenje u ovom slu aju je zato uvek nula. Interesantan slu aj
c
c
je dakle kada imamo zajedno pozitivne i negativne brojeve u datom nizu.
Za dati niz a od n brojeva, neka je M suma njegovog neprekidnog
podniza koji ima najve u sumu. Formalno,
c
M = max 0, max S i, j .
1 i j n

2.3. Primeri algoritama

31

Nula na desnoj strani ove jednakosti je potrebna zato to bez ove nule
jednakost ne bi bila ta na kada se dati niz sastoji samo od negativnih elec
menata. Ali radi jednostavnijeg pisanja, u daljem tekstu pretpostavljamo
da implicitno uvek uzimamo 0 kao maksimalnu sumu u tom specijalnom
slu aju. Tako, prethodnu jednakost piemo saetije:
c
M = max S i, j .
1 i j n

Da bismo izra unali M po deniciji, treba da izra unamo sume svih


c
c
podnizova koji po inju u poziciji 1 datog niza, zatim treba da izra unamo
c
c
sume svih podnizova koji po inju u poziciji 2 datog niza i tako dalje, sve dok
c
ne izra unamo sume svih podnizova koji po inju u poziciji n datog niza. Na
c
c
kraju, potrebno je da dodatno izra unamo maksimum svih ovih suma.
c

Koliko imamo ovih mogu ih suma ciji maksimum traimo? Lako je


c
videti da broj svih podnizova koji po inju u poziciji 1 datog niza (i dakle
c
njihovih suma) iznosi n, da broj svih podnizova koji po inju u poziciji 2
c
c
datog niza iznosi n 1 i tako dalje, da broj svih podnizova koji po inju u po
ziciji n datog niza iznosi 1. Prema tome, ukupan broj suma ciji maksimum
traimo je n + (n 1) + + 1 = n(n + 1)/2.
Primetimo da postupak izra unavanja M po deniciji moemo reorgac
nizovati bez uticaja na kona an rezultat. Naime, umesto da ra unamo
c
c
sve mogu e sume i tek nakon toga traimo njihov maksimum, moemo
c
ra unati parcijalne maksimume suma elemenata od i-te pozicije niza i na
c
kraju traiti maksimum ovih parcijalnih maksimalnih suma.2 Preciznije,
ako za svako i = 1, 2, . . ., n u i-tom koraku dodatno izra unamo parcijalni
c
maksimum suma svih podnizova koji po inju u i-poziciji datog niza, onda
c
na samom kraju preostaje samo da izra unamo maksimum ovih n parcijalc
nih maksimalnih suma. Ovo moemo predstaviti tako da najpre ra unamo
c

drugi niz b od n elemenata b 1 , b 2 , . . ., b n , pri cemu je


b i = max S i,i , S i,i+1 , . . ., S i,n = max S i, j ,
j = i,...,n

a zatim ra unamo M kao


c
M = max { b 1 , b 2 , . . ., b n } = max b i .
i=1,...,n

Za algoritamsko izra unavanje M primenjujemo upravo ovaj pristup.


c
Realizacija tog postupka na pseudo jeziku sastoji se od dva algoritma. Prvi,
2 Ovom reorganizacijom izra unavanja se dodue ne ubrzava odgovaraju i algoritam,
c
c
ali se tedi na memoriji.

32

Dizajn i analiza algoritama

pomo ni algoritam ra una element b i niza b. Drugi, glavni algoritam


c
c
koristi prvi algoritam kao potprogram za nalaenje reenja problema maksimalne sume podniza datog niza a. Pomo ni algoritam je po strukturi
c
sli an algoritmu min iz prethodnog odeljka:
c
// Ulaz: indeks i, niz a, broj elemenata n niza a
// Izlaz: element b i niza b
algorithm B(i, a, n)
m = 0;
s = 0;

// maksimalna suma podniza od pozicije i


// sume S i, j za j = i,... , n
// izraunati S i, j za j = i,... , n
c

for j = i to n do
s = s + a[j];
if (m < s) then
m = s;
return m;

// S i, j = S i, j 1 + a j
// naena vea suma
d
c
// aurirati maksimalnu sumu

// vratiti b i

Algoritam B izra unava element b i na slede i na in. Promenljiva m


c
c
c
sadri privremeno izra unatu maksimalnu sumu podnizova koji po inju
c
c
u poziciji i, a promenljiva s sadri sume tih podnizova. Ove promenljive
se najpre pravilno inicijalizuju vredno u 0. Potom se u svakom koraku
c
j od i do n izra unava suma S i, j u promenljivoj s dodavanjem elementa
c
c
a j prethodno izra unatoj sumi S i, j 1 . Odmah zatim se proverava da li je

c
m < s, odnosno da li je pronaden podniz od pozicije i cija je suma ve a od

trenutno maksimalne. Naravno, ako je to slu aj, privremenu maksimalnu


c

sumu treba aurirati, to se i cini.


Da bismo analizirali vreme izvravanja algoritma B, primetimo da ono
zavisi od dva parametra: broja elemenata n niza a i indeksa i elementa b i
koji se izra unava. U vremenu izvravanja ovog algoritma dominira for
c

petlja cije se telo ponavlja n i + 1 puta, jer se broja j ove petlje menja od
c
i do n. Prema tome, vreme izvravanja algoritma B je:
T(n, i) = 1 + 1 + (n i + 1)(1 + 2) + 1
= 3 + 3(n i + 1)
= 3(n i + 2) .

Sada je lako napisati algoritam kojim se nalazi maksimalna suma podniza datog niza: algoritmom B treba najpre redom izra unati sve elemente
c

2.3. Primeri algoritama

33

b i , a zatim prosto treba odrediti njihov maksimum. Ovaj postupak na


pseudo jeziku je:3
// Ulaz: niz a, broj elemenata n niza a
// Izlaz: maksimalna suma podniza M
algorithm mcss(a, n)
for i = 1 to n do
b[i] = B(i, a, n);
M = max(b, n);
return M;

S obzirom na to da znamo vremena izvravanja algoritama B i max, lako


je onda odrediti vreme izvravanja algoritma mcss:
T(n) =

n
i =1
n

=3

3(n i + 2) + 1 + (4n + 1) + 1

i =1

(n i) + 7n + 4n + 2

(n 1)n
+ 11n + 2
2
= 1.5n2 + 9.5n + 2 .

=3

Podsetimo se da funkcija T(n) predstavlja vreme izvravanja (u najgorem slu aju) nekog algoritma za sve ulazne podatke tog algoritma veli ine
c
c
n. Poto se promenljiva n u prethodnom izrazu za funkciju T(n) vremena
izvravanja algoritma mcss pojavljuje na drugi stepen, za taj algoritam
kaemo da je kvadratni algoritam.
Primetimo da je mogu e poboljati ovaj algoritam ukoliko eljeni makc
c
simum M elemenata b i izra unavamo u hodu. Naime, umesto da maksic
mum elemenata b i traimo nakon to sve te elemente izra unamo, moemo
da odredujemo njihov privremeni maksimum kako ih redom izra unavamo.
c

Pored toga, na ovaj na in nam ne treba poseban niz za cuvanje elemenata


c
c
b i , pa zato u ovom slu aju tedimo na memorijskom prostoru.
U stvari, ovaj pristup moemo dalje poboljati ukoliko odredujemo pri
c
vremeni maksimum ne od elemenata b i ve od suma S i, j kako ih redom
izra unavamo. Postupak na pseudo jeziku za ovu tedljivu verziju algoc
ritma mcss je:
3 Ime algoritma mcss je skra enica od engleskog termina za problem najve e sume
c
c
neprekidnog podniza: the maximum contiguous subsequence sum problem.

34

Dizajn i analiza algoritama

// Ulaz: niz a, broj elemenata n niza a


// Izlaz: maksimalna suma podniza M
algorithm mcss(a, n)
M = 0;
// maksimalna suma podniza
for i = 1 to n do
// izraunati b i za i = i,... , n
c
s = 0;
for j = i to n do
// izraunati S i, j za j = i,... , n
c
s = s + a[j];
// S i, j = S i, j 1 + a j
if (M < s) then
M = s;
return M;

Citaocima se za vebu ostavlja da se uvere da ova varijanta nije bra


od prvobitne, odnosno da je i dalje re o kvadratnom algoritmu.
c

Primer: sortiranje niza


Ako je dat niz neuredenih brojeva, problem njegovog sortiranja se sa
stoji od preuredivanja brojeva tog niza tako da oni obrazuju rastu i niz.
c

c
Preciznije, za dati niz a od n elemenata a 1 , a 2, . . ., a n treba na i permutaciju svih indeksa elemenata niza i 1 , i 2 , . . ., i n tako da novi prvi element a i 1 ,
novi drugi element a i 2 i tako dalje, novi n-ti element a i n u nizu zadovoljavaju uslov a i 1 a i 2 a i n .

Za reavanje problema sortiranja niza cemo pokazati tri jednostavna


algoritma. To su klasi ni algoritmi koji priblino imaju isto vreme izvrac
vanja koje kvadratno zavisi od veli ine ulaza (tj. broja elemenata niza). U
c

nastavku knjige cemo upoznati ekasnije metode sortiranja.


Sortiranje zamenjivanjem (bubble-sort). Najbolji na in za razumec
vanje osnovne ideje prvog metoda sortiranja, koji se popularno naziva sortiranje zamenjivanjem (engl. bubble-sort), jeste da zamislimo da je dati
niz potopljen u vodu i okrenut vertikalno. Ako dalje zamislimo da su

elementi datog niza sa malim vrednostima laki po teini, onda ce oni


ovim metodom isplivavati na vrh proizvode i mehuri e. Ova analogija
c
c
je upravo razlog za (interesantan?) engleski naziv ovog metoda.
Postupak sortiranja zamenjivanjem se sastoji od viestrukih prolaza
du datog niza od dna ka vrhu. Pri tome, ako dva susedna elementa
nisu u dobrom redosledu (laki element je ispod teeg), zamenjujemo
im mesta. Efekat ovog zamenjivanja je da se u prvom prolazu najlaki

2.3. Primeri algoritama

35

element sa najmanjom vredno u penje sve do vrha. U drugom prolazu,


c
drugi najmanji element se penje do druge pozicije. Sli no, tre i najmanji
c
c
element u tre em prolazu dolazi na svoje mesto i tako dalje. Na slici 2.2 je
c
prikazan ovaj metod sortiranja za niz [17, 23, 8, 11, 5, 2] od 6 elemenata. Na
toj slici vrednost promenljive i ukazuje na redni broj prolaza.
i=1

i=2

i=3

i=4

i=5

17

23

17

23

17

11

23

17

11

11

11

23

17

17

11

11

23

23

S LIKA 2.2: Sortiranje zamenjivanjem.


Primetimo sa slike 2.2 da u drugom prolazu moemo da stanemo do
druge pozicije, jer se najmanji element ve nalazi na svom prvom mestu.
c
Isto tako, u tre em prolazu moemo da stanemo do tre e pozicije, poto
c
c
znamo da se prva dva najmanja elementa ve nalaze u svojim zavrnim
c
pozicijama. Sledstveno tome, u i-tom prolazu moemo da stanemo do poc
zicije i poto se i 1 najmanjih elemenata ve nalaze u svojim zavrnim
pozicijama.
Precizniji opis ovog postupka na pseudo jeziku za sortiranje niza zamenjivanjem njegovih elemenata je:
// Ulaz:
niz a, broj elemenata n niza a
// Izlaz: niz a sortiran u rastuem redosledu
c
algorithm bubble-sort(a, n)
for i = 1 to n-1 do
for j = n downto i+1 do
if (a[j] < a[j-1]) then
swap(a[j], a[j-1]);
return a;

Da bismo analizirali vreme izvravanja algoritma bubble-sort, najpre


c
primetimo da algoritam swap na strani 13 moemo smatrati jedini nom

instrukcijom. To ima smisla za algoritam swap poto se njegove cetiri

36

Dizajn i analiza algoritama

naredbe izvravaju za ukupno konstantno vreme.4


Vreme jednog izvravanja tela unutranje for petlje je dve vremenske
jedinice: jedna za proveru uslova if naredbe i jedna za instrukciju swap).

Stoga preostaje jo da odredimo koliko puta ce se to telo izvriti u algoritmu

bubble-sort. Citaoci mogu lako proveriti da za ksnu vrednost broja a i =


c

1, 2, . . ., n 1 spoljanje for petlje, telo unutranje for petlje ce se izvriti


ta no n i puta. Zbog toga ukupan broj izvravanja tela unutranje petlje
c
iznosi:
n 1
(n 1)n
(n 1) + (n 2) + + 2 + 1 =
i=
.
2
i =1
Prema tome, ako uzmemo u obzir i naredbu return na kraju, ukupno
vreme izvravanja algoritma bubble-sort je:
T(n) =

(n 1)n
2 + 1 = n2 n + 1 .
2

Algoritam bubble-sort je dakle kvadratni algoritam poto vreme njegovog


c
izvravanja T(n) = n2 n + 1 zavisi od veli ine ulaza n na drugi stepen.
Vreme izvravanja nekog algoritma posmatramo u najgorem slu aju,
c

pa je to najdue vreme koje ce taj algoritam raditi za datu veli inu ulaznih
c
podataka. Primetimo da najgori slu aj algoritma bubble-sort (kada je
c
ulazni niz a po etno sortiran u opadaju em redosledu) nije mnogo gori od
c
c
najboljeg slu aja (kada je ulazni niz a po etno ve sortiran u rastu em
c
c
c
c
redosledu). U najboljem slu aju se nikad ne izvrava operacija swap u
c
c
unutranjoj for petlji, ali je vreme izvravanja u tom slu aju ipak jednako
(n 1)n
1 + 1 = 0.5n2 0.5n + 1 ,
2
to je i dalje kvadratna funkcija od n.
c
Ovo svojstvo algoritma bubble-sort ne vai u optem slu aju, jer se
vremena izvravanja nekih algoritama u najgorem i najboljem slu aju mogu
c
drasti no razlikovati. To je na neki na in dobra osobina algoritma, jer je
c
c
prirodno o ekivati da u najboljem slu aju ulaznih podataka algoritam radi
c
c
mnogo bre.
Prethodno opisani algoritam bubble-sort moemo lako modikovati
kako bi za dobre ulazne podatke taj algoritam radio mnogo bre. Primetimo da dodatni prolazi du datog niza nisu vie potrebni ukoliko se
4 Ovo je jedan od na ina za pojednostavljivanje analize algoritama: svaki algoritam koji
c

se izvrava za konstantno vreme smatramo jedini nom instrukcijom, jer ta na vrednost tog
c
c
konstantnog vremena nije bitna.

2.3. Primeri algoritama

37

u poslednjem prolazu nijedanput nije izvrila operacija swap. To sledi


otuda to onda ne postoji element niza koji je van svog mesta u rastu em
c
redosledu, odnosno onda se svi elementi niza nalaze na svojim mestima u
rastu em redosledu.
c
Ovo zapaanje se moe lako iskoristiti u algoritmu bubble-sort: kako
se u tom algoritmu prolazi du datog niza realizuju spoljanjom for pe
tljom, potrebno ju je prosto zameniti drugom petljom cije se izvravanje
kontrolie indikatorom da li se u poslednjem prolazu nijedanput nije izvrila operacija swap. Ova poboljana varijanta algoritma je:
// Ulaz:
niz a, broj elemenata n niza a
// Izlaz: niz a sortiran u rastuem redosledu
c
algorithm bubble-sort(a, n)
repeat
s = false; // indikator izvravanja operacije swap
i = 1;
for j = n downto i+1 do
if (a[j] < a[j-1]) then
swap(a[j], a[j-1]);
s = true;
i = i + 1;
until (s == false);
return a;

Citaocima se za vebu ostavlja da se uvere da je u najgorem slu aju


c
poboljana verzija algoritma bubble-sort i dalje kvadratni algoritam, ali
u najboljem slu aju je to linearni algoritam. Ovde je interesantno napomec
nuti da je ovaj na in jedan od najbrih metoda sortiranja u slu aju kada se
c
c
unapred zna da je samo mali broj elemenata van svog mesta u rastu em
c
redosledu (recimo, kada se ve sortiranom nizu dodaju dva-tri elementa).
c
Sortiranje umetanjem (insert-sort). Drugi metod za sortiranje niza
a od n elemenata a 1, a 2 , . . ., a n popularno se naziva sortiranje umetanjem

(engl. insert-sort). Ovaj metod se sastoji od n iteracija, pri cemu se u itoj iteraciji ume e element a i na njegovo pravo mesto izmedu prvih i 1
c

najmanjih elemenata prethodno ve uredenih u rastu em redosledu. Ovaj


c
c

na in sortiranja u i-toj iteraciji je ilustrovan na slici 2.3.


c
Da bi postupak sortiranja umetanjem bio jasniji na pseudo jeziku, po
godno je uvesti nulti element niza a 0 cija se vrednost pretpostavlja da je
manja od svih vrednosti pravih elemenata a 1 , a 2, . . ., a n . (Takva vrednost
se obi no naziva sentinela.)
c

38

Dizajn i analiza algoritama


1

i 1

S LIKA 2.3: Sortiranje umetanjem.

// Ulaz:
niz a, broj elemenata n niza a
// Izlaz: niz a sortiran u rastuem redosledu
c
algorithm insert-sort(a, n)
a[0] = -;
for i = 1 to n do
j = i
while (a[j] < a[j-1]) do
swap(a[j], a[j-1]);
j = j - 1;
return a;

Vreme izvravanja algoritma insert-sort se odreduje na sli an na in


c
c

kao za algoritam bubble-sort. Dodue, broj iteracija ugnjedene while

petlje nije odmah o igledan, ali moemo primetiti da taj broj nije ve i od
c
c
c
i 1. To je zato to promenljiva j dobija po etnu vrednost jednaku vrednosti promenljive i pre po etka while petlje, a j se smanjuje za jedan u
c
svakoj iteraciji te petlje do zavretka rada petlje. A while petlja se sigurno

zavrava kada je j = 1, jer je onda a j 1 = a 0 = , cime uslov nastavka te


petlje postaje neta an. U najgorem slu aju dakle, iteracije while petlja se
c
c
izvravaju za sve uzastopne vrednosti j od i do 2, pa je broj tih iteracija
najvie i 1.
Prema tome, u algoritmu insert-sort se izvrava n iteracija spoljanje for petlje, a u svakoj od tih iteracija za i = 1, 2, . . ., n izvrava se
najvie i 1 iteracija unutranje while petlje. Poto se telo unutranje
while petlje izvrava za 2 vremenske jedinice, ukupno vreme izvravanja
algoritma insert-sort je:
T(n) = 1 +
= 1+

n
i =1
n
i =1

1 + 2(i 1) + 1
1+2

= 1+n+2

n
i =1

(i 1) + 1

(n 1)n
+1
2

2.3. Primeri algoritama

39
= n2 + 2 .

Algoritam insert-sort je dakle kvadratni algoritam. Primetimo da


kada je ulazni niz po etno sortiran u opadaju em redosledu, onda je broj
c
c
c
iteracija unutranje while petlje jednak ta no i 1. Zato se u tom najgorem
slu aju algoritam insert-sort zaista izvrava za kvadratno vreme dato
c
funkcijom T(n). Sa druge strane, u najboljem slu aju kada je ulazni niz poc

cetno sortiran u rastu em redosledu, broj iteracija unutranje while petlje


c

je 0. Citaoci mogu lako proveriti da je onda vreme izvravanja algoritma


insert-sort jednako 2n + 2, to je mnogo bolje nego u najgorem slu aju.
c
Sortiranje izborom (select-sort). Metod sortiranja niza a od n elemenata a 1 , a 2 , . . ., a n , koji se popularno naziva sortiranje izborom (engl. selectsort), zasniva se kao i prethodni metodi na ponavljanju odredenog postupka

nad datim nizom. Taj postupak u ovom metodu je da se u i-toj iteraciji uzima najmanji element medu elementima a i , a i+1 , . . ., a n i zamenjuje

c
sa elementom a i . Ovaj na in sortiranja u i-toj iteraciji je ilustrovan na
slici 2.4.
a j = min{a i , a i+1 ,... , a n }
i 1

S LIKA 2.4: Sortiranje izborom.


Ispravnost postupka za sortiranje izborom sledi na osnovu toga to

posle prve iteracije ce najmanji element niza biti na prvom mestu, posle

druge iteracije ce drugi najmanji element niza biti na drugom mestu i

tako dalje, posle i-te iteracije ce i najmanjih elemenata niza biti poredano

u rastu em redosledu. Na kraju, posle (n 1)-ve iteracije ce ceo niz biti


c
poredan u rastu em redosledu.
c

Precizniji opis celokupnog postupka za sortiranje izborom na pseudo


jeziku je:
// Ulaz:
niz a, broj elemenata n niza a
// Izlaz: niz a sortiran u rastuem redosledu
c
algorithm select-sort(a, n)
for i = 1 to n-1 do

40

Dizajn i analiza algoritama

j = minr(a, i, n);
swap(a[i], a[j]);
return a;

Algoritam minr, koji se u algoritmu select-sort koristi kao potprogram, kao rezultat daje indeks najmanjeg elementa desnog podniza a i ,
a i+1 , . . ., a n datog niza a. Taj algoritam je mala modikacija algoritma min

na strani 28 i zato se preputa citaocima za vebu. Citaoci mogu usput lako


proveriti da vreme izvravanja algoritma minr iznosi 4(n i + 2).
Da bismo sada analizirali algoritam select-sort, primetimo da se
telo for petlje u tom algoritmu izvrava za vreme 4(n i + 2) + 1 + 1, gde
su dvema jedinicama obuhva ena vremena za naredbu dodele i operaciju
c
swap koju smatramo jedini nom instrukcijom. Prema tome, ukupno vreme
c
izvravanja algoritma select-sort je:
T(n) =
=

n 1
i =1
n 1
i =1

4(n i + 2) + 2 + 1
4(n i) + 10 + 1

(n 1)n
+ 10(n 1) + 1
2
= 2n2 + 8n 9 .
=4

I algoritam select-sort je dakle kvadratni algoritam, a citaocima se


ostavlja da analiziraju njegov najgori i najbolji slu aj.
c

Zadaci
1. Koriste i odgovaraju u invarijantu petlje, pokaite ispravnost algoritma
c
c
za problem pretrage niza u 1. zadatku prethodnog poglavlja. Pored toga,
odredite vreme izvravanja tog algoritma.
2. Koriste i odgovaraju u invarijantu petlje, pokaite ispravnost algoritma
c
c
za problem preostalog dela kredita u 2. zadatku prethodnog poglavlja.
(Savet: Iznos kredita koji preostaje nakon i-te iteracija petlje je p i .)
Pored toga, odredite vreme izvravanja tog algoritma.
3. Odredite vreme izvravanja slede ih algoritamskih fragmenata:
c

2.3. Primeri algoritama

41

a)

if (x == 0) then
for i = 1 to n do
a[i] = i;

b)

i = 1;
repeat
a[i] = b[i] + c[i];
i = i + 1;
until (i == n);

c)

if (x == 0) then
for i = 1 to n do
for j = 1 to n do
a[i,j] = 0;
else
for i = 1 to n do
a[i,i] = 1;

d)

for i = 1 to n do
for j = 1 to n do
for k = 1 to j do
if (i == j) then
a[k,k] = 0;

4. Ako niz brojeva predstavimo u prirodnom horizontalnom poloaju, postupak sortiranja zamenjivanjem (bubble-sort) na strani 34 sastoji se od
ponavljanja prolaza du datog niza od najve eg potrebnog indeksa niza
c
do najmanjeg, odnosno ti prolazi uvek idu u smeru zdesna na levo.
a) Napiite algoritam za sortiranja zamenjivanjem u kojem se du datog niza uvek prolazi u smeru sleva na desno.
b) Napiite algoritam za sortiranja zamenjivanjem u kojem se du datog niza naizmeni no prolazi u oba smera.
c

G LAVA

3
Vreme izvravanja algoritma

Analiza jednostavnih algoritama u prethodnom poglavlju pokazuje da


za odredivanje vremena izvravanja algoritma moramo voditi ra una o
c

mnogim sitnim koracima u algoritmu. Kod iole sloenijih algoritama bi


nas brojanje svake jedini ne instrukcije svakako omelo da steknemo pravu
c
sliku o brzini izvravanja algoritama, ako ne i spre ilo da do kraja ispravno
c
odredimo vreme izvravanja. Dobar uvid u sloenost algoritama zasniva se
na pravoj meri pojednostavljenja njihove analize.
Zato da ne bismo otili u drugu krajnost i bili suvie precizni, analiza algoritama se pojednostavljuje do krajnih granica kako bi se pravilno ocenilo
asimptotsko vreme izvravanja algoritma, odnosno njegovo vreme izvravanja samo za veliki broj ulaznih podataka. To drugim re ima moemo
c
kazati da nas zapravo ne interesuje apsolutno ta no vreme izvravanja nec
kog algoritma, nego samo to koliko brzo raste vreme izvravanja algoritma
sa pove anjem veli ine ulaza algoritma.
c
c

U ovom poglavlju cemo blie razraditi ovu ideju daju i njenu motivaciju
c
i formalizaciju.

3.1

Asimptotsko vreme izvravanja

Prilikom analize algoritama moemo dobiti vrlo komplikovane funkcije


za njihova vremena izvravanja. Na primer, u prethodnom poglavlju smo
za tri algoritma sortiranja dobili tri razli ite, relativno proste kvadratne
c

44

Vreme izvravanja algoritma

funkcije od veli ine ulaza n. Ali sasvim je mogu e i da za neki algoritam


c
c
dobijemo vreme izvravanja izraeno funkcijom, recimo,
T1 (n) = 10n3 + n2 + 40n + 80 .
Ili sli no, za neki drugi algoritam moemo dobiti da je njegovo vreme izvrc
avanja dato funkcijom
T2 (n) = 17n log n 23n 10 .
Ako zamislimo jo komplikovaniji izraz za funkciju vremena izvravanja, postavlja se pitanje da li nam sloenost tog izraza zamagljuje sliku
o odgovaraju em algoritmu? Na primer, da li na osnovu funkcija T1 (n)
c
c
i T2 (n) moemo lako re i koji je od dva algoritma bri? Za odgovor na
ovo pitanje moemo naravno uvek ta no nacrtati uporedo funkcije T1 (n) i
c
T2 (n) i videti za razne vrednosti argumenta n koja od funkcija ima manje
vrednosti, odnosno koji je algoritam bri.
Crtanje i izra unavanje sloenih matemati kih funkcija nije jednostavc
c
no (kao to svi znamo, zar ne?), ali sre om to nije ni potrebno u analizi
c
algoritama. To je zato to analizu algoritama teimo da pojednostavimo
to vie moemo i traimo zapravo samo red veli ine funkcije vremena
c
izvravanja algoritma za velike vrednosti njenog argumenta. Na primer,
ako je n zaista veliko (zamislimo da je n jedan milion ili jedna milijarda),
onda su vrednosti funkcija T1 (n) i n3 priblino jednake. Isto tako, za veliko
n, funkcije T2 (n) i n log n imaju sli ne vrednosti. Zato kaemo za funkciju
c
c
c
T1 (n) da je reda veli ine n3 i za funkciju T2 (n) da je reda veli ine n log n,1
podrazumevaju i da je n veliko.
c
Prema tome, za vreme izvravanja nekog algoritma uzimamo jednostavnu funkciju koja za velike vrednosti njenog argumenta najbolje aproksimira ta nu funkciju vremena izvravanja tog algoritma. To priblino
c
vreme izvravanja se naziva asimptotsko vreme izvravanja. Primetimo
da je ono, u stvari, mera brzine rasta ta nog vremena izvravanja algoc
ritma sa pove anjem broja njegovih ulaznih podataka. U daljem tekstu
c

cemo podrazumevati asimptotsko vreme izvravanja algoritama, ali radi

kratko e izraavanja cesto izostavljamo pridev asimptotsko.


c
Pojednostavljivanje cilja analize algoritama, odnosno odredivanje to

jednostavnijeg asimptotskog vremena izvravanja, opravdano je iz tri ra1 U ra unarstvu se logaritam skoro uvek uzima za osnovu 2, a ne za osnovu 10 ili e. U
c

skladu sa ovom tradicijom, u knjizi ne emo pisati osnovu za logaritam podrazumevaju i da


c
c
je ona 2 ukoliko to nije druga ije naglaeno.
c

3.1. Asimptotsko vreme izvravanja

45

zloga. Prvo, brzina algoritama je naro ito bitna kada je broj ulaznih poc
dataka veliki, jer se vreme izvravanja (skoro) svakog algoritma pove ava
c
sa brojem ulaznih podataka. Ako za isti problem imamo vie algoritama i
treba da odlu imo koji od njih da primenimo za njegovo reavanje, onda je
c
vano za koje vreme oni reavaju taj problem kada je broj ulaznih podataka
vrlo veliki. Naime, obi no je svaki algoritam dovoljno ekasan za mali broj
c
ulaznih podataka. To jest, uglavnom je irelevantno da li neki algoritam
radi, recimo, jednu milisekundu ili pet mikrosekundi za desetak ulaznih
podataka. Ta dva vremena su ionako neprimetna za ljude, ali to da li
algoritam radi pet minuta ili tri meseca za milion ulaznih podataka jeste

svakako zna ajno za odluku da li cemo ga primeniti za reavanje datog


c
problema.
Drugo, za dovoljno velike vrednosti argumenta, vrednost funkcije vremena izvravanja je preovladuju e odredena njenim dominantnim termom.
c

Na slici 3.1 je ovo ilustrovano gracima parova funkcija T1 (n) i n3 , kao i


T2 (n) i n log n. Sa slike se moemo uveriti da su krive za T1 (n) i n3 , kao i
c
za T2 (n) i n log n, vrlo blizu jedna drugoj za velike vrednosti n. To zna i da
ukoliko govorimo o ponaanju tih funkcija za veliko n, moemo smatrati da
su njihove vrednosti skoro jednake, odnosno da asimptotsko vreme izvravanja dva algoritma iz prethodnog primera moemo jednostavnije izraziti
pomo u T1 (n) n3 i T2 (n) n log n.
c
T(n)
T1 (n)

n3

T2 (n)

n log n

S LIKA 3.1: Graci dva para priblinih funkcija.


Tre e, jednostavna funkcija za vreme izvravanja se uzima bez konc
stanti, jer ta na vrednost konstante uz dominantni term nije zna ajna
c
c
za ra unare razli ite snage (mada relativna vrednost tih konstanti moe
c
c
biti vana za funkcije koje rastu istom brzinom). Te konstante odraavaju
uzetu jedinicu mere za vreme izvravanja jedini nih operacija, ali to vreme
c

46

Vreme izvravanja algoritma

je svakako razli ito za, na primer, personalne i super ra unare.


c
c
Da bismo ovo bolje razumeli, pretpostavimo da su A1, A2 i A3 tri

algoritma cija su vremena izvravanja data funkcijama 2n , 5n2 i 100n,


tim redom, gde je n veli ina ulaza. Vrednosti ovih funkcija za razli ite
c
c
vrednosti argumenta n su date u levoj tabeli na slici 3.2. Sa druge strane,
ako se svaki algoritam izvrava na ra unaru koji obavlja jedan milion (106 )
c

instrukcija u sekundi, tada ce se svaki algoritam izvravati u stvarnom

vremenu cije su vrednosti date u desnoj tabeli na istoj slici.


n

2n

5n2

100n

A1

100

1 s

10

1024

500

1000

10

100

100

50000

10000

100

21000

5 106

100000

1000

1000

A2

5 s 100 s

1 ms 0,5 ms
70

A3

1 ms

0,05 s

0,01 s

2970 g

5s

0,1 s

S LIKA 3.2: Vremena izvravanja tri algoritma.


Vrednosti stvarnih vremena izvravanja algoritama u desnoj tabeli na
slici 3.2 jasno pokazuju da je za veliko n (recimo, n > 100) algoritam A1
najsporiji, zatim algoritam A2 srednji, a algoritam A3 najbri. Dakle,
c
c
oblici jednostavnih funkcija od n (tj. 2n , n2 i n) su zna ajniji od ta nih konstantnih faktora (tj. 1, 5 i 100) tih funkcija. Zato da bismo to jednostavnije
i ta nije izrazili asimptotska vremena izvavanja algoritama A1, A2 i A3,
c
dovoljno je uzeti da su njihova vremena izvravanja, redom, T1 (n) = 2n ,
T2 (n) = n2 i T3 (n) = n.

Pojednostavljena analiza algoritama


Asimptotsko vreme izvravanja algoritma ne odreduje se, naravno, tako

to se odredi njegovo ta no vreme izvravanja, pa se onda dobijena funkcija


c
upro ava uzimanjem dominantnog terma koji najbolje opisuje njen red vec
li ine. Podsetimo se da smo upravo hteli da izbegnemo odredivanje ta nog
c
c

vremena izvravanja i uzimanje u obzir nevanih jedini nih instrukcija


c
koje mnogo ne doprinose vremenu izvravanja algoritma za veliki broj ulaznih podataka.
Analiza algoritama se zapravo sprovodi na sli an na in kao i ranije,
c
c
ali se pri tome pojednostavljuje sve ono to ne uti e bitno na odredivanje
c

reda veli ine vremena izvravanja algoritma. To zna i da se i dalje voc


c

3.1. Asimptotsko vreme izvravanja

47

dimo tabelom vremenske sloenosti osnovnih algoritamskih konstrukcija


na strani 26, ali uz zanemarivanje nedominantnih termova dobijenih u
izrazu za funkciju vremena izvravanja koji ne uti u na njen red veli ine
c
c
za velike vrednosti njenog argumenta. Mada se ovaj pristup moe ta nije
c

i formalnije opisati uvodenjem matemati kih pojmova (o cemu govorimo u


c

odeljku 3.2 u nastavku), njegovu sutinu je najbolje razumeti kroz primere.


Kao prvi primer, razmotrimo ovaj algoritamski fragment (koji matricu
c
a dimenzije n n inicijalizuje da bude jedini na matrica):
1
2
3
4
5

for i = 1 to n do
for j = 1 to n do
a[i,j] = 0;
for i = 1 to n do
a[i,i] = 1;

Vreme izvravanja T(n) ovog fragmenta jednako je zbiru vremena izvravanja dve petlje: prve for petlje u prvom redu i druge for petlje

u cetvrtom redu. Kako prva for petlja sadri ugnjedenu for petlju u

drugom redu, isto kao ranije moramo najpre odrediti broj iteracija ovih
petlji i vreme jednog izvravanja tela unutranje petlje, a zatim pomnoiti
ove tri vrednosti.
Poto se telo unutranje petlje u tre em redu izvrava za konstantno
c
vreme, a broj iteracija spoljanje i unutranje petlje jednak je n, ukupno
vreme izvravanja for petlje u prvom redu je neka konstanta pomnoena
sa n2 . Ovu konstantu moemo medutim zanemariti kada je n veliko, pa

zaklju ujemo da je vreme izvravanja prve for petlje reda n2 .


c

Sli no, vreme izvravanja druge for petlje u cetvrtom redu je reda n,
c
jer je broj njenih iteracija jednak n i njeno telo u petom redu se izvrava
za konstantno vreme. Prema tome, ukupno vreme izvravanja T(n) datog
fragmenta je reda n2 + n, ali to moemo dalje uprostiti i zaklju iti da je T(n)
c
reda veli ine n2 , poto funkcija n2 dominira funkcijom n za veliko n.
c
Kao drugi primer razmotrimo algoritamski fragment koji ima istu funkcionalnost kao prethodni primer (tj. matrica a dimenzije n n se inicijalizuje da bude jedini na matrica):
c
1
2
3
4
5
6

for i = 1 to n do
for j = 1 to n
if (i == j)
a[i,j] =
else
a[i,j] =

do
then
1;
0;

48

Vreme izvravanja algoritma

Vreme izvravanja T(n) ovog fragmenta jednako je vremenu izvravanja dve ugnjedene for petlje u prvom i drugom redu. Kako se telo

unutranje petlje sastoji samo od if naredbe u redovima 36, a nije se


teko uveriti da se ta naredba izvrava za konstantno vreme, to zna i da
c
se telo unutranje petlje izvrava za konstantno vreme. Kako je dalje broj
iteracija spoljanje i unutranje petlje jednak n, vreme izvravanja dve
ugnjedene for petlje je neka konstanta pomnoena sa n2 . Prema tome,

poto ovu konstantu moemo zanemariti kada je n veliko, ukupno vreme


izvravanja T(n) datog fragmenta je reda n2 .
Obratite panju na to da smo u prethodnim primerima za odredivanje

asimptotskog vremena izvravanja cesto koristili fraze vreme izvravanja


je reda veli ine, konstanta se moe zanemariti i jedna funkcija dominira
c
drugom funkcijom. To nisu jedine fraze u optem slu aju koje se stalno
c

ponavljaju, zbog cega se uvodi specijalna asimptotska notacija kojom se


izraavanje olakava i dodatno precizira.
Jedan oblik ove notacije je takozvani O-zapis, pa bismo recimo za prethodna dva algoritamska fragmenta kratko rekli da je njihovo vreme izvravanja T(n) = O(n2 ) (ovo se izgovara: veliko o od n2 ). Ovaj saet zapis
obuhvata ne samo to da je njihovo vreme izvravanja reda veli ine n2 za
c
veliko n, nego i ta no odreduje ta podrazumevamo pod time kada kaemo
c

da je jedna funkcija reda veli ine druge funkcije. O ovome cemo mnogo
c
detaljnije govoriti u odeljku 3.2 u nastavku.

Primer: binarna pretraga sortiranog niza


Opti problem pretrage niza (videti 1. zadatak na strani 15) je da, za
dati niz a od n neuredenih brojeva a 1 , a 2, . . ., a n i dati broj x, treba odrediti

da li se broj x nalazi u nizu a. Ukoliko je to slu aj, rezultat treba da bude


c
c
indeks niza i takav da je x = a i ; u suprotnom slu aju, rezultat treba da
bude 0.
U ovom primeru posmatramo specijalni slu aj opteg problema prec
trage kada se dati niz a ne sastoji od neuredenih brojeva, ve je taj niz
c

brojeva sortiran u rastu em redosledu: a 1 a 2 a n . Ovu pretpoc


stavku da je niz sortiran moemo iskoristiti da bismo pretragu broja x u
nizu znatno ubrzali.
Metod koji se primenjuje u specijalnom slu aju sortiranog niza naziva
c
se binarna pretraga i sli an je na inu na koji se trai neka osoba u debelom
c
c
telefonskom imeniku. Naime, da bismo dato ime i prezime neke osobe
pronali u imeniku, najpre bismo imenik otvorili negde na sredini imenika

3.1. Asimptotsko vreme izvravanja

49

i tu pokuali da pronademo eljenu osobu. Ako je tu nema, onda bismo

prezime traene osobe uporedili sa prezimenima osoba na toj srednjoj stranici. Ukoliko je prvo slovo prezimena traene osobe po azbu nom redu iza
c
prvog slova prezimena osoba na srednjoj stranici imenika, pretragu bismo
usmerili na drugu polovinu imenika. Naime, traena osoba se sigurno ne
moe nalaziti u prvoj polovini imenika poto su osobe u imeniku poredane

po azbu nom redu njihovih prezimena (tj. sortirane su u rastu em redoc


c
sledu). Naravno, u drugom slu aju kada je prvo slovo prezimena traene
c
osobe po azbu nom redu ispred prvog slova prezimena osoba na srednjoj
c
stranici imenika, pretragu bismo usmerili na prvu polovinu imenika.
U drugom koraku bismo pretragu nastavili u odgovaraju oj polovini
c
imenika ponavljanjem sli nog postupka. Negde na polovini odgovaraju e
c
c
polovine bismo pokuali da pronademo eljenu osobu, pa ako je tu nema,

pretragu bismo usmerili na jednu od polovina te polovine (tj. cetvrtinu


celog imenika) u kojoj se mora nalaziti traena osoba zavisno od prvog slova
njenog prezimena. U slede em koraku bismo pretragu usmerili na odgovac

raju u polovinu prethodne cetvrtine imenika (tj. osminu celog imenika) i


c
tako dalje. Na ovaj na in, u svakom koraku bismo za faktor dva smanjivali
c
duinu prethodnog dela imenika u kojem se moe nalaziti traena osoba.
Prema tome, ponavljanjem ovih koraka mogu a su dva ishoda: ili se
c
u nekom koraku pronalazi eljena osoba na njenoj stranici imenika, ili se
na kraju duina dela imenika u kome je mogu e na i traenu osobu svodi
c
c
na nulu. Naravno, u prvom slu aju je jasno da se traena osoba nalazi u
c
imeniku, dok u drugom slu aju moemo zaklju iti da se ona ne nalazi u
c
c
imeniku.
Ovaj dui opis ideje binarne pretrage je, nadamo se, dovoljan za lako
razumevanje sli nog postupka za traenje broja x u sortiranom nizu a:
c
// Ulaz:
sortiran niz a, broj elemenata n niza a, traeni broj x
// Izlaz: k takvo da x = a k ili 0 ako se x ne nalazi u nizu a
algorithm bin-search(a, n, x)
i = 1; j = n;
// oblast pretrage je ograniena indeksima i i j
c
while (i <= j) do
k = (i + j)/2;
// indeks srednjeg elementa
if (x < a[k]) then
j = k - 1;
// x se nalazi u prvoj polovini oblasti pretrage
else if (x > a[k]) then
i = k + 1;
// x se nalazi u drugoj polovini oblasti pretrage
else
return k;
// x je naen
d
return 0;
// x nije naen
d

50

Vreme izvravanja algoritma

U algoritmu bin-search se najpre pravilno inicijalizuje oblast pretrage


niza koja je ograni ena donjim indeksom i i gornjim indeksom j. Ta oblast
c
se na po etku naravno protee na ceo niz od prvog do n-tog elementa. Zatim
c
se, sve dok donji indeks oblasti pretrage ne premauje njen gornji indeks
(tj. i j), izra unava indeks k srednjeg elementa oblasti pretrage (pri
c

cemu se podrazumeva celobrojno deljenje brojem dva) i ispituje taj srednji


element a k . Ako ovaj element nije jednak traenom broju x, pretraga se
nastavlja u prvoj ili drugoj polovini oblasti pretrage zavisno od toga da li
je x manje ili ve e od a k . Ako je srednji element jednak traenom broju x,
c
pretraga se prekida i vra a se rezultat k. Na slici 3.3 je ilustrovana prva
c
iteracija binarne pretrage broja x u sortiranom nizu a.
k n/2

a
oblast pretrage
ako je x < a k

x = ak ?

oblast pretrage
ako je x > a k

S LIKA 3.3: Binarna pretraga.


Ako se izvravanje while petlje zavrilo zbog toga to je donji indeks
c
oblasti pretrage premaio njen gornji indeks (tj. i > j), to zna i da se duina
oblasti pretrage niza smanjila do nule. U tom slu aju dakle broj x nije
c
pronaden u nizu a, pa se kao rezultat vra a 0.
c

Da bismo odredili (asimptotsko) vreme izvravanja T(n) algoritma binarne pretrage bin-search, primetimo da je dovoljno samo odrediti vreme
izvravanja njegove while petlje. Ostali delovi tog algoritma (inicijalizacija
oblasti pretrage na po etku i return naredba na kraju) izvravaju se za
c
konstantno vreme, koje je zanemarljivo u odnosu na vreme izvravanja
while petlje kada je duina niza n dovoljno velika.
Sa druge strane, vreme izvravanja while petlje je proporcionalno broju
iteracija te petlje, jer se telo te petlje izvrava za konstantno vreme. U to se
lako moemo uveriti ukoliko primetimo da se telo while petlje sastoji samo
od jedini nih instrukcija, pa je o igledno njihovo ukupno vreme izvravac
c
nja u najgorem slu aju konstantno. Pojednostavljena analiza algoritma
c
bin-search se svodi dakle na odredivanje najve eg broja iteracija while
c

petlje u tom algoritmu.


Medutim, najve i mogu i broj iteracija while petlje nije o igledan, jer
c
c
c

se petlja zavrava kada uslov i j nije ispunjen ili je traeni broj x naden,

a to zavisi od samih brojeva niza a i traenog broja x. Mogu e je da broj x


c

3.1. Asimptotsko vreme izvravanja

51

nademo odmah u prvom koraku ili u nekom koraku posle toga, ali se nije

teko uveriti da se najve i broj iteracija while petlje izvrava kada se broj x
c
ne nalazi u nizu a. Onda se naime prolazi kroz ceo ciklus suavanja oblasti

pretrage od celog niza, zatim jedne polovine niza, pa jedne cetvrtine niza,
pa jedne osmine niza i tako dalje, na kraju do oblasti pretrage od samo

jednog elementa niza, posle cega vie ne vai uslov i j i petlja se zavrava.
c
Koliki je onda najve i broj iteracija while petlje u tom slu aju kada se
c
broj x ne nalazi u nizu a? Obratite panju na to da na ovo pitanje moemo
ne razmiljaju i mnogo odgovoriti da je taj broj najvie n, jer se nikad neki
c
element niza ne ispituje vie od jednom. To je ta no, ali onda bismo mogli
c
c
c
re i i da je taj broj najvie n2 ili n3 ili neto sli no. Ovde se sre emo sa jo
c
jednim svojstvom asimptotskog vremena izvravanja algoritma: iako se
njegova analiza umnogome pojednostavljuje, ipak se trudimo da dobijemo
to ta niju ocenu pravog vremena izvravanja algoritma.
c
Da bismo ta nije odredili najve i broj iteracija while petlje, moramo na
c
c
neki na in na i dobru meru onoga to se zaista deava prilikom izvravanja
c
c
te petlje u algoritmu bin-search. U postupku binarne pretrage sutina je
da duina oblasti pretrage po etno iznosi n, a na po etku svake iteracije
c
c
osim prve, duina oblasti pretrage jednaka je otprilike polovini duine
oblasti pretrage na po etku prethodne iteracije. Drugim re ima, ako m
c
c
ozna ava ukupan broj iteracija while petlje kada se broj x ne nalazi u nizu
c
a, onda:
na po etku prve iteracije, duina oblasti pretrage iznosi n;
c
na po etku druge iteracije, duina oblasti pretrage iznosi otprilike
c
n/2 = n/21;
na po etku tre e iteracije, duina oblasti pretrage iznosi otprilike
c
c
(n/2)/2 = n/4 = n/22;

na po etku cetvrte iteracije, duina oblasti pretrage iznosi otprilike


c
(n/4)/2 = n/8 = n/23;
i tako dalje . . .
na po etku poslednje m-te iteracije, duina oblasti pretrage iznosi
c
otprilike n/2m1.

Ali ono to jo znamo je da se oblast pretrage na po etku poslednje m-te


c
iteracije sastoji od samo jednog elementa niza. Zato mora biti
n
2 m 1

= 1,

52

Vreme izvravanja algoritma

odnosno

n = 2 m 1 .

Sada lako moemo dobiti ukupan broj iteracija m u zavisnosti od broja


elemenata niza n ukoliko poslednju jednakost logaritmujemo za osnovu
dva i dobijenu jednakost reimo po m:
m = log n + 1 .
Najve i broj iteracija while petlje u algoritmu bin-search je dakle
c
reda log n, pa je to i red veli ine vremena izvravanja tog algoritma. Jo
c

bolje, ukoliko primenimo O-zapis, ovu cinjenicu moemo saeto izraziti


izrazom T(n) = O(log n).

Tipicne funkcije vremena izvravanja

Pojednostavljenom analizom algoritma, ciji je cilj odredivanje njegovog

asimptotskog vremena izvravanja za veliki broj ulaznih podataka, dobija


se nekoliko standardnih funkcija koje naj e e opisuju vremena izvravac c
nja algoritama. Poznavaju i zato samo ovaj mali broj funkcija moemo
c
mnogo bre i lake ste i uvid u performanse algoritma.
c
U tabeli 3.1 se nalaze naj e e funkcije koje sre emo u analizi algoric c
c
tama. Te funkcije su navedene redom odozgo na dole po rastu im brzinama
c
rasta za velike vrednosti svog argumenta.
Funkcija

Neformalno ime

konstantna funkcija

log n

logaritamska funkcija

linearna funkcija

n log n

linearno-logaritamska funkcija

n3
2

kvadratna funkcija
kubna funkcija
eksponencijalna funkcija

T ABELA 3.1: Tipi ne funkcije vremena izvravanja algoritama.


c
Funkcije u tabeli 3.1 nisu interesantne u ra unarstvu zbog svoje apc
straktne matemati ke prirode, ve one predstavljaju asimptotska vremena
c
c

3.1. Asimptotsko vreme izvravanja

53

izvravanja algoritama. Uo imo zato da se u toj tabeli svako neformalno


c
ime funkcije odnosi, u stvari, na klasu funkcija iste brzine rasta. Tako,
kvadratnom funkcijom se nazivaju sve funkcije koje su reda veli ine n2 za
c
veliko n. Sli no, za konstantnu funkciju je uobi ajeno da se uzima najproc
c
stiji broj 1 za vrednost konstante, mada vrednost konstantne funkcije moe
biti bilo koji broj nezavisan od n.
Brzina algoritma je dakle bolja ukoliko se njegova funkcija vremena
izvravanja nalazi blie vrhu tabele 3.1. Drugim re ima, jedan algoritam
c
je bri od drugog ukoliko je njegova funkcija vremena izvravanja ispod,
ili neformalno manja od, funkcije vremena izvravanja drugog algoritma.
Radi boljeg razumevanja relativne brzine rasta tipi nih funkcija vremena
c
izvravanja iz tabele 3.1, na slici 3.4 su otprilike prikazani njihovi graci.
T(n)

2n

n3 n2

n log n n

log n

S LIKA 3.4: Tipi ne funkcije vremena izvravanja.


c
Sa slike 3.4 moemo videti da za male vrednosti argumenta n postoje
ta ke u kojima je jedna kriva po etno ispod druge, mada kasnije to nije
c
c
slu aj. Na primer, po etno je kvadratna kriva ispod linearne krive, ali kada
c
c
n postane dovoljno veliko, ta osobina se menja u korist linearne krive. Za
malo n je teko uporedivati funkcije poto su tada konstante vrlo bitne. Na

c
primer, funkcija 7n + 120 je ve a od n2 kada je n manje od 15. Ali, za mali
broj ulaznih podataka se vreme izvravanja obi no meri deli em sekunde,
c
c
pa oko toga ne moramo ni da brinemo.
Na slici 3.4 se vidi da je logaritamska funkcija od neke ta ke uvek ispod
c
ostalih funkcija. To zna i da su logaritamski algoritmi u praksi uvek bri
c
od algoritama ostalih vremenskih sloenosti (osim, naravno, konstantne
funkcije). Obratite ipak panju na to da stvarna vremenska razlika zavisi od konstanti koje u estvuju u izrazima za vremena izvravanja, pa je
c

54

Vreme izvravanja algoritma

mogu e da, recimo, linearno-logaritamski algoritam bude bri od linearnog


c
algoritma za relativno mali broj ulaznih podataka.
Sa druge strane, ono to se potvrduje na slici 3.4 i to upada u o i u
c

tabelama na slici 3.2 jeste da su eksponencijalni algoritmi beskorisni za


veliki broj ulaznih podataka. Eksponencijalni algoritam moemo paljivo

optimizovati i realizovati na vrlo ekasnom mainskom jeziku, ali opet ce


takav algoritam raditi neprihvatljivo dugo za veliki broj ulaznih podataka.
Prema tome, najpametnija programerska poboljanja ili sjajni ra unari ne
c
mogu u initi brzim neki neekasan algoritam. Zbog toga, pre nego to
c
uzalud utroimo vreme na popravku loeg algoritma ili potroimo novac
na bre ra unare, moramo se najpre potruditi da napiemo ekasan algoc
ritam.

3.2

Asimptotska notacija

Iz prethodne diskusije moemo zaklju iti da algoritme uporedujemo


c

prema njihovim funkcijama asimptotskog vremena izvravanja: to je takva funkcija manja, to je algoritam bolji (bri). Obi no je jasno da li
c
je neka funkcija manja od druge, ali za sloenije slu ajeve je potrebno
c
imati precizniju deniciju toga to se podrazumeva kada se tvrdi da je neka
funkcija manja od druge. Asimptotska notacija omogu ava upravo da se
c
na precizan na in uvede relativni poredak za funkcije.
c

Asimptotska notacija ima cetiri oblika: O-zapis (veliko o), -zapis (veliko omega), -zapis (veliko teta) i o-zapis (malo o). S obzirom na to da

se u praksi naj e e koristi O-zapis, u ovom odeljku cemo najve u panju


c c
c
posvetiti tom zapisu. Ali iako u ostalom delu knjige skoro isklju ivo koc

ristimo O-zapis, u nastavku cemo se kratko osvrnuti i na ostale varijante


asimptotske notacije radi kompletnosti.

Jedna napomena: nekim citaocima ce ovo poglavlje izgledati kao suva


matematika naalost ili na sre u, to je najbolji na in da se precizno
c
c

izrazi ono o cemu se govori.

O-zapis
O-zapis se koristi za precizno denisanje svojstva da je neka funkcija
manja od druge. Na po etku napomenimo da za sve funkcije o kojima goc
vorimo, podrazumevamo da su to pozitivne (ili ta nije, nenegativne) funkc
cije, a nenegativnost se podrazumeva i za njihove argumente. Preciznije

3.2. Asimptotska notacija

55

re eno, posmatramo funkcije koje preslikavaju skup prirodnih brojeva N u


c
c
skup nenegativnih realnih brojeva R+ . Ova restriktivnost ne uti e na optost razmatranja, ali se vodimo time da posmatrane funkcije predstavljaju
vremena izvravanja algoritama, koja su prirodno neke pozitivne vrednosti
za neki pozitivni broj ulaznih podataka.
Ako za dve funkcije f i g kaemo da je f manja od g, onda intuitivno
mislimo da je f (n) g(n) za sve vrednosti argumenta n. U stvari, poto nas
interesuje asimptotsko ponaanje funkcija (vremena izvravanja), moemo
c
re i da je f (n) g(n) za sve osim za kona no mnogo vrednosti argumenta
c
n. Ovo je upravo motivacija za O-zapis f (n) = O(g(n)) kojim predstavljamo
svojstvo da je funkcija f manja od funkcija g, odnosno da funkcija g dominira nad funkcijom f .
D EFINICIJA (O- ZAPIS ) Za dve nenegativne funkcije f , g : N R+ kaemo
da je f (n) = O(g(n)) ako postoje pozitivne konstante c i n 0 takve da je f (n)
c g(n) za svako n n 0 .
Zapis f (n) = O(g(n)) formalno dakle zna i da postoji ta ka n 0 takva
c
c
da za sve vrednosti n od te ta ke, funkcija f (n) je ograni ena vredno u
c
c
c
proizvoda neke pozitivne konstante c i funkcije g(n). Drugim re ima, Oc
zapis ozna ava da funkcija g(n) predstavlja asimptotsku gornju granicu za
c

funkciju f (n). Ova cinjenica je ilustrovana na slici 3.5.

g(n)
f (n)

n0

S LIKA 3.5: f (n) = O(g(n)).


Da bismo ovu sliku interpretirali u kontekstu vremena izvravanja
algoritama, pretpostavimo da funkcija f (n) predstavlja vreme izvravanja
T(n) nekog algoritma i da je recimo g(n) = n2 . Sa slike dakle vidimo da ukoliko uspemo da pokaemo da je T(n) = O(n2 ), onda smo zapravo pokazali,
zanemaruju i konstante, da je vreme izvravanja algoritma sigurno ograc
ni eno kvadratnom funkcijom. Primetimo da O-zapisom dobijamo samo
c

56

Vreme izvravanja algoritma

gornju granicu vremena izvravanja. To ipak nije veliki problem, poto


ionako vreme rada algoritama odredujemo za najgori slu aj izvravanja,
c

odnosno pravo vreme rada algoritma ograni avamo najgorim vremenom


c
njegovog izvravanja.
Da bismo za konkretne funkcije pokazali da je T(n) = O(g(n)), moemo
u krajnjem slu aju koristiti formalnu deniciju O-zapisa. Za to je potrebno
c
da nademo konkretne vrednosti za n 0 i c > 0 takve da je T(n) c g(n) za

svako n n 0 . Na primer, pokaimo da je vreme izvravanja algoritma


bubble-sort na strani 34 jednako O(n2 ). Poto smo u ovom slu aju izc
2
ra unali da je T(n) = n n + 1, za n 1 imamo
c
n2 n + 1 n2 + 1 n2 + n2 = 2n2 .
c
Dakle, ako izaberemo n 0 = 1 i c = 2, po deniciji moemo zaklju iti da je
2
T(n) = O(n ).
Prakti ni postupak dobijanja dominiraju e funkcije moe se znatno ubrc
c
zati ukoliko se iskoriste opte osobine O-zapisa. Neke od ovih osobina, koje

zainteresovani citaoci mogu lako dokazati na osnovu denicije, navodimo


u nastavku.
1. Konstantni faktori nisu vani:2 T(n) = O(cT(n)) za svaku pozitivnu
konstantu c > 0. Na primer, u slu aju algoritma bubble-sort moemo
c
2
tvrditi da je T(n) = O(3n ) ukoliko u prethodnom dokazu izaberemo

konstantu c = 2/3. Ili cak moemo tvrditi da je T(n) = O(0.01n2 ) ukoliko


izaberemo konstantu c = 200.
2. Dominantni termi su najvaniji: ako je T(n) = O f (n) + g(n) i g(n) =
O( f (n)), onda je T(n) = O( f (n)). Na primer, opet u slu aju algoritma
c
bubble-sort, odmah moemo zaklju iti da je T(n) = O(n2 ), jer je o ic
c
2
2
2
gledno n n = O(n ) i 1 = O(n ).
3. Pravilo zbira: O f (n) + g(n) = O( f (n)) + O(g(n)). Na primer, ako je
T(n) = O(n) + O(17), onda je T(n) = O(n + 17), odnosno T(n) = O(n) prema
prethodnom pravili jer je 17 = O(n).
4. Pravilo proizvoda: O f (n) g(n) = O( f (n)) O(g(n)). Na primer, ako je
T(n) = n O(1), onda je T(n) = n O(1) = O(n) O(1) = O(n).
2 Pravilo da konstante nisu vane ne treba pogreno razumeti. Prakti ni programeri
c

ponekad danima pokuavaju da jedan algoritam ubrzaju za neki vrlo mali faktor. Ovde
je re samo o tome da elimo dobru optu sliku o algoritmima, koja bez jednostavnosti
c
asimptotske notacije ne bi bila mogu a.
c

3.2. Asimptotska notacija

57

5. Pravilo tranzitivnosti: ako je T(n) = O( f (n)) i f (n) = O(g(n)), onda je


c
T(n) = O(g(n)). Na primer, u slu aju algoritma bubble-sort je T(n) =
O(n2 ). Ali kako je o igledno n2 = O(n3 ), moemo re i da je i T(n) = O(n3 ).
c
c
Poznavaju i ove osobine O-zapisa moemo obi no relativno lako odrec
c
diti dominiraju u funkciju vremena izvravanja jednostavnih algoritama.
c
Za malo sloenije algoritme je potrebno poznavati i relativne odnose nekih
osnovnih funkcija, na primer:
izraz na dominira nad izrazom n b za a > b: na primer, n = O(n3 );
svaka eksponencijalna funkcija dominira nad svakom polinomskom
funkcijom: na primer, n5 = O(2n );
svaka polinomska funkcija dominira nad svakom logaritamskom funkcijom: na primer, (log n)3 = O(n). Primetimo da odavde sledi da je
n log n = nO(n) = O(n2 ).

Paljivi citaoci su moda primetili da je O-zapis unekoliko dvosmislen


i da se postavlja pitanje kako tim zapisom, u stvari, izraavamo vreme
izvravanja nekog algoritma. Recimo, videli smo da za vreme izvravanja
c
algoritma bubble-sort T(n) = n2 n + 1 = O(n2 ) moemo re i na osnovu
3

pravila tranzitivnosti da je i T(n) = O(n ), ili dalje cak i T(n) = O(n10 ).


Sa druge strane, prirodno je traiti najbolju (u smislu najbliu) dominiraju u funkciju za vreme izvravanja. To jest, ako je T(n) = 2n2 + n 1,
c
c
c
to elimo da ocenimo sa T(n) = O(n2 ), a ne tehni ki ta nom ali loijom
ocenom T(n) = O(n3 ). Medutim, prema pravilu da konstantni faktori nisu

vani, moemo bez kraja navoditi blie granice, recimo T(n) = O(0.01n2 ) ili
T(n) = O(0.0001n2 ) i tako dalje.
Da bismo razreili ovaj naizgled kontradiktoran problem, uvek kada je
to mogu e koristimo O-zapis koji je najprostiji. To zna i da je on izraen
c
c
jednim termom i da je konstantni faktor uz taj term jednak broju 1. Treba
ipak imati na umu da su jednostavnost i najbolja ocena u nekim slu ajec
vima suprostavljeni ciljevi, ali ti slu ajevi su sre om retki u praksi.
c
c
Na kraju, primetimo da u radu zloupotrebljavamo simbol =, jer znak
jednakosti nije zapravo simetri an (reeksivan) kada se koristi O-zapis.
c
To zna i da ako je f 1 (n) = O(g(n)) i f 2 (n) = O(g(n)), onda to ne implicira
c
c
da je f 1 (n) = f 2 (n). Striktno govore i, za nenegativnu funkciju g : N R+ ,
O(g(n)) treba denisati kao klasu nenegativnih funkcija:
O(g(n)) = f : N R+ | ( c > 0)( n 0 N)( n n 0 ) f (n) c g(n) .

58

Vreme izvravanja algoritma

Medutim, radi jednostavnosti se nautrb preciznosti tradicionalno vie ko


risti prostija denicija koju smo naveli. Nadamo se da to ne e zbuniti
c

citaoce koji su vie naklonjeni matemati koj korektnosti.


c

-zapis, -zapis i o-zapis


Ba kao to je O-zapis analogan relaciji za funkcije, tako isto moemo
c
c
denisati analogne zapise za relacije i = na slede i na in: f (n) = (g(n))
ako je g(n) = O( f (n)), a f (n) = (g(n)) ako je istovremeno f (n) = O(g(n)) i
f (n) = (g(n)). Poslednji oblik asimptotske notacije, o-zapis, nema svoju
analogiju sa uobi ajenim relacijama poredenja, ali se ponekad moe pokac

zati korisnim za opis asimptotskih relacija medu funkcijama.

D EFINICIJA (- ZAPIS ) Za dve nenegativne funkcije f , g : N R+ kaemo


da je f (n) = (g(n)) ako postoje pozitivne konstante c i n 0 takve da je f (n)
c g(n) za svako n n 0 .
D EFINICIJA (- ZAPIS ) Za dve nenegativne funkcije f , g : N R+ kaemo
da je f (n) = (g(n)) ako je f (n) = O(g(n)) i f (n) = (g(n)).
D EFINICIJA (o- ZAPIS ) Za dve nenegativne funkcije f , g : N R+ kaemo
da je f (n) = o(g(n)) ako za svaku pozitivnu konstantu c postoji konstanta
n 0 takva da je f (n) c g(n) za svako n n 0 .
Denicija -zapisa ukazuje da funkcija g(n) predstavlja asimptotsku
donju granicu za funkciju f (n). Ovaj oblik se obi no koristi u dokazima
c
donjih granica vremena izvravanja kada elimo da pokaemo da se neki
algoritam mora izvriti bar za neko odredeno vreme.

Denicija -zapisa ukazuje da funkcija g(n) predstavlja asimptotski


najbolju ocenu za funkciju f (n). Ukoliko koristimo ovaj oblik u analizi
algoritama, onda ne samo da dajemo gornju granicu za vreme izvravanja
nekog algoritma, nego i njegovu donju granicu. Drugim re ima, vreme
c
izvravanja algoritma je najbolje mogu e ocenjeno. Uprkos ovoj dodatnoj
c
c
c
preciznosti -zapisa ce e se ipak koristi O-zapis, jer je obi no mnogo lake
odrediti samo gornju granicu vremena izvravanja.
Na kraju, denicija o-zapisa ozna ava da je brzina rasta funkcije f (n)
c
reda veli ine manja od brzine rasta funkcije g(n). To zna i da vrednost
c
c
funkcije f (n) postaje mnogo manja u poredenju sa vredno u funkcije g(n)
c

kako n tei beskona nosti, odnosno


c
lim

f (n)
= 0.
g(n)

3.2. Asimptotska notacija

59

Intuitivno zna enje cetiri oblika asimptotske notacije ilustrovano je u


c
tabeli 3.2.
Asimptotska notacija

Intuitivno znacenje

f (n) = O(g(n))

f g

f (n) = (g(n))

f g

f (n) = (g(n))

f g

f (n) = o(g(n))

T ABELA 3.2: Intuitivno zna enje asimptotske notacije.


c
Radi kratke ilustracije prethodnih denicija, ta nije -zapisa, pokac
imo da za vreme izvravanja algoritma bubble-sort vai T(n) = (n2 ).
c
Kako je T(n) = n2 n + 1, a ve smo pokazali da je T(n) = O(n2 ), dovoljno
je samo pokazati da je i T(n) = (n2 ). Po deniciji -zapisa treba dakle da
odredimo pozitivne konstante c i n 0 takve da je
n2 n + 1 cn2 ,
za svako n n 0. Deljenjem ove nejednakosti sa n2 dobijamo
1

1
1
+
c.
n n2

Odavde je jasno da moemo uzeti konstante c = 1/2 i n 0 = 1 tako da prva


nejednakost bude zadovoljena.
Postoji drugi na in da pokaemo da data funkcija zadovoljava neku
c

asimptotsku granicu. Naime, cesto je lake to pokazati pomo u grani nih


c
c
iji lagan dokaz
vrednosti nego direktno po deniciji. Naredna teorema, c

preputamo citaocima, daje dovoljne uslove za razne tipove asimptotskih


granica.
T EOREMA (P RAVILO

LIMESA )

Za nenegativne funkcije f (n) i g(n),

f (n)
= c > 0 f (n) = (g(n))
n g(n)
f (n)
lim
= c 0 f (n) = O(g(n))
n g(n)
lim

60

Vreme izvravanja algoritma


f (n)
= 0 f (n) = (g(n))
n g(n)
f (n)
lim
= 0 f (n) = o(g(n)) ,
n g(n)
lim

gde je c neka konstanta, a u slu aju -zapisa limes moe biti beskona an.
c
c
Pravilo limesa je skoro uvek lake primeniti nego formalne denicije.
Pored toga, mada naizgled to pravilo zahteva da se pokau da vae stroiji
uslovi, ono se moe primeniti u skoro svim prakti nim primerima funkcija
c
vremena izvravanja. Jedini izuzeci su slu ajevi kada grani na vrednost
c
c
c
ne postoji (recimo, f (n) = n sin n ), ali poto su vremena izvravanja obi no
dobre funkcije, to retko predstavlja problem.
c
Na primer, ako treba uporediti funkcije log2 n i n/ log n, moemo izra unati limes njihovog koli nika (pomo u, recimo, Lopitalovog pravila):
c
c
log2 n
= 0.
n n/ log n
lim

Po pravilu limesa je zato log2 n = O(n/ log n).


Treba jo naglasiti da asimptotska notacija ne uvodi totalni poredak
medu funkcijama. To zna i da postoje parovi funkcija koje nisu uporedive,
c

recimo, O-zapisom. To jest, postoje funkcije f (n) i g(n) takve da niti je f (n)
jednaka O(g(n)) niti je g(n) jednaka O( f (n)). Na primer,
f (n) =

n3 , ako je n parno
n,

ako je n neparno

g(n) =

n,

ako je n parno

n , ako je n neparno

takve su neuporedive funkcije, jer nijedna nije veliko-o od druge.

Primer: Euklidov algoritam


U odeljku 2.1 na strani 19 razmotrili smo problem najve eg zajedni kog
c
c
delioca: ako su data dva pozitivna cela broja x i y, odrediti njihov najve i
c
zajedni ki delilac nzd(x, y). Tamo smo pokazali (neekasan) algoritam gcd
c

koji reava taj problem, a ovde cemo predstaviti drugi, Euklidov algoritam
za isti problem koji je mnogo bri.

Ali poto algoritam gcd nismo analizirali u odeljku 2.1, ovde cemo ga
najpre ponoviti da bismo mogli lake da ocenimo njegovo vreme izvravanja
i uporedimo to sa Euklidovim algoritmom.

3.2. Asimptotska notacija

61

// Ulaz: pozitivni celi brojevi x i y


// Izlaz: nzd(x, y)
algorithm gcd(x, y)
d = min{x,y};
while ((x % d != 0) || (y % d != 0)) do
d = d - 1;
return d;

O igledno je vreme izvravanja ovog algoritma proporcionalno broju


c
iteracija while petlje, jer se ostale naredbe izvravaju za konstantno vreme.
Taj broj iteracija sa svoje strane zavisi od ulaznih brojeva x i y. Najbolji slu
caj je kada su ulazni brojevi jednaki, x = y, jer je onda broj iteracija jednak
0. U slu aju kada su ulazni brojevi razli iti, broj iteracija je min{ x, y} 1,
c
c
pa je najgori slu aj kada se ulazni brojevi razlikuju za jedan.
c
Poto je vreme izvravanja algoritma gcd linearna funkcija od manjeg
od dva ulazna broja, da li to zna i da je on brz algoritam? Odgovor je
c
negativan, to je moda neo ekivano s obzirom na to da smo govorili da su
c
linerani algoritmi jedni od najbrih mogu ih algoritama. Objanjenje ove
c
kontroverze sadrano je u odgovoru na pravo pitanje u vezi sa aritmeti kim
c
algoritmom gcd.
Klju no pitanje za analizu svakog aritmeti kog algoritma je: ta je
c
c
zapravo veli ina ulaza za taj algoritam? Na primer, ako algoritam gcd
c
primenimo na dva broja x i y od, recimo, 100 cifara, onda ne moemo
realisti no o ekivati da se aritmeti ke operacije koje u estvuju u izra uc
c
c
c
c
navanju nzd(x, y) mogu obaviti za jednu jedinicu vremena. Stoga u aritmeti kim algoritmima moramo sami realizovati celobrojnu aritmetiku ve e
c
c
ta nosti, odnosno koristiti posebne algoritme za rad sa velikim brojevima.
c
U konkretnom slu aju algoritma gcd radi se o algoritmima za operaciju
c
dodele, ra unanje po modulu i smanjivanje vrednosti promenljive za jedan.
c
Ti algoritmi na ulazu dobijaju (velike) brojeve u obliku niza cifara i njihova
vremenska sloenost nije jedini na, nego zavisi od broja ovih cifara. Zbog
c
toga se i vreme ovih algoritama, koje moe biti poprili no, mora uzeti u
c
obzir prilikom analize aritmeti kh algoritama.
c
Iz ove diskusije se moe naslutiti da je prava mera veli ine ulaza aritc
meti kh algoritama jednaka zbiru broja cifara (ta nije, broja bitova u bic
c
narnom zapisu) njihovih ulaznih brojeva. Naime, sm broj ulaznih brojeva
nije dobra mera, jer je konstantan (na primer, algoritam gcd uvek ima dva
ulazna broja). Ali broj bitova u binarnom zapisu ulaznih brojeva raste sa
magnitudom ulaznih brojeva i time se na pravi na in obuhvata vremenc

62

Vreme izvravanja algoritma

ska sloenost aritmeti kih operacija u zavisnosti od veli ine brojeva koji u
c
c
njima u estvuju.
c
Primenimo ovaj pristup u analizi algoritma gcd. Neka je n 1 broj bitova
binarnog zapisa ulaznog broja x i n 2 broj bitova binarnog zapisa ulaznog
broja y. Mera veli ine ulaza tog algoritma n je dakle zbir brojeva bitova
c
binarnog zapisa ulaznih brojeva: n = n 1 + n 2 . Sada dakle treba, zavisno
od ove prave mere veli ine ulaza za algoritam gcd, oceniti njegovo vreme
c
izvravanja u najgorem slu aju.
c

U takvoj analizi algoritma gcd moemo cak zanemariti cinjenicu da


se osnovne aritmeti ke operacije ne izvravaju za jedini no vreme, jer to
c
c
vreme samo doprinosi ukupnom vremenu izvravanja, koje je u ovom slu
caju ionako veliko i iznosi bar 2n/2 . Da bismo ovo pokazali, primetimo
najpre da je broj bitova binarnog zapisa svakog pozitivnog celog broja a
c
jednak log a +1.3 To zna i da je n 1 log x i n 2 log y, odnosno x 2n1 i
y 2n2 .
U najgorem slu aju algoritma gcd kada su ulazni brojevi susedni, rec
cimo x = y 1, broj njihovih bitova je otprilike podjednak, odnosno n 1
n 2 n/2. Kako je vreme izvravanja tog algoritma T(n) proporcionalno
vrednosti manjeg od dva ulazna broja, to je:
T(n) = (y) = 2n2 = 2n/2 .
To pokazuje da se algoritam gcd izvrava za ekponencijalno vreme, to je
beskorisno za velike brojeve od 100200 cifara.
Jedna oblast primene ra unara u kojoj se problem izra unavanja najvec
c

ceg zajedni kog delioca velikih brojeva cesto pojavljuje jeste kriptograja.
c
Bez preterivanja moemo re i da mnoge vane oblasti ljudske delatnosti
c
(vojska, nansije, Internet, . . . ) ne bi mogle da funkcioniu bez ekasnog
algoritma za njegovo reavanje. Sre om, takav algoritam je bio poznat jo
c
u anti kim vremenima i naziva se Euklidov algoritam. Ovaj algoritam se
c

zasniva na slede oj prostoj cinjenici:


c
T EOREMA (E UKLID ) Ako su x i y pozitivni celi brojevi takvi da x y,
onda je nzd(x, y) = nzd(y, x%y).
Dokaz: Dovoljno je pokazati da su skupovi zajedni kih delilaca celobrojc
nih parova brojeva (x, y) i (y, x%y) jednaki, jer su onda i njihovi najve i
c
3 Ako je r neki realan broj, tada r (engl. oor) ozna ava celobrojni deo realnog broja
c

c
r, odnosno najve i ceo broj manji ili jednak r. Prema tome, 7.51 = 7 i 7 = 7. Sli no, r
c
(engl. ceiling) ozna ava najmanji ceo broj ve i ili jednak r. Prema tome, 7.51 = 8 i 7 = 7.
c
c

3.2. Asimptotska notacija

63

zajedni ki delioci jednaki. U tom cilju, svaki ceo broj koji deli oba broja x
c
i y bez ostatka, mora deliti bez ostatka i brojeve y i x%y = x k y, (k N).
Obrnuto, svaki ceo broj koji deli bez ostatka i y i x%y = x k y, (k N), mora
deliti bez ostatka kako x = x%y + k y, (k N), tako i y.
Uz primedbu da svaki pozitivan ceo broj x deli broj 0 bez ostatka i da
c
c
zato nzd(x, 0) = x, najve i zajedni ki delilac dva broja moemo lako izra
cunati uzastopnim ponavljanjem jednakosti iz Euklidove teoreme. Neki
primeri tog izra unavanja za razne parove brojeva su:
c
nzd(1055, 15) = nzd(15, 5) = nzd(5, 0) = 5
nzd(400, 24) = nzd(24, 16) = nzd(16, 8) = nzd(8, 0) = 8
nzd(101, 100) = nzd(100, 1) = nzd(1, 0) = 1
nzd(34, 17) = nzd(17, 0) = 17
nzd(89, 55) = nzd(55, 34) = nzd(34, 21) = nzd(21, 13) =
= nzd(13, 8) = nzd(8, 5) = nzd(5, 3) =
= nzd(3, 2) = nzd(2, 1) = nzd(1, 0) = 1

Na osnovu ovih primera se moe otkriti Euklidov postupak kojim se


dobija najve i zajedni ki delilac dva broja: dati par brojeva se transformie
c
c

u niz parova, pri cemu je prvi broj narednog para jednak drugom broju
prethodnog para, a drugi broj narednog para jednak je ostatku celobrojnog
deljenja prvog broja sa drugim brojem prethodnog para. Poslednji par u
nizu je onaj kod koga je drugi broj jednak nuli, a onda je najve i zajedni ki
c
c
delilac po etnog para jednak prvom broju tog poslednjeg para.
c
Ispravnost ovog postupka je o igledna na osnovu Euklidove teoreme, ali
c

se postavlja pitanje da li ce se niz parova jedne transformacije sigurno zavriti za svaki po etni par pozitivnih celih brojeva (x, y) takvih da x y. Da
c
je to slu aj nije se teko uveriti ukoliko primetimo da je drugi broj narednog
c
para uvek striktno manji od drugog broja prethodnog para. To sledi prosto
zato to je uvek x%y < y. Prema tome, ovo smanjivanje drugih brojeva u
parovima niza jedne transformacije ne moe se beskona no produiti, jer
c
najgori slu aj tih brojeva u nizu je y, y 1, y 2, . . . , 1, 0.
c
Precizniji opis Euklidovog algoritma na pseudo jeziku je:
// Ulaz: celi brojevi x i y takvi da x y > 0
// Izlaz: nzd(x, y)
algorithm euclid(x, y)
while (y > 0) do
z = x % y;

64

Vreme izvravanja algoritma

x = y;
y = z;
return x;

Preostaje jo da odredimo vreme izvravanja Euklidovog algoritma kako


bismo se uverili da je vrlo ekasan. U stvari, pokaza emo da je vreme
c
3

izvravanja Euklidovog algoritma T(n) = O(n ), pri cemu je n = n 1 + n 2 i n 1


i n 2 su brojevi bitova binarnog zapisa ulaznih brojeva x i y. To je ogromno,
eksponencijalno ubrzanje u odnosu na prvi algoritam gcd.
Pre svega, primetimo da u vremenu izvravanja Euklidovog algoritma
dominira broj iteracija while petlje u algoritmu euclid. Primetimo i da je
taj broj ekvivalentan duini niza parova jedne transformacije od po etnog
c
para (x, y). Ali pitanje duine niza parova jedne transformacije je delikatno. Sa jedne strane, kao to moemo videti iz datih primera izra unavac
nja za razne parove, neki parovi brojeva zahtevaju dve-tri transformacije,
dok je kod drugih parova brojeva odogovaraju i niz transformacija znatno
c
dui. Sa druge strane, kada smo utvrdili da je niz parova jedne transformacije uvek kona an, prakti no smo pokazali da je njegova duina najvie
c
c
y. Ova gruba ocena nas medutim ne zadovoljava, jer time ne bismo dobili

nita bolje vreme od onog za prvi algoritam gcd.


Ta nija ocena vremena izvravanja Euklidovog algoritma zasniva se na
c
slede oj cinjenici:
c
L EMA Ako je x y > 0, onda je x%y < x/2.
Dokaz: Mogu a su dva slu aja: y x/2 ili y > x/2. U prvom slu aju je
c
c
c
c
x%y < y x/2. U drugom slu aju je x%y = x y < x/2.
Pretpostavimo da u algoritmu euclid za ulazne brojeve x i y, x y,
c
imamo m iteracija while petlje pre njene poslednje iteracije. Ozna imo
ulazne brojeve algoritma sa x0 i y0 da ih ne bismo meali sa promenljivim
x i y u telu while petlje. Pretpostavimo dalje da se izvravanjem while
petlje dobija niz parova brojeva:
(x0 , y0 ) (x1 , y1 ) (x2 , y2 ) (xm , ym ) (xm+1 = nzd(x, y), ym+1 = 0) ,
gde (x i , yi ) ozna ava par brojeva koji su vrednosti promenljivih x i y u telu
c
while petlje nakon izvravanja i-te iteracije.

Kako bismo sada ocenili broj iteracija while petlje m, najpre cemo
c
oceniti proizvod parova brojeva x i yi primenjuju i prethodnu lemu vie
puta:

3.2. Asimptotska notacija

65

nakon prve iteracije je x1 = y0 i y1 = x0 %y0 , a kako je x0 y0 to je na


osnovu leme:
x1 y1 = y0 (x0 %y0 ) < x0 y0 /2
nakon druge iteracije je x2 = y1 i y2 = x1 %y1 , a kako je x1 y1 to je
na osnovu leme i prethodne nejednakosti:

x2 y2 = y1 (x1 %y1 ) < x1 y1 /2 < x0 y0 /22


nakon tre e iteracije je x3 = y2 i y3 = x2 %y2 , a kako je x2 y2 to je na
c
osnovu leme i prethodne nejednakosti:

x3 y3 = y2 (x2 %y2 ) < x2 y2 /2 < x0 y0 /23


i tako dalje . . .
nakon m-te iteracije je xm = ym1 i ym = xm1 %ym1 , a kako je xm1
ym1 to je na osnovu leme i prethodne nejednakosti:

xm ym = ym1 (xm1 %ym1 ) < xm1 ym1 /2 < x0 y0 /2m


Kako je svakako xm ym 1, a x0 i y0 su ulazni brojevi x i y, na osnovu
poslednje nejednakosti sledi da je x y/2m > 1, odnosno x y > 2m . Logaritmovanjem ove nejednakosti za osnovu dva napokon dobijamo ocenu za m:
m < log x y = log x + log y < n 1 + n 2 = n .
Obratite panju na to da je ovo klju na ocena za veliku ekasnost Euc
klidovog algoritma: broj iteracija while petlje u algoritmu euclid je uvek
manji ili jednak zbiru brojeva bitova binarnog zapisa ulaznih brojeva. Uporedite to sa nekasnim algoritmom gcd u kome je taj broj iteracija eksponencijalno rastao sa zbirom brojeva bitova binarnog zapisa ulaznih brojeva!
Vreme izvravanja T(n) Euklidovog algoritma ipak nije optimalna linearna funkcija od n, jer T(n) obuhvata i vreme za osnovne aritmeti ke opec
racije koje nad velikim brojevima nisu jedini ne instrukcije. Ovde o tome
c

ne emo mnogo govoriti, nego cemo samo kratko napomenuti da je izra uc


c
navanje ostatka o igledno najskuplja operacija, ali da se lako moe realic

zovati tako da njeno vreme izvravanja bude O(n2 ). Zainteresovani citaoci


mogu to i sami pokazati ukoliko primete da se izra unavanje ostatka svodi
c
na deljenje, a za deljenje se moe primeniti obi an postupak za ru no
c
c
deljenje celih brojeva sa ostatkom.

66

Vreme izvravanja algoritma

Uz ostala upro avanja moemo dakle uzeti da je vreme izvravanja


c
jedne iteracije while petlje u algoritmu euclid jednako O(n2 ). Stoga,
ukupno vreme izvravanja ovog algoritma je:
T(n) = O(m)O(n2 ) = O(n)O(n2 ) = O(n3 ) .

Zadaci
1. Odredite (asimptotsko) vreme izvravanja slede ih algoritamskih fragc
menata:
a)

if (x == 0) then
for i = 1 to n do
a[i] = i;

b)

i = 1;
repeat
a[i] = b[i] + c[i];
i = i + 1;
until (i == n);

c)

if (x == 0) then
for i = 1 to n do
for j = 1 to n do
a[i,j] = 0;
else
for i = 1 to n do
a[i,i] = 1;

d)

for i = 1 to n do
for j = 1 to n do
for k = 1 to j do
if (i == j) then
a[k,k] = 0;

e)

i = 0; k
while (k
k = 2
i = i

= 1;
<= n) do
* k;
+ 1;

f)

for i = 1 to n/2 do
for j = i downto 1 do
if (j % 2 == 0) then
a[i,j] = b[i] + c[j];

2. Napiite ekasan algoritam za nalaenje najve eg i drugog najve eg elec


c
menta niza a od n brojeva. Odredite vreme izvravanja tog algoritma.
3. Ternarna pretraga. Binarnu pretragu na nalaenje broja x u sortiranom nizu a od n brojeva moemo modikovati na slede i na in. Ako
c
c
je oblast pretrage u sortiranom nizu a indeksirana od i do j, najpre
izra unavamo ta ku k koja se nalazi na otprilike 1/3 te oblasti, tj. k =
c
c
(2 i + j)/3 , a zatim uporedujemo traenu vrednost x sa elementom

c
a k . U slu aju kada nisu jednaki, postupamo tako to ukoliko je x <
a k , pretragu nastavljamo u oblasti od i do k 1. A ukoliko je x > a k ,

3.2. Asimptotska notacija

67

izra unavamo ta ku m koja se nalazi na otprilike 2/3 po etne oblasti,


c
c
c
c
tj. m = (i + 2 j)/3 , i uporedujemo x sa a m . Drugim re ima, elimo

da izolujemo x u ta no jednoj od tri podoblasti duine jedna tre ina


c
c
polazne oblasti od i do j. Napiite algoritam kojim se realizuje ova tzv.
ternarna pretraga. Moete li da odredite njegovo vreme izvravanja
T(n) i uporedite ga sa vremenom izvravanja binarne pretrage?
4. Sportski navija . Posmatrajmo niz a veli ine n koji sadri samo crvene
c
c
i bele elemente u proizvoljnom redosledu. (Crveno i belo su hipoteti ki
c
zvani ne boje nekog sportskog tima.) Pretpostavljaju i da je proveravac
c
nje boje nekog elementa jedini na instrukcija, cilj je da se niz preuredi
c
tako da se svi crveni elementi nalaze na po etku, a svi beli elementi
c
da se nalaze iza njih na kraju niza a. Na slici 3.6 je ilustrovan zavrni
rezultat.
a

crveno

belo

S LIKA 3.6.
Navedite bar dva algoritma za reenje ovog problema i odredite vreme
izvravanja svakog od njih.
5. Srpska zastava. Posmatrajmo niz a veli ine n koji sadri crvene, plave i
c
bele elemente u proizvoljnom redosledu. Pretpostavljaju i da je proverac
vanje boje nekog elementa jedini na instrukcija, cilj je da se niz preuredi
c
tako da se svi crveni elementi nalaze na po etku, svi plavi elementi da
c
se nalaze u sredini, a svi beli elementi da se nalaze na kraju niza a. Na
slici 3.7 je ilustrovan zavrni rezultat.
a

crveno

plavo

belo

S LIKA 3.7.
Navedite bar dva algoritma za reenje ovog problema i odredite vreme
izvravanja svakog od njih.
6. Dokaite pravilo limesa na strani 59.

68

Vreme izvravanja algoritma

7. Formalno dokaite slede e asimptotske relacije:


c
a) 10n3 + n2 + 40n + 80 = (n3 )
b) 17n log n 23n 10 = (n log n)
c) n log n = O(n2 )
d) log2 n = O(n)
e) log n = O( n)
f) nlog n = O(2n )
g) sin n = O(1)
8. U svakom od ovih slu ajeva odredite da li je f (n) = O(g(n)) ili f (n) =
c
(g(n)) ili f (n) = (g(n)).
a) f (n) = n + 100,
b) f (n) = n1/2 ,

g(n) = n + 200

g(n) = n2/3

c) f (n) = 10n + log n,

g(n) = n + log2 n

d) f (n) = n log n,

g(n) = 10n log10n

e) f (n) = log 2n,

g(n) = log 3n
g(n) = n log2 n

f) f (n) = n / log n,
g) f (n) = (log n)log n ,
log n

h) f (n) = (log n)
i) f (n) =

g(n) = 2n

j) f (n) = nlog n ,
l) f (n) = 2n ,

g(n) = 2log

g(n) = log3 n

n,

k) f (n) = n2n ,

g(n) = n

g(n) = 3n
g(n) = 2n/2

m) f (n) = n!,

g(n) = 2n

n) f (n) = n!,

g(n) = n n

o) f (n) =

n
k
i =1 i ,

g(n) = n k+1

9. Poredajte slede e funkcije po brzini njihovog rasta za velike vrednosti


c

argumenta n:
n, log n, loglog n, log2 n,

n
, n! , n log2 n,
log n

log n

, (1/3)n , (3/2)n , 17

10. Ako su x i y pozitivni celi brojevi, dokaite slede e cinjenice o njihovom


c
najve em zajedni kom deliocu.
c
c

3.2. Asimptotska notacija

69

a) Ako je x = 2a i y = 2b, onda je nzd(x, y) = 2 nzd(a, b).


b) Ako je x = 2k a i y = 2k b za k 0, onda je nzd(x, y) = 2k nzd(a, b).
c) Ako je x paran i y neparan, onda je nzd(x, y) = gcd(x/2, y).
d) Ako je x y, onda je nzd(x, y) = nzd(x y, y).

11. Koriste i poslednju cinjenicu iz prethodnog zadatka napiite algoritam


c
za izra unavanje najve eg zajedni kog delioca pozitivnih celih brojeva
c
c
c
x i y. (Savet: Ako je x = y, nzd(x, y) = x; ako je x > y, nzd(x, y) = nzd(x
y, y); ako je x < y, nzd(x, y) = nzd(y x, x).) Pored toga, odredite vreme
izvravanja tog algoritma.
12. Razmotrimo drugu verziju Euklidovog algoritma za izra unavanje najc
ve eg zajedni kog delioca pozitivnih celih brojeva x i y. Najpre se izrac
c

cunava najve i stepen broja 2 koji deli oba broja x i y neka je to 2k .


c
Zatim se x zamenjuje sa rezultatom deljenja x sa 2k i y se zamenjuje sa
rezultatom deljenja y sa 2k . Nakon ove prethodne obrade, ponavlja se
slede i postupak:
c
1. Zameniti brojeve ako je to neophodno da bismo imali x y.
2. Ako je y > 1, onda proveriti parnost brojeva x i y. Ako je jedan od
tih brojeva paran i drugi neparan, zameniti paran broj njegovom
polovinom, tj. x sa x/2 ako je x paran ili y sa y/2 ako je y paran. Ako
su x i y neparni brojevi, zameniti x sa x y. Nakon toga, u svakom
slu aju, ponoviti postupak od koraka 1.
c
3. Ako je y = 1, onda vratiti 2k kao rezultat.
4. Ako je y = 0, onda vratiti 2k x kao rezultat.
Za ovu verziju Euklidovog algoritma uradite slede e:
c
a) Izra unajte nzd(18, 8) primenjuju i prethodni postupak korak po
c
c
korak.

b) Cini se da smo u koraku 2 zaboravili slu aj kada su oba broja x i y


c
parna. Pokaite da se to nikad ne moe desiti.
c) Pokaite da se ovaj modikovan Euklidov algoritam uvek zavrava
ta nim odgovorom.
c
d) Pokaite da se proizvod dva aktuelna broja u promenljivim x i
y smanjuje za faktor dva u bar jednoj od svake dve sukcesivne
iteracije prethodnog postupka. Drugim re ima, ako je (x0 , y0 ) par
c
brojeva u koraku 1 neke iteracije tog postupka i (x2 , y2 ) par brojeva

70

Vreme izvravanja algoritma


dobijen u koraku 2 nakon dve sukcesivne iteracije tog postupka,
tada je x2 y2 x0 y0 /2.
e) Izvedite gornju granicu za broj iteracija ovog algoritma.

13. Proireni Euklidov algoritam. Euklidovim algoritmom se izra unava


c
vie nego samo najve i zajedni ki delilac dva pozitivna cela broja x i y.
c
c
Naime, ako primenimo Euklidov algoritam za izra unavanje nzd(x, y),
c
svi medubrojevi dobijeni tokom izra unavanja se mogu predstaviti kao
c

zbir dva proizvoda: jedan sabirak je proizvod broja x i nekog celog broja,
a drugi sabirak je proizvod broja y i nekog drugog celog broja. Koriste i
c
ovo zapaanje dokaite slede u cinjenicu:
c
T EOREMA nzd(x, y) se moe predstaviti kao linearna kombinacija brojeva x i y u obliku nzd(x, y) = ax + b y, gde su a i b celi brojevi (koji ne
moraju biti pozitivni).
Napiite proireni Euklidov algoritam koji izra unava ne samo nzd(x, y),
c
nego i cele brojeve a i b iz prethodne teoreme za koje vai nzd(x, y) =
ax + b y.

G LAVA

4
Osnovne strukture podataka

U ovom poglavlju izu avamo neke od najfundamentalnijih struktura


c
podataka u programiranju. Tu spadaju najpre nizovi i liste, koje predstavljaju sekvence elemenata. Zatim izu avamo dva specijalna slu aja listi:
c
c
stekove, kod kojih se elementi dodaju i uklanjaju samo sa jednog kraja,

kao i redove za cekanje, kod kojih se elementi dodaju na jednom kraju i


uklanjaju sa drugog kraja. Za svaku od ovih struktura podataka opisa emo
c
nekoliko konkretnih realizacija i uporediti njihove dobre i loe strane.

4.1

Opte napomene

Svaki vii programski jezik obezbeduje neke primitivne tipove poda


taka. Njihov repertoar se razlikuje od jezika do jezika, ali ve ina jezika
c
sadri celobrojni, realni, logi ki, znakovni i pokaziva ki tip podataka. Pric
c
mitivni tipovi podataka predstavljaju osnovne gradivne elemente za konstruisanje sloenih tipova podataka. Svaki programski jezik propisuje i
pravila za konstruisanje sloenih tipova podataka polaze i od primitivnih
c
tipova, koja se takode razlikuju od jezika do jezika. Najjednostavniji na in
c

1
za strukturiranje podataka u ve ini viih programskih jezika je niz.
c
Realizacija apstraktnog tipa podataka u ra unaru zahteva prevodenje
c

njegovog logi kog opisa (specikacije) u naredbe odredenog programskog


c

1 Jo jedan na in za grupisanje podataka u svim programskim jezicima je datoteka


c
(engl. le), ali datoteke ne emo koristiti u ovoj knjizi.
c

72

Osnovne strukture podataka

jezika. Ovo prevodenje obuhvata upotrebu primitivnih tipova podataka

programskog jezika kao gradivnih elemenata i kori enje raspoloivih mec


hanizama strukturiranja za njihovo grupisanje. Na taj na in se dobija odc
govaraju a struktura podataka, odnosno kolekcija elemenata povezanih na
c
odreden na in i skup operacija dozvoljenih nad tom kolekcijom elemenata.
c

Pod elementom se ovde podrazumeva podatak kome tip nije preciziran zato
to nije bitan.
Operacije koje su denisane nad strukturama podataka se veoma razlikuju od strukture do strukture, ali sve strukture imaju bar dve zajedni ke operacije: jednu za dodavanje novih elemenata kolekciji postoje ih
c
c
elemenata koji sa injavaju odgovaraju u strukturu podataka, kao i onu za
c
c
uklanjanje starih elemenata iz kolekcije elemenata. Ovde bi mogli dodati i
operaciju za konstruisanje potpuno nove, prazne strukture podataka. Medutim, ona umnogome zavisi od konkretnog programskog jezika, a poto su

detalji prili no trivijalni i uglavnom nas interesuju vremena izvravanja


c

sloenijih operacija, obi no cemo presko iti ovu operaciju konstruktora


c
c
strukture podataka. Pored toga, iz naeg idealizovanog ugla gledanja zanemari emo i ostale implementacione detalje, kao to su provera greaka i
c
oslobadanje memorije onih elemenata koji vie nisu potrebni.

U ostale tipi ne operacije nad strukturama podataka spadaju odredic

vanje da li se dati element nalazi u nekoj strukturi podataka, preuredivanje elemenata strukture podataka u nekom redosledu, odredivanje

broja elemenata strukture podataka (tj. njene veli ine) i tako dalje. Uopc
teno govore i, operacije nad strukturama podataka se mogu podeliti u dve
c
kategorije: (a) upite, koji kao rezultat daju neku informaciju o strukturi
podataka ne menjaju i je, i (b) modikuju e operacije, koje menjaju sadraj
c
c
strukture podataka.
Vreme za izvravanje neke operacije nad strukturom podataka izraava se u funkciji od veli ine strukture podataka. To ima smisla, jer je pric
rodno pretpostaviti da vreme za neku operaciju zavisi od broja elemenata
u strukturi podataka nad kojima se primenjuje. Na primer, ako niz ima
n elemenata, vreme za operaciju kojom se odreduje da li se dati element

nalazi u nizu zavisi od duine niza n.


Dodatne konvencije pseudo jezika. Kako bismo mogli da pokaemo
konkretne implementacije sloenijih struktura podataka, u pseudo jeziku
pretpostavljamo da nam na raspolaganju stoji prakti no sve ono to (dic
rektno ili indirektno) obezbeduju moderni programski jezici. To obuhvata

c
pokaziva ki tip podataka i mogu nost rada sa nizovima.
c

4.2. Nizovi

73

U prezentaciji neke strukture podataka uglavnom primenjujemo proceduralni pristup, mada koristimo i neke rudimentarne koncepte objektno
orijentisanog programiranja. Naime, poto se elementi struktura podataka
obi no sastoje od vie delova, pogodno ih je smatrati objektima koji sadre
c
unutranja polja za razli ite podatke. (Medutim, mogu nost da objekti
c
c

sadre metode ne emo koristiti.)


c
Ako neki pokaziva ukazuje na objekat, taj objekat i njegov pokaziva
c
c

radi jednostavnosti cesto poistove ujemo u izlaganju. Tako, umesto rogoc


batne fraze pokaziva x koji ukazuje na neki objekat (element) kaemo
c
prostije objekat (element) x misle i zapravo na objekat (element) na koga
c
ukazuje pokaziva x. Isto tako, ako pokaziva x ukazuje na objekat koji
c
c
sadri polje y, sadraj tog polja ozna avamo zapisom x.y. Specijalna vredc
nost pokaziva a kojom se ne ukazuje ni na jedan objekat ozna ava se sa
c
c
null.2

4.2 Nizovi
Niz (engl. array) je osnovni na in strukturiranja podataka u programic
ranju i zato se koristi u skoro svim programskim jezicima. Pretpostavljamo

da su se citaoci ve sretali u programiranju sa nizovima i zbog toga o njima


c
ovde ne emo govoriti na elementarnom nivou. U stvari, nizove smo ve
c
c

intezivno koristili u prethodnom poglavlju i nadamo se da citaoci bez predznanja o nizovima nisu imali problema da razumeju njihovu jednostavnu
prirodu. Ipak, s obzirom na to da su primene nizova brojne i raznovrsne,

ovde cemo radi kompletnosti ista i njihove konceptualne osobine. Pored


c

toga, u ovom odeljku cemo pokazati jo dva interesantna primera njihove


primene, a u drugim odeljcima njihovu primenu u realizaciji sloenijih
struktura podataka.
Niz je struktura podataka koja predstavlja sekvencu elemenata istog
tipa. Sekvencijalna uredenost niza ogleda se u numeraciji njegovih eleme
nata, redom, od prvog do poslednjeg. Redni broj nekog elementa u nizu
se naziva indeks elementa. Ime niza grupno ozna ava sve elemente niza
c
kao jednu celinu. Za ozna avanje pojedina nih elemenata niza koristi se
c
c
zapis koji se sastoji od imena niza i indeksa odgovaraju eg elementa niza.
c
(Podsetimo se da u ovoj knjizi indeksi niza po inju od 1 i da koristimo zapis
c
indeksa u uglastim zagradama.) Ukupan broj elemenata niza se naziva
2 Citaoci koji poznaju Javu mogu ovde prepoznati elemente tog programskog jezika.

74

Osnovne strukture podataka

duina ili veli ina niza. Na primer, niz a duine 100 se sastoji od 100
c

elemenata istog tipa ciji je izgled prikazan na slici 4.1.


a

a[1]

a[2]

a[3]

a[100]

S LIKA 4.1: Niz a od 100 elemenata.


Dve glavne osobine nizova su:
1. Svi elementi niza moraju biti istog tipa. Ova osobina homogenosti,
medutim, ne zna i da postoji neko ograni enje za taj tip, odnosno tip
c
c

pojedina nih elemenata niza moe biti bilo koji, ma kako sloen.
c
2. Duina niza mora biti unapred zadata i ne moe se menjati.
Upravo ove osobine nizova omogu avaju njihovu jednostavnu zi ku rec
c
prezentaciju u memoriji ra unara. Naime, ta memorijska reprezentacija je
c
isklju ivo neka vrsta sekvencijalne alokacije, odnosno elementi niza zauzic
maju neprekidni niz susednih memorijskih lokacija. Zato se prakti no i ne
c
razdvaja logi ki koncept niza od njegove zi ke memorijske reprezentacije.
c
c
Primetimo da se ukupna veli ina potrebne memorije za neki niz lako
c
odreduje kao proizvod broja elemenata i veli ine jednog elementa tog niza.
c

Ove dve vrednosti su unapred poznate, jer se duina niza mora unapred
nazna iti, a veli ina jednog elementa je poznata na osnovu tipa elemenata
c
c
niza. Ali ono to je jo vanije, lokacija svakog elementa niza se lako
izra unava, nezavisno od indeksa elementa: ako je prvi element na lokaciji
c
a i veli ina jednog elementa je b bajtova, onda se i-ti element niza nalazi
c
c
na lokaciji a + (i 1)b. Ovo zna i da je vreme pristupa svim elementima

niza konstantno, odnosno da se u algoritmima operacija citanja ili pisanja


nekog elementa niza moe smatrati jedini nom instrukcijom.
c
Prema tome, niz je koncepcijski jednostavna i ekasna struktura podataka koju treba koristiti kad god je to mogu e. Treba ipak imati u vidu
c
da je struktura niza neprakti na u slu ajevima kada se radi o elementima
c
c
razli itih tipova ili njihov priblian ukupan broj nije unapred poznat. Ovaj
c
drugi nedostatak se moe prevazi i zadavanjem neke maksimalne duine
c
niza, ali to obi no dovodi do loe iskori enosti memorijskog prostora rezerc
c
visanog za niz. Pored toga, operacije dodavanja ili uklanjanja elemenata
na proizvoljnoj poziciji niza nisu ekasne, jer dovode do pomeranja svih
elemenata od date lokacije do kraja niza za jedno mesto udesno ili ulevo.

4.2. Nizovi

75

Zbog toga struktura niza nije pogodna ni u slu ajevima kada su ovakve
c
operacije dominantne.

Primer: linearni algoritam za maksimalnu sumu podniza


Sa problemom maksimalne sume podniza upoznali smo se na strani 29:
treba odrediti najve u sumu svih podnizova datog niza brojeva. Preciznije,
c
j
c
za dati niz a od n brojeva a 1 , a 2, . . ., a n , ukoliko sa S i, j = k= i a k ozna imo
sumu svih elemenata podniza sa indeksima od i do j, onda treba odrediti
maksimalnu vrednost M ovih suma:
M = max S i, j .
1 i j n

Podsetimo se da se kvadratni algoritam za reenje ovog problema sastoji od dva koraka. U prvom koraku se odreduje drugi niz b od n eleme

nata b 1 , b 2 , . . ., b n , pri cemu je element b i jednak parcijalnom maksimumu


suma elementa od i-te pozicije niza:
b i = max S i,i , S i,i+1 , . . ., S i,n = max S i, j .
j = i,...,n

U drugom koraku se zatim odreduje vrednost M:

M = max { b 1 , b 2 , . . ., b n } = max b i .
i=1,...,n

Malo poboljanje ove opte strategije u kvadratnom algoritmu sastoji


se u tome da se dva prethodna koraka ne razdvajaju, nego da se za svako
c
c
i = 1, . . ., n redom izra unavaju sume S i,i ,S i,i+1 , . . . , S i,n koriste i jednakost S i, j = S i, j 1 + a j i istovremeno odreduje njihov maksimum. Znatno

poboljanje, medutim, zahteva bolji uvid u izra unavanje maksimuma M


c

elementa niza b kako bi se to postiglo u jednom prolazu ispituju i ulazni


c
niz sleva na desno. Dobijeni linearni algoritam je tipi ni primer opte zakoc
nomernosti: ekasniji algoritmi moraju iskoristiti prirodu samog problema
na dublji na in. Primetimo i da je zato ispravnost ekasnijih algoritama
c
mnogo manje o igledna i da stoga zahteva paljiviji dokaz.
c
Kvadratno vreme za nalaenje maksimalne sume podniza moemo drasti no smanjiti do linearnog vremena ukoliko obratimo ve u panju na
c
c
c
sume S i,i ,S i,i+1 , . . ., S i,n koje se izra unavaju u i-tom koraku radi odredivanja elementa b i niza b. Ove sume koje se redom izra unavaju zadovoc

ljavaju jedan od ova dva uslova: ili su one sve nenegativne ili su neke od

76

Osnovne strukture podataka

njih negativne. Prvo zapaanje je da u oba slu aja moemo izbe i mnoga
c
c
naredna izra unavanja elemenata niza b.
c
L EMA 1 Za svako i {1, 2, . . ., n},
1) Ako su sve sume S i,i ,S i,i+1 , . . ., S i,n nenegativne, odnosno S i, j 0 za
svako j = i, i + 1, . . ., n, onda je
M = max{ b 1 , . . ., b i } .
2) Ako su neke od suma S i,i , S i,i+1 , . . ., S i,n negativne, neka je j najmanji
(prvi) indeks tako da je S i, j < 0. Onda je
M = max{ b 1 , . . ., b i , b j +1, . . ., b n } .

Dokaz: Oba slu aja se sli no dokazuju i zasnivaju se na prostoj cinjenici:


c
c
suma nekog podniza moe samo da se smanji ukoliko se podniz smanji za

elemente na njegovom po etku cija je suma pozitivna. Formalnije, u prvom


c

slu aju cemo pokazati da je b k b i za svako k = i + 1, . . ., n, odakle onda


c
sledi da je
M = max{ b 1 , . . ., b i , b i+1 , . . ., b n } = max{ b 1 , . . ., b i } ,
jer su svi elementi b i+1 , . . ., b n manji ili jednaki b i .
Zato za element b k sa indeksom takvim da i < k n pretpostavimo
b k = max S k,k , S k,k+1 , . . ., S k,n = S k,r
za neko r k, kao to je to ilustrovano na slede oj slici:
c
1

k1 k

a
S i,k1 0

S k,r

Onda je
b k = S k,r
S i,k1 + S k,r , jer S i,k1 0 po pretpostavci
= S i,r
bi,

to je trebalo pokazati.

jer b i = max S i, j ,
j = i,...,n

4.2. Nizovi

77

U drugom slu aju je dokaz skoro identi an, osim to se pokazuje da je


c
c
b k b i za svako k = i +1, . . ., j, gde je j prvi indeks za koji je S i, j < 0. Naime,
ako za i < k j pretpostavimo b k = S k,r za neko r k, kako je j prvi indeks
za koji je S i, j < 0, to je S i,k1 0, pa zato
b k = S k,r S i,k1 + S k,r = S i,r b i .
Prema tome,
M = max{ b 1 , . . ., b i , b i+1 , . . ., b j , b j +1, . . ., b n } = max{ b 1 , . . ., b i , b j +1, . . ., b n } ,
jer su svi elementi b i+1 , . . ., b j manji ili jednaki b i .
Primetimo da na osnovu prvog zapaanja jo ne moemo mnogo da
ubrzamo kvadratni algoritam. Prvi slu aj prethodne leme nije problem,
c
jer od i-te pozicije redom ispitujemo elemente niza a do kraja tog niza
i nikad se ne vra amo: kada se ustanovi da su sve sume S i,i ,S i,i+1 , . . .,
c
c
S i,n nenegativne, postupak se moe zavriti jer su dalja izra unavanja
elemenata b i+1 , . . ., b n nepotrebna.
U drugom slu aju kada se iza i-te pozicije otkrije prva pozicija j za koju
c
c
c
je S i, j < 0, onda se mogu presko iti izra unavanja elemenata b i+1 , . . ., b j i
nastaviti sa izra unavanjem od elementa b j +1. Medutim, problem je to
c

element b i do pozicije j nije jo odreden i zato se moraju ispitivati svi

elementi niza a do kraja radi izra unavanja suma S i, j +1 ,S i, j +2 , . . ., S i,n .


c
U drugom slu aju dakle prolazi se od i-te pozicije niza a do njegovog
c
kraja, a zatim se vra a i nastavlja sli an postupak od pozicije j + 1. To u
c
c
najgorem slu aju moe opet proizvesti kvadratno vreme. Sre om, drugo
c
c
zapaanje je da u ovom slu aju, da bismo odredili element b i , zapravo ne
c
moramo ispitivati sve elemente niza a do kraja radi izra unavanja suma
c
S i, j +1 ,S i, j +2 , . . ., S i,n .
L EMA 2 Za svako i {1, 2, . . ., n}, ako je j najmanji (prvi) indeks tako da je
S i, j < 0 i b i = max S i,i , S i,i+1 , . . ., S i, j 1 , onda je b i b j +1.
Dokaz: Pretpostavimo b i = S i,r . Kako je b i = max S i,i , S i,i+1 , . . ., S i, j 1
po pretpostavci, to je r > j. (Primetimo da r = j poto S i, j < 0.) Ova situacija
je ilustrovana na slede oj slici:
c
1

j j+1

a
S i, j < 0

S j +1,r

78

Osnovne strukture podataka


Onda je
b i = S i,r
= S i, j + S j +1,r
S j +1,r ,

jer S i, j < 0 po pretpostavci

b j +1 ,

jer b j +1 = max{S j +1, j +1, . . ., S j +1,n }

to je trebalo pokazati.
Ova lema implicira da, tokom izra unavanja bilo kog elementa b i , prvi
c
c
put kada otkrijemo S i, j < 0 moemo bezbedno prekinuti to izra unavanje
i nastaviti sa izra unavanjem elemenata b j +1 , . . . , b n . Naime, ukoliko je
c
element b i jednak jednoj od suma S i,i , S i,i+1 , . . ., S i, j 1 , onda svakako ne
c
moramo ispitivati dalje sume S i, j +1 , S i, j +2 , . . ., S i,n . U suprotnom slu aju,
ukoliko je element b i jednak nekoj daljoj sumi od pozicije j, onda je prema
c
c
prethodnoj lemi b i b j +1. To zna i da je element b i nevaan za izra unavanje maksimuma niza b, pa zato izra unavanje elementa b i moemo
c
potpuno zanemariti i nastaviti sa izra unavanjem elemenata b j +1, . . ., b n .
c
Postupak koji se zasniva na prethodnim zapaanjima na pseudo jeziku
je:
// Ulaz: niz a, broj elemenata n niza a
// Izlaz: maksimalna suma podniza M
algorithm mcss(a, n)
M = 0;
// maksimalna suma podniza
i = 1;
while i < n do
// izraunati b i
c
s = 0;
for j = i to n do
// izraunati S i, j
c
s = s + a[j];
// S i, j = S i, j 1 + a j
if (s < 0) then

// da li je S i, j < 0?

// ako jeste, prekinuti sa b i , b i+1 ,... , b j


else if (M < s) then // ako nije, aurirati maksimalnu sumu
M = s;
i = j + 1;
// nastaviti sa b j +1 ,... , b n
break;

return M;

Mada i ova verzija algoritma mcss sadri dve ugnjedene petlje, njegovo

vreme izvravanja je linearno. Naime, primetimo da u svakom koraku


c
c
spoljanje while petlje pove avamo njen broja i do pozicije ulaznog niza
koja je za jedan ve a od pozicije u kojoj je unutranja for petlja stala. To
c
zna i da broja j unutranje petlje dobija sve vrednosti od 1 do n ta no
c
c
c

4.2. Nizovi

79

jednom. Zato se telo unutranje petlje izvrava ta no n puta, a kako je


c
za jedno izvravanje tog tela o igledno potrebno konstantno vreme, to je
c
ukupno vreme izvravanja ove verzije algoritma T(n) = O(n)O(1) = O(n).

Matrice
Do sada smo govorili, u stvari, o naj e e kori enom obliku niza koji se
c c
c
optije naziva jednodimenzionalni niz (ili ponekad i vektor). Generalizacija
tog oblika se moe dobiti ukoliko se uzme da su sami elementi jednodimenzionalnog niza opet jednodimenzionalni nizovi. (Podsetimo se da za
tip elemenata nizova ne postoji nikakvo ograni enje u vezi sa njihovom
c
sloeno u.) Tako se dobija dvodimenzionalni niz ili matrica elemenata.
c
Matrica elemenata predstavlja koncepcijski tabelu tih elemenata koja
ima odreden broj vrsta i kolona. Elementi matrice imaju zato dvostruke in
dekse: prvi indeks ukazuje na vrstu i drugi na kolonu u kojima se element
nalazi u matrici. Pored toga, za matricu elemenata se unapred moraju
zadati brojevi njenih vrsta i njenih kolona koji se nazivaju veli ina mac
trice. Veli ina matrice ne moe se menjati, to proizilazi iz nepromenljivoc
sti veli ine jednodimenzionalnog niza. Na primer, na slici 4.2 je prikazana
c

matrica elemenata veli ine 34 koja ima tri vrste i cetiri kolone.
c
a
a[1,1]

a[1,2]

a[1,3]

a[1,4]

a[2,1]

a[2,2]

a[2,3]

a[2,4]

a[3,1]

a[3,2]

a[3,3]

a[3,4]

S LIKA 4.2: Matrica a veli ine 34.


c

Postupak uoptavanja osnovnog koncepta niza kojim se dobija matrica


moe se sli no nastaviti. Ukoliko elementi jednodimenzionalnog niza predc
stavljaju matrice, dobija se trodimenzionalni niz, odnosno niz matrica. Naravno, ovaj postupak se moe dalje nastaviti da bi se dobili viedimenzionalni nizovi, ali njihova upotreba u praksi je ograni ena na vrlo specijalne
c
primene. Kako se ni konceptualno nita novo ne dobija daljim uoptavanjem, to o njima u ovoj knjizi vie ne emo govoriti.
c

80

Osnovne strukture podataka

Primer: problem stabilnih brakova


Problem stabilnih brakova u svom osnovnom obliku su predstavili ameri ki ekonomisti Gejl (Gale) i ejpli (Shapley) u vezi sa problemom upisa
c
studenata na univerzitete. Taj po etni oblik problema je pretrpeo mnoge
c
modikacije i njegove razne varijante su nale iroku primenu u ra uc
narstvu, matematici, ekonomiji, teoriji igara i operacionim istraivanjima.
Postupak za reavanje problema stabilnih brakova otkriva bogatu struk
turu tog problema i u ra unarstvu slui kao primer algoritma ciji je dokaz
c
ispravnosti sloeniji nego analiza njegovog vremena izvravanja.
U opisu problema stabilnih brakova sledimo tradiciju po kojoj se taj
problem ivopisno denie kao problem enidbe mladi a sa devojkama (ili
c
udaje devojaka za mladi e). Pretpostavimo da imamo dva disjunktna skupa
c

M i D, oba veli ine n, ciji se elementi poistove uju sa mladi ima i devojc
c
c
kama. Prosto re eno, skup M se sastoji od n mladi a i skup D se sastoji od
c
c
n devojaka. Pretpostavimo dalje da mladi i i devojke iz ova dva skupa trae
c
svoje ivotne partnere u socijalnom okruenju koje predstavlja monogamno
i heteroseksualno drutvo, to zna i da svaka osoba za supranika eli
c
ta no jednu osobu suprotnog pola. Vezivanje kojim se svakom mladi u iz
c
c
skupa M dodeljuje razli ita devojka iz skupa D naziva se savreno vezivac
nje. Slikovito re eno, jedno savreno vezivanje predstavlja jedno mogu e
c
c
kolektivno ven anje svih mladi a i devojaka iz dva data skupa. Radi dalje
c
c
analogije, ako mladi u m M u savrenom vezivanju odgovara devojka
c
d D, to se ozna ava kao (bra ni) par (m, d).
c
c
Jasno je da za date skupove M i D veli ine n postoji veliki broj (n!) moc
gu ih savrenih vezivanja, pa bez ikakvih ograni enja to nije mnogo intec
c
resantno. Ograni enje koje savreno vezivanje mora zadovoljiti za problem
c
stabilnih brakova se denie u duhu toga da sve veze mladi a i devojaka
c
budu dugotrajne, odnosno da njihovi brakovi budu stabilni bez razvoda.
Zato pretpostavljamo da svaka osoba ima listu naklonosti svih osoba
suprotnog pola koja odraava prvenstvo po kojem bi data osoba elela da
stupi u brak sa drugom osobom. Drugim re ima, svaki mladi rangira sve
c
c
devojke od one koja mu se najvie svida pa do one koja mu se najmanje

svida, a to isto cine i devojke za mladi e. Ovo rangiranje se podrazumeva


c

da je bez jednakih naklonosti tako da se lista naklonosti svake osobe moe


predstaviti sortiranim nizom u striktno opadaju em redosledu svih n osoba
c
suprotnog pola. Podrazumeva se i da se naklonosti osoba ne menjaju tokom
vremena.

Na primer, ako su M = { X , Y , Z,U } i D = { x, y, z, u} dva skupa po cetiri

4.2. Nizovi

81

mladi a i devojaka, liste naklonosti mladi a u skupu M i devojaka u skupu


c
c
D mogu biti:
X : z, y, x, u

Y : y, x, z, u

Z : x, u, z, y

U : u, z, x, y

x : X , Y , Z,U

y : U, Z, Y , X

z : Y , Z, X ,U

u : Z,U, X , Y

Liste naklonosti svih mladi a i devojaka je pogodnije predstaviti dvema


c
tabelama, jednom za mladi e i jednom za devojke. Tabelarni oblik svih lista
c
naklonosti u prethodnom primeru je:
mladi i
c
X
Y
Z
U

1
z
y
x
u

2
y
x
u
z

3
x
z
z
x

4
u
u
y
y

devojke
x
y
z
u

1
X
U
Y
Z

2
Y
Z
Z
U

3
Z
Y
X
X

4
U
X
U
Y

Ako je data lista naklonosti osobe p, kaemo da se osobi p vie svida

osoba q od osobe r suprotnog pola ukoliko se q nalazi pre r na listi naklonosti osobe p. Tako u prethodnom primeru, devojci z se vie svida Y od U

i mladi u Y se vie svida x od z.


c

Nalaenje savrenog vezivanja mladi a i devojaka tako da se potpuno


c
zadovolje njihove liste naklonosti je teak zadatak, a u nekim slu ajevima
c
je i nemogu . Odmah je jasno da se ne moe obezbediti da svako za bra nog
c
c
druga dobije svoj prvi izbor: ako je isti mladi prvi izbor za vie devojaka,
c
samo jedna devojka mu moe postati ena, dok se druge moraju zadovoljiti
muem koji nije prvi na njihovoj listi. Zbog toga, umesto da se u savrenom
vezivanju trai najve a sre a za svakoga, postavlja se skromniji drutveni
c
c
cilj da dobijeni brakovi budu stabilni.
Ovaj skromniji cilj podrazumeva da treba prona i savreno vezivanje
c
koje spre ava potencijalno saglasno brakolomstvo. To je ono vezivanje koje
c
ne pravi nijedne dve osobe suprotnog pola nezadovoljnim u smislu da se obe
osobe medusobno vie svidaju jedno drugom nego njihovi dodeljeni bra ni
c

drugovi u vezivanju. Preciznije, neki mladi m M i neka devojka d D se


c
nazivaju nezadovoljni par u savrenom vezivanju ako m i d nisu vezani
jedno za drugo u tom vezivanju, odnosno u tom vezivanju su odredeni

c
bra ni parovi (m, ) i (, d) za neke druge D i M, ali se mladi u
c
m vie svida d od njegove ene i devojci d se vie svida m od njenog mua

. (Primetimo da su miljenja mladi a i devojke nebitna).


c

82

Osnovne strukture podataka

Prirodno je pretpostaviti da niko ne bi vrljao i stupio u vezu sa nekim


ko mu se manje svida od dodeljenog partnera, ali nita ne spre ava neki nec

zadovoljni par mladi a i devojke da raskinu brakove sa svojim dodeljenim


c
bra nim drugovima i medusobno stupe u brak. Radi opte dobrobiti druc

tva treba zato na i savreno vezivanje bez nezadovoljnih parova, odnosno


c
takozvano stabilno vezivanje. Prethodni zadatak se upravo naziva problem
stabilnih brakova: za date liste naklonosti svih mladi a iz skupa M i svih
c
devojaka iz skupa D odrediti jedno stabilno vezivanje.
Razmotrimo savreno vezivanje (X , x), (Y , y), (Z, z), (U, u) za prethodni
primer listi naklonosti. Mladi Z i devojka u su nezadovoljni par u ovom
c
vezivanju poto se mladi u Z vie svida u od njegove ene z, a devojci u se
c

vie svida Z od njenog mua U. Prema tome to vezivanje nije stabilno.

Ako pokuamo da uklonimo ovu nestabilnost vezivanjem ovog nezadovoljnog para (zamislimo da su se bra ni parovi (Z, z) i (U, u) razveli), i zatim
c
veemo U i z poto je to jedini izbor za njih, dobijamo novo vezivanje (X , x),
(Y , y), (Z, u), (U, z). Medutim, ovo vezivanje je takode nestabilno zbog X

i z. Sada se mladi u X vie svida z od x, a devojci z se vie svida X od


c

U. Ovaj postupak sukcesivnih razvoda i vezivanja nezadovoljnih parova


moemo nastaviti, ali nije teko smisliti primer u kojem se ovim pristupom
vrtimo u krug i nikad ne dobijamo stabilno vezivanje.
Posle ovoga se odmah postavlja pitanje postojanja stabilnog vezivanja
u svakoj instanci problema stabilnih brakova. To jest, ako su date proizvoljne liste naklonosti svih mladi a i devojaka, da li uvek postoji bar
c
jedno stabilno vezivanje? Odgovor na ovo pitanje je potvrdan i, donekle
iznenaduju e, dokaz toga je sasvim konstruktivan. U stvari, dokaz se
c

sastoji od samog algoritma kojim se konstruie stabilno vezivanje za ulazne


liste naklonosti.
Mada je nalaenje bra nog druga i ostajanje s njim u stabilnoj vezi
c
daleko komplikovanije u stvarnom ivotu, reenje ra unarskog problema
c
stabilnih brakova je relativno jednostavno. Glavna ideja originalnog Gejlejpli algoritma moe se popularno saeti u obliku mladi i prose devojke,
c
a devojke biraju ponude. To zna i da u toku rada algoritma neki parovi
c
postaju verenici usled prosidbi mladi a, a ponekad devojke raskidaju vec
ridbe ako dobiju bolju priliku. Algoritam u glavnim crtama moe se opisati
na slede i na in:
c
c
Na po etku, svi mladi i i devojke su slobodni (nisu vereni), a zatim
c
c
algoritam radi u iteracijama.
Na po etku svake iteracije se bira slobodan mladi koji prosi prvu
c
c

4.2. Nizovi

83

(najpoeljniju) devojku na svojoj listi naklonosti od onih koje nikad


ranije nije zaprosio. (Primetimo da ovo implicira da nijedan mladi
c
ne prosi istu devojku dvaput.)
Ako je slobodna devojka zaproena, ona uvek prihvata ponudu, a
mladi koji ju je zaprosio i ta devojka postaju verenici (i nisu vie
c
slobodni). Ako je zauzeta devojka zaproena, ona proverava svoju
listu naklonosti i prihvata ponudu samo ako joj se vie svida mladi
c

koji ju je zaprosio od svog aktuelnog verenika. Ako je to slu aj,


c
mladi koji je zaprosio devojku i zaproena devojka postaju novi par
c
verenika, a stari verenik devojke postaje slobodan mladi . Ako se
c
zauzetoj devojci vie svida aktuelni verenik od mladi a koji ju je
c

zaprosio, ona odbija ponudu i nita se ostalo ne menja.


Algoritam zatim prelazi u narednu iteraciju sve dok svi mladi i ne
c
postanu vereni (neslobodni), kada se sve veridbe proglaavaju brakovima. To jest, svi zavrni parovi verenika su rezultat koji se vra a
c
kao stabilno vezivanje.
Ovaj neformalni opis izraen malo preciznije na pseudo jeziku je:3
// Ulaz: liste naklonosti mladia, liste naklonosti devojaka
c
// Izlaz: stabilno vezivanje mladia i devojaka
c
algorithm smp(liste naklonosti mladia i devojaka)
c
Svi mladii i devojke su slobodni;
c
while (postoji slobodan mladi m) do
c
d = prva devojka na m-ovoj listi od onih koje nije zaprosio;
// m prosi d
if ( d slobodna) then
// d prihvata m
m i d su verenici;
else if ( d vie voli m od verenika ) then
// d prihvata m
m i d su verenici;
je slobodan;
else
// d ne prihvata m
nita;
return veridbe;

// proslaviti stabilne brakove

Ako za trenutak zanemarimo programsku realizaciju algoritma smp,

paljiviji citaoci su moda primetili da on ima tri potencijalne greke. Pre


svega, nije jasno da li se algoritam uopte zavrava, a kamoli da li je njegov
rezultat zaista jedno stabilno vezivanje. Naime, u svakoj iteraciji while
3 Ime algoritma smp je skra enica od engleskog termina za problem stabilnih brakova:
c
the stable marriage problem.

84

Osnovne strukture podataka

petlje imamo slobodnog mladi a koji moe ostati slobodan ukoliko ga odbije
c

njegova najpoeljnija zauzeta devojka koju prosi. Cak i ako ga ona prihvati,
njen stari verenik postaje slobodan, tako da se broj slobodnih mladi a ne e
c
c

smanjiti. Zato je zamislivo da ce uvek postojati slobodan mladi na po etku


c
c

svake iteracije, pa ce se algoritam izvravati beskona no.


c
Druga potencijalna greka algoritma je zbog toga to izabrani slobodni
mladi na samom po etku neke iteracije moda nema devojku na svojoj
c
c
listi naklonosti koju nije ve zaprosio. Naime, moda je mogu e da je
c
c
neki slobodan mladi m ve zaprosio sve devojke. Ekvivalentno, ne postoji
c
c
devojka u listi naklonosti mladi a m koju on ve nije zaprosio, pa m nema
c
c
prvu takvu devojku koju bi zaprosio.
c
Kona no, opis algoritma smp nije u potpunosti deterministi ki, poto
c
se u uslovu nastavka while petlje proverava samo da li postoji slobodan
mladi . Ako je to slu aj, u algoritmu nije navedeno kako se bira jedan takav
c
c
mladi ako postoje vie kandidata za aktuelnu iteraciju. Zato se s pravom
c
moe postaviti pitanje da li je redosled po kojem se oni biraju vaan za
rezultuju e vezivanje, odnosno da li moda neki pogrean redosled izbora
c
slobodnih mladi a ne bi proizveo nestabilno vezivanje.
c
c
Ovo ukazuje da ispravnost algoritma smp nije o igledna i da je potrebno

paljivije pokazati njegova svojstva. U nastavku cemo zato kroz niz formalnih zapaanja odgovoriti na sve prethodne dileme.
L EMA 1 Za n mladi a i n devojaka, algoritam smp se zavrava u najvie
c
2
n iteracija.
Dokaz: Primetimo da ovde tvrdimo vie od toga da algoritam smp ne
radi beskona no on se zavrava i to u najvie n2 iteracija. Da bismo
c
ovo pokazali, moramo na i dobru meru napredovanja while petlje. (Videli
c
smo da to nije broj slobodnih mladi a.) Pokaza emo da je to broj prosidbi
c
c
koje mladi i izvedu.
c
Zaista, nijedan mladi ne prosi istu devojku dvaput, jer neki mladi
c
c
uvek prosi devojku koju nikad ranije nije zaprosio. To zna i da svaki
c
mladi izvede najvie n prosidbi tokom rada algoritma smp, odnosno svih
c
n mladi a zajedno izvedu najvie n2 prosidbi ukupno. U svakoj iteraciji
c
while petlje se izvodi ta no jedna nova prosidba, pa zato moe biti najvie
c
n2 iteracija.
Pre nego to pokaemo da u algoritmu smp svaki slobodan mladi ima
c
devojku na svojoj listi koju jo nije zaprosio, primetimo jedno interesantno
svojstvo tog algoritma. Svaki put kada mladi prosi neku devojku, on to
c

4.2. Nizovi

85

radi na svoju ve u alost: prvi put prosi svoju najve u ljubav, zatim prosi
c
c
devojku koja je njegov drugi izbor, pa tre i izbor i tako dalje. Devojke sa
c
druge strane svaki put kada promene verenike, rade to na svoju ve u sre u.
c
c
Slobodna devojka od trenutka kada prihvati ponudu nekog mladi a koji
c
ju je zaprosio, nikad vie ne postaje slobodna ona moe samo promeniti
svog verenika ako dobije bolju ponudu iz njenog ugla gledanja, odnosno ako
je zaprosi mladi koji joj se vie svida od aktuelnog verenika.
c

c
c
L EMA 2 Svaki slobodan mladi na po etku while petlje u algoritmu smp
ima devojku koju jo nije zaprosio.
Dokaz: Primetimo najpre da je na po etku izvravanja svake iteracije
c
while petlje u algoritmu smp broj slobodnih mladi a jednak broju slobodnih
c
devojaka. To je, u stvari, invarijanta te petlje, odnosno uslov koji ostaje

nepromenjen nakon izvravanja svake iteracije petlje. (Citaoci se o invarijantama petlji mogu podsetiti na strani 20.)
U to se moemo uveriti na slede i na in. Jasno je da je taj uslov zadovoc
c
ljen na po etku prve iteracije, poto su onda svi mladi i i devojke slobodni.
c
c
Pod pretpostavkom da je taj uslov ta an na po etku neke iteracije, izvrac
c
vanjem te iteracije se broj slobodnih mladi a i broj slobodnih devojaka ili ne
c
menjaju ili oba smanjuju za jedan (kada slobodna devojka prihvati ponudu
slobodnog mladi a), pa je taj uslov ta an i na po etku slede e iteracije.
c
c
c
c
Sada moemo pokazati da vai tvrdenje leme. Neka je m slobodan

mladi na po etku while petlje u algoritmu smp. Prema invarijanti te


c
c
petlje, mora postojati i bar jedna slobodna devojka, recimo d. To zna i
c
da ovu devojku d do tada jo niko nije zaprosio. U suprotnom, da ju je
neki mladi ranije zaprosio, ona bi morala da prihvati njegovu ponudu i
c
nikad vie ne bi bila slobodna. Prema tome, speci no ni mladi m nije jo
c
c
zaprosio (slobodnu) devojku d. To zna i da je bar ta devojka jedna od onih
c
koje slobodni mladi nije zaprosio, to je trebalo pokazati.
c
L EMA 3 Algoritam smp kao rezultat daje stabilno vezivanje.

Dokaz: Neka su broj mladi a i broj devojaka jednaki n. Prvo cemo poc
c
kazati da algoritam smp proizvodi savreno vezivanje, odnosno ta no n
bra nih parova u kojima se svaki mladi i devojka pojavljuju ta no jednom.
c
c
c
c
c
Kada se while petlja zavri, ne postoji slobodan mladi . To zna i da su
svi mladi i vereni bar sa jednom devojkom. O igledno je da neki mladi
c
c
c
moe biti veren sa najvie jednom devojkom, jer mladi moe biti veren
c
c
samo kada je slobodan. Stoga, kada se while petlja zavri, svaki mladi je
veren sa ta no jednom devojkom. Sa druge strane, na osnovu invarijante
c

86

Osnovne strukture podataka

while petlje ne postoji ni slobodna devojka, jer je broj slobodnih mladi a


c

(tj. nula) jednak broju slobodnih devojaka. To zna i da je i svaka devojka


c
verena bar sa jednim mladi em. Kako je i o igledno da neka devojka moe
c
c
biti verena sa najvie jednim mladi em, to zna i je rezultat algoritma smp
c
c
jedno savreno vezivanje.
Da bismo pokazali da je rezultuju e savreno vezivanje stabilno, pric
meni emo na in zaklju ivanja po kontradikciji. Pretpostavimo dakle suc
c
c
protno, da postoji nezadovoljni par, recimo mladi m i devojka d, u dobijec
nom vezivanju. To zna i da u tom vezivanju imamo bra ne parove (m, )
c
c
c
i (, d), ali se mladi u m vie svida d od njegove ene i devojci d se vie

c
svida m od njenog mua . Poto je (m, ) bra ni par, m je morao da zaprosi

, jer neki mladi moe biti veren samo ako zaprosi devojku. Ali tada je
c
m morao da zaprosi i sve devojke koje su pre njegove ene na njegovoj
listi naklonosti, jer mladi i prose devojke po redu u kojem se one nalaze
c
na njihovoj listi naklonosti. Speci no, tokom rada algoritma m je morao
c
zaprositi i devojku d, jer mu se ona vie svida od njegove ene (i pri tome

je m zaprosio d pre nego to je zaprosio svoju enu ).


c
Sa druge strane, poto je (, d) bra ni par, suprug je po miljenju
devojke d najbolji (najvie rangirani) mladi koji ju je ikad zaprosio, jer
c
devojke menjaju verenike samo ukoliko dobiju bolje ponude. Speci no,
c
poto je m prosio d, to zna i da je ispred m na listi naklonosti devojke d.
c
Ali ovo je u suprotnosti sa naom pretpostavkom da je par m i d nezadovoljan, odnosno da se devojci d vie svida m od njenog mua . Dakle

naa pretpostavka da postoji nezadovoljni par je neodriva, jer to vodi


u kontradikciju. Ovo pokazuje da ne postoji nijedan nezadovoljni par u
dobijenom vezivanju.
Preostalo je jo da se uverimo da nedeterminizam algoritma nije bitna,
odnosno da izbor slobodnog maladi a na po etku while petlje moe biti
c
c
proizvoljan.
L EMA 4 Algoritam smp proizvodi isto stabilno vezivanje bez obzira na to
kako se biraju slobodni mladi i u svakoj iteraciji while petlje.
c
Dokaz: Na prosidbu slobodnog mladi a ni na koji na in ne uti e to ta
c
c
c
neki drugi mladi radi. Sli no, na izbor nijedne devojke ne uti e to ta
c
c
c
druge devojke rade. Prema tome, u svakoj iteraciji nije bitno kojim redom
se prosidbe obavljaju niti kojim redom devojke biraju mladi e.
c
Analizirajmo sada vreme izvravanja algoritma smp. Ako su date liste
naklonosti n mladi a i n devojaka, znamo da je broj iteracija while petlje
c

4.2. Nizovi

87

najvie n2 . Vreme izvravanja ovog algoritma bi e zato u najgorem slu aju


c
c
2
proporcionalno n ukoliko izaberemo njegovu implementaciju tako da se
svaka iteracija izvrava za konstantno vreme. Bez mnogo detaljisanja

(videti 6. zadatak na kraju poglavlja), u nastavku cemo samo u grubim


crtama navesti mogu e strukture podataka koje omogu avaju da se svaki
c
c
korak u telu while petlje realizuje za konstantno vreme:
Za predstavljanje n mladi a i n devojaka moemo koristiti obi ne
c
c
brojeve 1, 2, . . ., n za njihova imena.
Za predstavljanje njihovih veridbi moemo koristiti dva niza a i b od
c
n elemenata. Prirodno, a i {1, . . ., n} ozna ava devojku sa kojom je
c
c
mladi i veren, a a i = 0 ako je mladi i slobodan. Sli no, b i {1, . . ., n}
c
ozna ava mladi a za koga je devojka i verena, a b i = 0 ako je devojka
c
c
i slobodna.
Za predstavljanje slobodnih mladi a moemo koristiti niz s od n elec
menata i voditi ra una o njegovoj stvarnoj duini. Postoje i sloboc
c
dan mladi se uzima sa kraja tog niza, a novi slobodan mladi se
c
c

takode dodaje na kraj tog niza. (Citaoci koji bolje poznaju strukture

podataka mogu prepoznati da ovim simuliramo stek, mada se moe

koristiti i red za cekanje.)


Za predstavljanje listi naklonosti svih mladi a moemo koristiti n n
c
matricu m tako da i-ti red te tabele predstavlja listu naklonosti mladi a i, sortiranu od najvie do najmanje eljene devojke za mladi a i.
c
c
c
Tako m i, j = k zna i da je devojka k na j-tom mestu u listi naklonosti
mladi a i.
c
Za predstavljanje ranga devojke koju je neki mladi poslednje zaproc
c
sio moemo koristiti niz r od n elemenata tako da r i = j ozna ava da
se poslednja devojka koju je mladi i zaprosio nalazi na j-tom mestu
c
c
u njegovoj listi naklonosti, odnosno to je devojka m i, j . Na ovaj na in
moemo lako odrediti prvu devojku koju neki mladi treba da zaprosi.
c
Za predstavljanje listi naklonosti svih devojaka moemo koristiti nn
c
c
matricu rangiranja d tako da d i, j ozna ava rang mladi a j za dec
c
vojku i u njenoj listi naklonosti. Tako d i, j = k ozna ava da se mladi
j nalazi na k-tom mestu u listi naklonosti devojke i. Razlog ove
asimetri nosti u odnosu na liste naklonosti mladi a je u tome to na
c
c
ovaj na in moemo lako proveriti da li se devojci i vie svida mladi
c
c

c
j 1 od mladi a j 2 .

88

Osnovne strukture podataka

4.3 Liste
Lista (ta nije povezana lista) je struktura podataka koja je sli na nizu
c
c
jer predstavlja sekvencu elemenata istog tipa. Medutim, za razliku od

niza kod koga se sekvencijalna uredenost dobija indeksiranjem elemenata

niza, linearni poredak elemenata liste se odreduje pokaziva em u svakom


c

elementu na slede i element u listi. Ova konceptualna slika povezane liste


c
l = x1 , x2 , . . ., xn prikazana je na slici 4.3.
l
x1

x2

xn

S LIKA 4.3: Povezana lista l.


Obratite panju na to da pojam pokaziva a u listi kao apstraktnom tipu
c
podataka ne mora da bude isti onaj kao kod programskih jezika. Na apstraktnom nivou je to jednostavno neka indikacija u jednom elementu liste
na to koji je slede i element u logi kom poretku liste. Poslednji element
c
c
liste sadri specijalni pokaziva koji ne ukazuje ni na jedan element.
c
Terminologija u vezi sa listama je sli na onoj za nizove. Broj elemenata
c
liste se naziva veli ina ili duina liste, a lista bez elemenata se naziva
c
prazna lista. Za dva susedna elementa liste se kae da je drugi sledbenik
prvom ili da je prvi prethodnik drugom. Prvi element liste, koji se obi no
c
naziva glava liste, nema prethodnika; poslednji element liste, koji se obi no
c
naziva rep liste, nema sledbenika.
Glavna razlika listi u odnosu na nizove je u tome to duina liste nije
unapred odredena. Svaka lista je na po etku prazna, a zatim se njena
c

duina pove ava ili smanjuje dodavanjem novih ili uklanjanjem postoje ih
c
c
elemenata. Zato lista kao apstraktni tip podataka ima prednost nad nizom
u primenama kod kojih ukupan broj nekih istorodnih elemenata nije poznat, ili operacije dodavanja i uklanjanja tih elemenata ne slede unapred
poznat obrazac.
Sa druge strane, nizovi imaju prednost kada je potreban ekasan pristup proizvoljnom elementu pristup svakom elementu kod liste mora
po eti od prvog elementa i slede i njegovog sledbenika do i do drugog elec
c
c
menta, zatim slede i njegovog sledbenika do tre eg i tako dalje, dok se ne
c
c
stigne do eljenog elementa. Prema tome, pristup proizvoljnom elementu

4.3. Liste

89

liste nije operacija konstantnog vremena, nego zavisi od njegove pozicije u


listi.
Nepotpun spisak tipi nih operacija nad listom je:
c
Konstruisanje prazne liste;
Dodavanje novog elementa u listu;
Uklanjanje datog elementa iz liste;
Pretraga liste.

Implementacija liste pomocu pokazivaca


U programskim jezicima koji obezbeduju rad sa pokaziva ima, strukc

tura podataka liste realizuje se na prirodan na in: svaki element liste predc
stavlja se jednim objektom sa dva polja. Ovaj objekat se obi no naziva cvor
c

liste, a prvo polje cvora sadri relevantan podatak odgovaraju eg elementa


c

liste, dok drugo polje cvora sadri pokazava na slede i cvor liste.
c
c
Poto sadraj elemenata liste mogu biti podaci bilo kog (istog) tipa,
prvo polje mora biti odgovaraju eg tipa tih podataka koji zavisi od konc
kretne primene liste. Medutim, na optem nivou se sadraj elemenata

liste posmatra neutralno i obi no se naziva klju em cvora liste. Prema


c
c

c
c
tome, prvo polje u svakom cvoru liste (oznaka klju) poistove uje se sa
pravim sadrajem odgovaraju eg elementa liste, dok drugo pokaziva ko
c
c
polje (oznaka sled) ukazuje na sledbenika elementa liste.
Listi l se grupno pristupa preko posebnog spoljanjeg pokaziva a (ozc

naka l) koji nije deo liste i koji pokazuje na prvi cvor liste. Pogodno je
pretpostaviti i postojanje specijalne vrednosti pokaziva a null koja nikad
c

ne ukazuje ni na ta. Na taj na in moemo uniformno tretirati cvorove liste


c

i smatrati da poslednji cvor liste u pokaziva kom polju sadri tu specijalnu


c
vrednost pokaziva a. Pored toga, ako pokaziva l ima vrednost null, onda
c
c
smatramo da je lista l prazna. Na slici 4.4 je ilustrovana reprezentacija
liste pomo u pokaziva a.
c
c
l

klju sled
c

klju sled
c

klju sled
c

S LIKA 4.4: Reprezentacija liste l pomo u pokaziva a.


c
c

90

Osnovne strukture podataka

Da bismo ilustrovali tipi ne operacije nad listom, u nastavku cemo


c
predstaviti algoritme za svaku od njih i analizirati njihovo vreme izvravanja.
Konstruisanje prazne liste. Konstruisanje prazne liste sastoji se prosto od inicijalizacije njenog pristupnog pokaziva a vredno u null:
c
c
// Ulaz: lista l
// Izlaz: prazna lista l
algorithm list-make(l)
l = null;
return l;

Vreme izvravanja algoritma list-make je o igledno konstantno.


c

Dodavanje novog cvora u listu. Dodavanje elemenata u listu (kao i


uklanjanje elemenata iz nje) modikuje sadraj liste, pa je potrebno lokalno preurediti listu kako bi se zadrala sekvencijalna uredenost liste sa

novim sadrajem. Da bi to bilo mogu e, kod dodavanja novog cvora u listu


c

mora se znati cvor liste iza koga se dodaje novi cvor.

Ako je dat (pokaziva na) novi cvor x i (pokaziva na) cvor p liste iza
c
c

koga se dodaje novi cvor, veza izmedu cvora p i njegovog sledbenika u listi

mora se raskinuti i izmedu njih umetnuti cvor x. Na slici 4.5 su prikazane

neophodne manipulacije pokaziva ima radi dodavanja cvora x u listu iza


c

cvora p.
p
a

b
x

S LIKA 4.5: Dodavanje cvora x u listu iza cvora p.

U posebnom slu aju kada novi cvor treba dodati na po etak liste, poto
c
c
to mesto nema prethodnika pretpostavljamo da je p jednako null. Algori

tam na pseudo jeziku za dodavanje novog cvora x u listu l iza cvora p te


liste je:

4.3. Liste

91

// Ulaz: novi cvor x, cvor p u listi l


// Izlaz: lista l sa vorom x iza vora p
c
c
algorithm list-insert(x, p, l)
if (p == null) then
x.sled = l;
l = x;
else
x.sled = p.sled;
p.sled = x;

// novi vor dodati na poetak


c
c

// novi vor dodati iza p


c

return l;

Poto su sve manipulacije pokaziva ima jedini ne instrukcije, vreme


c
c

izvravanja ovog algoritma za dodavanje cvora u listu je o igledno konc


stantno.

Uklanjanje cvora iz liste. Sli no kao kod dodavanja cvora u listu, za


c

uklanjanje cvora iz liste mora se znati cvor liste iza koga se uklanja postoje i cvor kako bi se lokalne veze mogle preurediti i zadrati sekvencijalna
c
uredenost liste.

Ako je dat (pokaziva na) cvor p liste cijeg sledbenika treba ukloniti,
c

veza izmedu tog cvora i njegovog sledbenika x u listi se raskida, a uspo


stavlja se nova veza izmedu cvora p i sledbenika starog sledbenika x. Na

slici 4.6 su prikazane neophodne manipulacije pokaziva ima radi uklanjac

nja cvora x iz liste koji se nalazi iza cvora p.


x

p
a

S LIKA 4.6: Uklanjanje cvora x iz liste iza cvora p.

Mada za uklanjanje nekog cvora iza datog cvora logi ki ne treba nita
c
dodatno uraditi od onog to je prikazano na slici 4.6, prakti no je potrebno i
c

osloboditi ra unarske resurse koje zauzima uklonjeni cvor. To oslobadanje


c

zauzetih resursa se kod nekih programskih jezika mora ru no uraditi.


c
U pseudo jeziku za opis algoritama u ovoj knjizi usvajamo laki pristup
i koristimo mogu nost drugih programskih jezika kod kojih se to obavlja
c
automatski postupkom sakupljanja otpadaka.

92

Osnovne strukture podataka

Ako opet pretpostavimo da je p jednako null kada treba ukloniti cvor

na po etku liste, algoritam na pseudo jeziku za uklanjanje cvora iz liste l


c

iza cvora p te liste je:


// Ulaz: vor p u listi l iza koga treba ukloniti vor
c
c
// Izlaz: lista l bez uklonjenog vora
c
algorithm list-delete(p, l)
if (p == null) then // ukloniti vor na poetku
c
c
l = l.sled;
else
// ukloniti vor iza p
c
p.sled = p.sled.sled;
return l;

O igledno kao kod dodavanja cvora u listu, kako su sve manipulacije


c
pokaziva ima jedini ne instrukcije, vreme izvravanja ovog algoritma za
c
c

uklanjanje cvora iz liste je konstantno.


Pretraga liste. Sli no problemu pretrage niza, operacijom pretrage liste
c

se odreduje da li se u datoj listi l nalazi cvor sa datim klju em k. Ako je to


c

slu aj, algoritam za ovu operaciju u nastavku kao rezultat vra a (pokaziva
c
c
c

na) prvi pronadeni cvor sa datim klju em. U suprotnom slu aju, ako cvor
c
c

sa datim klju em nije pronaden u listi, kao rezultat se vra a pokaziva


c
c
c

null.
// Ulaz: lista l , klju k
c
// Izlaz: vor x u listi sa kljuem k ili vrednost null
c
c
algorithm list-search(l, k)
x = l;
while ((x != null) && (x.klju != k)) do
c
x = x.sled;
return x;

O igledno je da u najgorem slu aju moramo pro i kroz celu listu da


c
c
c

bismo otkrili da se cvor sa datim klju em ne nalazi u listi. Zbog toga je


c

vreme izvravanja algoritma list-search u funkciji broja cvorova liste n


jednako O(n).

Obratite panju na to da smo kod dodavanja ili uklanjanja cvora pret vora, na kojem
postavljali da ta no znamo mesto u listi, naime iza datog c
c

se deava odgovaraju a promena. Cesto medutim elimo da dodamo ili


c

uklonimo cvor iza nekog cvora u listi sa datim klju em. U takvom slu aju
c
c

4.3. Liste

93

zato ne moemo neposredno iskoristiti date algoritme za dodavanje ili ukla


njanje cvora, nego najpre moramo koristiti algoritam list-search radi

nalaenja cvora sa datim klju em i zatim prethodnim algoritmima dodati


c

ili ukloniti cvor iza pronadenog cvora. Prema tome, vreme izvravanja ovih

operacija dodavanja ili uklanjanja cvora za listu od n cvorova bilo bi O(n),


a ne O(1).

Dvostruko povezane liste


Liste o kojima smo do sada govorili su jednostruko povezane, poto

svaki cvor ima jedno pokaziva ko polje koje ukazuje na sledbenika cvora.
c
Jednostruko povezane liste se mogu prelaziti samo u jednom smeru sleva
na desno, to smo mogli primetiti u algoritmu list-search. Medutim, u

nekim primenama je potrebno ekasno prelaziti listu u oba smera ili je

za dati cvor potrebno ekasno odrediti njegovog prethodnika, a ne samo


njegovog sledbenika.
U takvim slu ajevima moemo koristiti dvostruko povezanu listu u koc

joj svaki cvor ima polje klju a i dva pokaziva ka polja sa oznakama sled
c
c

i pret: polje sled kao i ranije ukazuje na sledbenika cvora, dok polje

pret ukazuje na prethodnika cvora. Prvi cvor dvostruko povezane liste

u polju pret i poslednji cvor u polju sled imaju vrednost null. Kao kod
jednostruko povezane liste, dvostruko povezanoj listi se pristupa preko

posebnog spoljanjeg pokaziva a koji pokazuje na prvi cvor liste, a koji nije
c
deo liste. Na slici 4.7 je prikazan primer dvostruko povezane liste l.
l

c
pret klju sled

S LIKA 4.7: Dvostruko povezana lista l.

Druga prednost dvostruko povezane liste je u tome to dodavanje cvora

moemo izvoditi iza ili ispred datog cvora. Pored toga, za uklanjanje cvora

moemo kao parametar direktno koristiti eljeni cvor, a ne manje prirodno


njegovog prethodnika. Na primer, na slici 4.8 je prikazano kako se neki

cvor uklanja iz dvostruko povezane liste na ovaj na in.


c

Algoritam dlist-delete u nastavku slui za uklanjanje cvora x iz


dvostruko povezane liste l. Jednostavni algoritmi za ostale operacije pre-

94

Osnovne strukture podataka


x
a

S LIKA 4.8: Uklanjanje cvora x iz dvostruko povezane liste.

putaju se citaocima za vebu, kao i ocena vremena izvravanja svih algoritama.


// Ulaz: vor x koji treba ukloniti iz l
c
// Izlaz: lista l bez uklonjenog vora x
c
algorithm dlist-delete(x, l)
if (x.pret != null) then
x.pret.sled = x.sled;
else
l = x.sled;
if (x.sled != null) then
x.sled.pret = x.pret;

// x nije prvi vor


c

// x nije poslednji vor


c

return l;

Implementacija liste pomocu nizova


Implementacija liste pomo u pokaziva a je vrlo prirodna i jednostavna.
c
c
Neki programski jezici medutim ne omogu avaju direktan rad sa pokazivac

cima, pa cemo u ovom odeljku kratko opisati kako se liste mogu predstaviti
pomo u nizova i kako se pokaziva i mogu simulirati pomo u indeksa elec
c
c
menata nizova.4

Cvorovi liste (ili optije bilo koji objekti) sa istim poljima mogu se najjednostavnije predstaviti pomo u posebnog niza za svako polje. Speci no,
c
c
jednostruko povezana lista se predstavlja pomo u dva niza, a dvostruko
c
povezana lista pomo u tri niza. Kod dvostruko povezane liste na primer,
c
jedan niz, recimo k, sadri vrednosti polja klju a cvorova liste, a preostala
c
dva niza, recimo s i p, simuliraju polja pokaziva a na sledbenika i pretc
hodnika. Na slici 4.9 je prikazano mogu e stanje ovih nizova za dvostruku
c
4 Re simulirati treba shvatiti uslovno, poto se u ra unarima pokaziva i zaista realic
c
c

zuju pomo u indeksa (memorijskih adresa) elemenata jednog velikog niza (glavne memoc
rije).

4.3. Liste

95

povezanu listu sa slike 4.7. U optem slu aju, element dvostruko povezane
c
liste se grupno predstavlja elementima tri niza k i , s i i p i na i-toj poziciji.
Pri tome, vrednost pokaziva a x se predstavlja zajedni kim indeksom elec
c
menata tri niza k x , s x i p x . Indeksi nizova u ovoj interpretaciji se ponekad
nazivaju kursori.
l

2
2

0
a

5
c

S LIKA 4.9: Reprezentacija dvostruko povezane liste pomo u tri niza.


c
Element liste a zauzima drugu grupnu poziciju nizova na slici 4.9, pa je
k 2 = a. Njegov sledbenik u listi, element b, nalazi se u grupnoj poziciji 5, pa
zato k 5 = b. Pored toga, poredak ova dva elementa liste je odreden time to

c
c
s 2 = 5 i p 5 = 2. Drugi elementi liste su na sli an na in povezani kursorima
c
umesto pokaziva ima. Pokaziva null se obi no predstavlja brojem (na
c
c
c
primer, 0 ili 1) koji sigurno ne moe biti stvarni indeks nizova. Pokaziva
preko koga se pristupa listi predstavlja se obi nom promenljivom l koja
c
sadri indeks prvog elementa liste.
Povezane liste moemo predstaviti i pomo u samo jednog niza, ukoc
liko primenimo metod sli an onom koji se koristi za smetanje objekata
c
u glavnoj memoriji stvarnih ra unara. Naime, jedan objekat zauzima suc
sedne lokacije u glavnoj memoriji ra unara. Pokaziva na neki objekat
c
c
predstavlja adresu prve memorijske lokacije tog objekta, a polja unutar
tog objekta mogu se indeksirati dodavanjem njihove relativne pozicije na
po etni pokaziva .
c
c
Isti princip moemo primeniti za predstavljanje objekata u programskim jezicima koji nemaju ugradeni pokaziva ki tip podataka. Na slici 4.10
c

je prikazano mogu e stanje jednog niza m koji se koristi za predstavljanje


c

dvostruko povezane liste sa slike 4.7. Jedan cvor liste zauzima mesto

c
neprekidnog podniza m i , . . ., m j niza m. Pokaziva na ovaj cvor je odre
den po etnim indeksom i podniza, a svako polje ovog cvora je odredeno
c

relativnom pozicijom iz opsega 0 do j i. Na primer, relativne pozicije

96

Osnovne strukture podataka

polja klju, sled i prev u nekom cvoru na slici 4.10 su 0, 1 i 2. Stoga,


c
c
za dobijanje vrednosti polja x.prev ukoliko je data vrednost pokaziva a x,
c
treba najpre dodati relativnu poziciju 2 polja prev na vrednost pokaziva a
x, a zatim treba pro itati sadraj elementa niza m[x+2].
c
1

10

a 13 0 d 0 19

11

12

13

14

15

b 19 4

16

17

18

19

20

21

7 13

S LIKA 4.10: Reprezentacija dvostruko povezane liste pomo u jednog niza.


c
Prednost upotrebe jednog niza za predstavljanje struktura podataka je
u tome to se na taj na in mogu predstaviti i kolekcije heterogenih objec
kata razli ite veli ine. Sa druge strane, rad sa takvom reprezentacijom je
c
c
komplikovaniji.

4.4

Stekovi

Stek (engl. stack) je specijalna vrsta liste kod koje se dodavanja i uklanjanja elemenata obavljaju samo na jednom kraju koji se naziva vrh steka.
Intuitivni model strukture podataka steka su naslagani posluavnici u restoranu ili komadi i mesa poredani na ranji u. U oba primera je pogodno
c
c

ukloniti samo onaj element (posluavnik ili komadi mesa) koji se nalazi na
c
vrhu steka, kao i dodati novi element samo na vrh steka. Drugim re ima,
c
poredak elemenata po kojem se oni uklanjaju sa steka je obrnut onom po
kojem su oni dodati na stek. Operacija dodavanja elemenata na stek se
tradicionalno zove push, a operacija uklanjanja elemenata iz steka zove se
pop.
Sve implementacije liste o kojima smo govorili u prethodnom odeljku
mogu se iskoristiti i za stek, poto je stek sa svojim operacijama specijalni slu aj liste sa svojim operacijama. U programskom okruenju koje
c
obezbeduje rad sa pokaziva ima, implementacija liste prakti no ne mora
c
c

da se menja za implementaciju steka. Pri tome, operacije za dodavanje


elemenata na po etak liste i za uklanjanje elemenata sa po etka liste su, u
c
c
stvari, druga imena za operacije push i pop.
Sa druge strane, za implementaciju steka pomo u nizova moe se isc
injenica da se dodavanja i uklanjanja elemenata vre samo na
koristiti c
vrhu steka. Zato moemo koristiti samo jedan niz, izjedna iti dno steka
c
sa po etkom tog niza, a zatim uve avati stek prema kraju tog niza. Ovaj
c
c

4.4. Stekovi

97

pristup je ilustrovan na slici 4.11 na kojoj je levo prikazan logi ki izgled


c
jednog steka s i desno njegova realizacija pomo u niza a.
c
s
10

23

17

20

10

8
20
17
23

S LIKA 4.11: Stek s predstavljen jednim nizom a.


Kao to je prikazano na slici 4.11, stek s od najvie n elemenata se

predstavlja nizom a duine n. Steku se pristupa preko promenljive v ciji


sadraj ukazuje na vrh steka, odnosno na poziciju elementa niza koji je
poslednje dodat na stek. Elementi steka zauzimaju pozicije 1, . . ., v u nizu

a, pri cemu je a 1 element na dnu steka i a v element na vrhu steka.


Ukoliko je v = 0, stek nema elemenata i onda se kae da je stek prazan.
Ako se grekom uklanja element iz praznog steka, takva programska greka se naziva potkora enje steka (engl. underow). Ukoliko je v = n, stek
c
je pun. Ako se dodaje element na pun stek, dolazi do programske greke
prekora enja steka (engl. overow).
c
Tipi ne operacije za rad sa stekom, pored tri uobi ajene operacije konc
c
struisanja (praznog) steka, dodavanja elementa na vrh steka i uklanjanja
elementa sa vrha steka, uklju uju i upite da li je stek prazan ili pun kako
c
bi se izbegle greke potkora enja i prekora enje steka. U nastavku je data
c
c
jednostavna algoritamska implementacija ovih operacija nad stekom predstavljenog jednim identikuju im objektom s koji obuhvata promenljivu v
c
i niz a duine n.
// Ulaz: stek s
// Izlaz: poetno stanje steka s
c
algorithm stack-make(s)
s.v = 0;
return;

// Ulaz: stek s
// Izlaz: tano ako je s prazan, inae netano
c
c
c
algorithm stack-empty(s)

98

Osnovne strukture podataka

if (s.v == 0)
return true;
else
return false;

// Ulaz: stek s
// Izlaz: tano ako je s pun, inae netano
c
c
c
algorithm stack-full(s)
if (s.v == n)
return true;
else
return false;

// Ulaz: novi element x, stek s


// Izlaz: stek s sa elementom x na vrhu
algorithm push(x, s)
// Pretpostavlja se da stek nije pun
s.v = s.v + 1;
s.a[s.v] = x;
return;

// Ulaz: stek s
// Izlaz: element x uklonjen sa vrha steka s
algorithm pop(s)
// Pretpostavlja se da stek nije prazan
x = s.a[s.v];
s.v = s.v - 1;
return x;

Citaoci se lako mogu uveriti da se svi navedeni algoritmi izvravaju za


konstantno vreme.

4.5

Redovi za cekanje

Red za cekanje (engl. queue) je druga specijalna vrsta povezane liste kod

koje se elementi dodaju na jednom kraju liste i uklanjaju sa drugog kraja


liste. Mesto na kojem se elementi dodaju logi ki predstavlja kraj reda, a
c
mesto gde se elementi dodaju ozna ava po etak reda. Prema tome, kada
c
c


4.5. Redovi za cekanje

99

se novi element dodaje u red za cekanje, taj element se uvek priklju uje na
c

kraj reda. Sa druge strane, kada se element uklanja iz reda za cekanje,


izbacuje se uvek prvi element reda. Intuitivni model za strukturu poda

taka reda za cekanje je red ljudi koji ceka ispred bioskopa da kupi karte,

pri cemu ljudi na po etku reda odlaze iz reda poto kupe karte, a novi ljudi
c

staju na kraj reda da cekaju. (Ali u strukturi podataka reda za cekanje


ekanje se
nema padobranaca!) Operacija dodavanja elementa u red za c
tradicionalno naziva enqueue, a operacija uklanjanja se naziva dequeue.
Kao i za stekove, sve implementacije liste mogu se iskoristiti i za redove

za cekanje. U programskom okruenju sa pokaziva kim tipom podataka,


c

implementacija reda za cekanje je skoro identi na implementaciji liste.


c
Primetimo samo da tu moemo dodatno koristiti pokaziva na kraj reda
c
da bismo operaciju enqueue u inili ekasnijom. Na taj na in naime, svaki
c
c
put kada dodajemo novi element ne moramo da prolazimo kroz celu listu
od po etka do kraja.
c

Kod implementacije reda za cekanje q pomo u nizova, jedno interec


santno reenje koristi kruni niz a veli ine n, kao to je to prikazano na
c
slici 4.12.
q

1
2

a
r

S LIKA 4.12: Red za cekanje q u obliku krunog niza.


Niz a zamiljamo u krunom obliku tako da prvi element niza sledi

iza poslednjeg. Red za cekanje q se nalazi unutar kruga u susednim lo


kacijama, pri cemu je kraj reda negde iza po etka reda u smeru kretanja
c
kazaljke na satu. Obratite panju da se susedne lokacije uzimaju u krunom smislu. Red q ima kursor g koji ukazuje na prvi element (glavu), kao
i kursor r koji ukazuje na poslednji element (rep). Na taj na in, elementi
c
reda se nalaze u lokacijama g, g + 1, . . . , r, koje su susedne u smislu da

100

Osnovne strukture podataka

lokacija 1 sledi odmah iza lokacije n u krunom redosledu.


Kada se dodaje neki element, kursor r se uve ava za jedan i novi elec
ment se upisuje u poziciju na koju ukazuje kursor. Kada se neki element
uklanja, kursor g se samo uve ava za jedan. Prema tome, kako se elementi
c

dodaju i uklanjaju, ceo red za cekanje se tokom vremena pomera u nizu u


smeru kretanja kazaljke na satu.

U reprezentaciji reda za cekanje koja je prikazana na slici 4.12, kao


i u manjim varijacijama na tu temu (na primer, kada kursor r ukazuje
na prvu lokaciju iza poslednjeg elementa, a ne na sm poslednji element),
nailazimo na jednu teko u. Naime, problem je da ne moemo razlikovati
c
prazan od punog reda, ukoliko eksplicitno ne pratimo duinu reda. (Zain
teresovani citaoci se lako mogu uveriti da je ovo zaista problem.)
Zato se obi no koristi dodatna promenljiva, recimo l, koja sadri aktuc
elni broj elemenata reda u nizu a. Drugi na in za reavanje ovog problema
c
je ne dozvoliti da red ima vie od n 1 elemenata, ali imati jedan neupotrebljiv element u nizu izgleda manje prirodno nego imati jednu promenljivu
za pra enje duine reda.
c

Prema tome, red za cekanje se predstavlja identikuju im objektom q


c

koji obuhvata tri promenljive g, r i l, cija je uloga prethodno objanjena,


kao i niz a duine n za smetanje elemenata reda. Ako se koristi sabiranje
po modulu za realizaciju krunog izgleda niza a, algoritamska implemen
tacija operacije nad redom za cekanje, koja je data u nastavku, nije uopte

komplikovana. Citaoci se lako mogu uveriti da se svi navedeni algoritmi


izvravaju za konstantno vreme.
// Ulaz: red q
// Izlaz: poetno stanje reda q
c
algorithm queue-make(q)
q.g = 1;
q.r = n;
q.l = 0;
return;

// Ulaz: red q
// Izlaz: tano ako je q prazan, inae netano
c
c
c
algorithm queue-empty(q)
if (q.l == 0)
return true;
else


4.5. Redovi za cekanje

101

return false;
// Ulaz: red q
// Izlaz: tano ako je q pun, inae netano
c
c
c
algorithm queue-full(q)
if (q.l == n)
return true;
else
return false;
// Ulaz: novi element x, red q
// Izlaz: red q sa elementom x na kraju
algorithm enqueue(x, q)
// Pretpostavlja se da red nije pun
q.r = q.r % n + 1;
q.a[q.r] = x;
q.l = q.l + 1;
return;
// Ulaz: red q
// Izlaz: element x uklonjen iz reda q na poetku
c
algorithm dequeue(q)
// Pretpostavlja se da red nije prazan
x = q.a[q.g];
q.g = q.g % n + 1;
q.l = q.l - 1;
return x;

Zadaci
1. Virtuelna inicijalizacija niza. Ako je dat niz a 1 , . . ., a n duine n, naivni
na in za inicijalizaciju svih elemenata niza nekom vredno u x je:
c
c
algorithm array-init(a, n, x)
for i = 1 to n do
a[i] = x;
return a;

102

Osnovne strukture podataka

Ovaj algoritam o igledno zahteva vreme O(n) za izvravanje i konstantc


ni memorijski prostor (pored prostora potrebnog za sam niz). Pri tome,
obe operacije za pristup nekom elementu niza a koje su realizovane

algoritmima array-read(a,i), kojim se cita vrednost i-tog elementa


niza a, i array-write(a,i,x), kojim se upisuje vrednost x u i-ti element niza a, izvravaju se za konstantno vreme:
algorithm array-read(a, i)

algorithm array-write(a, i, x)

return a[i];

a[i] = x;
return a;

U nekim primenama je linearno vreme za inicijalizaciju niza neprihvatljivo dugo, pa je potrebno virtuelno inicijalizovati niz za konstantno
vreme. To je posebno zna ajno u slu ajevima kada se tokom rada proc
c
grama koristi zapravo samo mali deo nekog velikog niza. Napiite algoritme array-init(a,n,x), array-read(a,i) i array-write(a,i,x)
koji rade ta no ono to treba, ali svaki od njih se izvrava za konstantno
c

vreme. (Savet: Koristite dva dodatna niza veli ine n, pri cemu jedan od
c
njih simulira stek.)

2. Pokaite da je ispravna ova verzija linearnog algoritma mcss koja ima


samo jednu petlju:
// Ulaz: niz a, broj elemenata n niza a
// Izlaz: maksimalna suma podniza M
algorithm mcss(a, n)
M = 0;
// maksimalna suma podniza
s = 0;
for j = i to n do
s = s + a[j];
if (s < 0) then
s = 0;
else if (M < s) then
M = s;
return M;

3. Ako su date slede e liste naklonosti mladi a i devojaka, pronadite sva


c
c

mogu a stabilna vezivanja. (Savet: Ima ih ta no pet.)


c
c


4.5. Redovi za cekanje
mladi i
c
X
Y
Z
U
V

1
x
y
z
u
v

2
y
z
u
v
x

3
z
u
v
x
y

103
4
u
v
x
y
z

5
v
x
y
z
u

devojke
x
y
z
u
v

1
Y
Z
U
V
X

2
Z
U
V
X
Y

3
U
V
X
Y
Z

4
V
X
Y
Z
U

5
X
Y
Z
U
V

4. Pokaite da se u algoritmu smp zaista izvrava skoro n2 iteracija u


nekim instancama problema stabilnih brakova. (Savet: Uzmite da je
lista naklonosti svakog od n mladi a u obliku 1, 2, . . ., n 1, n, uzmite
c
da je lista naklonosti svake od n devojaka u obliku n, n 1, . . ., 2, 1, i
pretpostavite da se slobodni mladi i biraju krunim redom 1, 2, . . ., n i
c

zatim opet od 1, kao da se nalaze u redu za cekanje.)


5. Pokaite da je Gejl-ejpli algoritam polno nefer jer favorizuje mladi e
c
(kao i da je suprotno ta no ukoliko mladi i i devojke zamene uloge tako
c
c
to devojke prose mladi e i mladi i biraju bolje ponude). Speci no,
c
c
c
navedite primer lista naklonosti mladi a i devojaka tako da je dobijeno
c
stabilno vezivanje najbolje mogu e za mladi e i najgore mogu e za dec
c
c
vojke.
6. Koriste i strukture podataka iz ovog poglavlja, napiite detaljniji algoc
ritam smp na pseudo jeziku. Jo bolje, na svom omiljenom programskom
jeziku napiite i testirajte pravi program za reavanje problema stabilnih brakova. (Savet: Koristite strukture podataka koje su spomenute
kod analize vremena izvravanja algoritma smp.)
7. Napiite algoritam list-length(l) kojim se izra unava duina liste l
c
pretpostavljaju i da su liste implementirane pomo u pokaziva a. Anac
c
c
lizirajte vreme izvravanja svog algoritma.
8. Napiite algoritam list-copy(l1,l2) kojim se konstruie lista l 2 tako
da bude identi na kopija liste l 1 , a lista l 1 ostaje nepromenjena. Pretc
postavite da su liste implementirane pomo u pokaziva a i analizirajte
c
c
vreme izvravanja svog algoritma.
9. Napiite algoritam list-concat(l1,l2,l3) kojim se spajaju (konka-

104

Osnovne strukture podataka

teniraju) dve liste l 1 i l 2 u tre u listu l 3 . Pretpostavite da su liste imc


plementirane pomo u pokaziva a i analizirajte vreme izvravanja svog
c
c
algoritma.

10. Napiite algoritam list-deldup(l) kojim se uklanjaju svi duplikati iz


liste l. Pretpostavite da su liste implementirane pomo u pokaziva a i
c
c
analizirajte vreme izvravanja svog algoritma.

11. Napiite algoritam dlist-insert(x,l,p) kojim se cvor x dodaje iza

cvora p u dvostruko povezanu listu l. Pretpostavite da su liste implementirane pomo u pokaziva a i analizirajte vreme izvravanja svog
c
c
algoritma.

12. Jedan niz se moe iskoristiti za predstavljanje dva steka, jedan koji
raste udesno od po etka niza i drugi koji raste ulevo od kraja niza.
c
Implementirajte operacije nad stekom koriste i ovu reprezentaciju dva
c
steka pomo u jednog niza. Analizirajte vreme izvravanja tih operacija.
c

13. Pokaite da se red za cekanje moe implementirati pomo u dva steka,


c
odnosno napiite algoritme enqueue(q), dequeue(q) i queue-empty(q)
koriste i jedino operacije push, pop i stack-empty nad dva steka koji
c

predstavljaju jedan red za cekanje. Analizirajte vreme izvravanja tih

operacija nad redom za cekanje.

14. Pokaite da se stek moe implementirati pomo u dva reda za cekanje,


c
odnosno napiite algoritme push(x,s), pop(s) i stack-empty(s) koriste i jedino operacije enqueue, dequeue i queue-empty nad dva reda za
c

cekanje koji predstavljaju jedan stek. Analizirajte vreme izvravanja


tih operacija nad stekom.

15. Skup kao struktura podataka je kona na kolekcija elemenata (ili clac

nova) istog tipa. Dve konceptualne osobine skupa su da su svi njegovi


elementi medusobno razli iti i da ne postoji nikakva relacija uredenosti
c

medu elementima skupa. Jedan lak na in za predstavljanje skupa je


c

pomo u povezane liste njegovih elemenata. Na primer, na slici 4.13 je


c
prikazan skup S = { x1 , x2 , . . ., xn } predstavljen povezanom listom s.


4.5. Redovi za cekanje

x1

105

x2

xn

S LIKA 4.13: Skup S = { x1 , x2 , . . . , xn } predstavljen listom s.

Tipi ne skupovne operacije su dodavanje datog elementa skupu, uklac


njanje datog elementa iz skupa i provera da li dati element pripada
skupu.
a) Pretpostavljaju i implementaciju skupa pomo u liste njegovih elec
c
menata, napiite algoritme set-insert(x,s), set-delete(x,s)
i set-member(x,s) kojima se realizuju prethodne skupovne operacije. Za sve algoritme odredite vreme njihovog izvravanja.
b) Ako se elementi skupa mogu medusobno uporedivati, druga mo

gu nost za predstavljanje skupa pomo u liste je da se skupovni elec


c
menti u listi smetaju u rastu em redosledu. Ponovite prethodni
c
zadatak pretpostavljaju i ovakvu implementaciju skupa pomo u
c
c
sortirane liste njegovih elemenata.
16. Napiite algoritme za operacije unije i preseka dva skupa pretpostavljaju i implementaciju skupova pomo u a) nesortiranih listi i b) sortiranih
c
c
listi.

G LAVA

5
Rekurzivni algoritmi

U rekurzivnom algoritmu se do reenja problema dolazi pristupom od


opteg ka pojedina nom. To se neformalno moe opisati na slede i na in:
c
c
c
dati problem se reava tako to se najpre podeli u nekoliko manjih potproblema, zatim se nezavisno reava svaki od tih potproblema i, na kraju,
kombinovanjem njihovih reenja se dolazi do reenja polaznog problema.
Ako su manji potproblemi sli ni polaznom problemu, njihova reenja se
c
mogu dobiti ponovnom (rekurzivnom) primenom istog postupka. Naravno,
postupak deljenja u manje probleme se mora zavriti posle kona no mnogo
c

koraka i dobiti trivijalni potproblemi cija se reenja mogu neposredno dobiti bez daljeg deljenja. U suprotnom slu aju dolazi do programske greke,
c
jer bi rekurzivni algoritam nastavio proces deljenja potproblema u beskona nost i ne bi doao do reenja.
c
Rekurzivni na in reavanja problema u programiranju je vrlo vaan i
c

ekasan metod za reavanje sloenih problema. Takvi problemi se cesto


mogu mnogo prirodnije i jednostavnije reiti primenom rekurzije nego klasi nim, iterativnim putem. Poto rekurzivno reavanje problema zahteva
c

druga iji pristup u na inu programiranja, u ovom poglavlju cemo ilustroc


c
vati osnovne principe rekurzivnog razmiljanja kroz brojne reprezentativne primere. Pored toga, analiza rekurzivnih algoritama se ne sastoji od
pukog prebrojavanja jedini nih instrukcija, nego se zasniva na reavanju
c

tzv. rekurentnih jedna ina. O tome ce takode biti re i u ovom poglavlju.


c
c

108

Rekurzivni algoritmi

5.1

Iterativni i rekurzivni algoritmi

Rekurzivni metod je alternativni oblik programske kontrole u odnosu


na petlje, ali se takode sastoji od ponavljanja nekog istog postupka. Kada

se u iterativnom algoritmu koristi petlja, postupak koji se ponavlja navodi


se u formi tela petlje, a broj ponavljanja tela petlje kontrolie se uslovom
prekida (nastavka) petlje. Kod rekurzivnih algoritama, postupak koji se
ponavlja je sm algoritam koji sam sebe poziva radi viestrukog izvravanja. Broj ponavljanja tog postupka kontrolie se naredbom grananja u
rekurzivnom algoritmu kojom se odreduje da li isti algoritam treba pozvati

ili ne. U sutini dakle, rekurzivni i iterativni algoritmi predstavljaju razli


cite zapise za opis viestrukog ponavljanja jednog istog postupka.
Svaki problem koji se moe reiti rekurzivno moe se reiti i iterativno,
kao i obrnuto. Obratite ipak panju na to da postupak koji se ponavlja u
rekurzivnom i iterativnom algoritmu za isti problem ne mora biti identi
can.
Razmotrimo, na primer, izra unavanje stepena x n , gde je x neki realan
c
broj razli it od nule i n ceo broj ve i ili jednak nuli. Iterativni na in za reec
c
c
nje ovog problema sastoji se od uzastopnog mnoenja broja x sa parcijalno
izra unatim stepenima x i za i = 0, 1, . . ., n 1. Naredni iterativni algoritam
c
power1 koristi for petlju radi realizacije ovog postupka:
// Ulaz: realan broj x, ceo broj n 0
// Izlaz: broj x n
algorithm power1(x, n)
y = 1;
for i = 1 to n do
y = x * y;
return y;

Pored ovog klasi nog iterativnog na ina, za izra unavanje stepena moc
c
c
emo primeniti druga iji, rekurzivni pristup ukoliko uo imo da je x0 = 1 za
c
c
c
c
stepen n = 0 i x n = x x n1 za stepen n ve i od nule. Drugim re ima, ako je
stepen n = 0, rezultat je uvek 1, dok za stepen n > 0 rezultat dobijamo ako
x pomnoimo sa (n 1)-im stepenom broja x. Naredni rekurzivni algoritam
power2 koristi ovaj na in za izra unavanje n-tog stepena broja x:
c
c
// Ulaz: realan broj x, ceo broj n 0
// Izlaz: broj x n
algorithm power2(x, n)

5.1. Iterativni i rekurzivni algoritmi

109

if (n == 0)
return 1;
else
return x * power2(x,n-1);

Obratite panju na to da, za izra unavanje n-tog stepena broja x, rec


kurzivni algoritam power2 u drugoj naredbi return poziva sam sebe radi
izra unavanja (n 1)-og stepena broja x.
c
Rekurzivni algoritam je algoritam koji poziva sam sebe, bilo direktno
ili indirektno. Algoritam direktno poziva sam sebe (kao recimo power2)
ukoliko se u njegovoj deniciji nalazi poziv samog algoritma koji se denie. Algoritam indirektno poziva sebe ukoliko se u njegovoj deniciji
nalazi poziv drugog algoritma koji sa svoje strane poziva polazni algoritam
koji se denie (bilo direktno ili indirektno).
Mehanizam pozivanja rekurzivnih algoritama se ne razlikuje od standardnog mehanizma za obi ne algoritme: argumenti u pozivu algoritma
c
se najpre dodeljuju parametrima algoritma kao po etne vrednosti i zatim
c
se izvrava telo pozvanog algoritma. Medutim, ovde je vano primetiti

da poziv rekurzivnog algoritma generie lanac poziva istog algoritma za


reavanje niza prostijih zadataka sve dok se ne dode do najprostijeg za

datka cije je reenje o igledno. Tada se lanac rekurzivnih poziva prekida i


c
zapo eti pozivi se zavravaju jedan za drugim u obrnutom redosledu njihoc
vog pozivanja, odnosno sloenosti zadataka koje reavaju (od najprostijeg
zadatka ka sloenijim zadacima). Na taj na in, na kraju se dobija reenje
c
najsloenijeg polaznog zadatka.
Na primer, na slici 5.1 je ilustrovano rekurzivno izvravanje poziva
power2(1.5,3) kojim se izra unava 1.53 = 3.75.
c
power2(1.5,3)

power2(1.5,2)

power2(1.5,1)

return 1.5*power2(1.5,2)

return 1.5*power2(1.5,1)

return 1.5*power2(1.5,0)

3.75

2.25

1.5

power2(1.5,0)
return 1
1

S LIKA 5.1: Lanac rekurzivnih poziva za power2(1.5,3).


Na slici 5.1 gornje strelice pokazuju da poziv power2(1.5,3) najpre
proizvodi drugi poziv power2(1.5,2); ovaj drugi poziv zatim proizvodi
c
tre i poziv power2(1.5,1); i na kraju, tre i poziv dovodi do poslednjeg
c
poziva power2(1.5,0). U ovom lancu jedan poziv dovodi do drugog poziva
jer je u svim slu ajevima argument poziva za stepen razli it od nule. Zato
c
c

110

Rekurzivni algoritmi

se u telu algoritma power2 izvrava deo else naredbe if, odnosno naredba
return u kojoj se argument za broj x mnoi sa odgovaraju im rezultatom
c
poziva algoritma. Tek u poslednjem pozivu je argument za stepen jednak nuli, pa se izvravanjem dela then naredbe if kao rezultat dobija
broj 1. Nakon toga se lanac rekurzivnih poziva odmotava u obrnutom
smeru, kako to pokazuju donje strelice na slici 5.1. Pri tome se izvravanje
aktuelnog poziva sastoji od mnoenja rezultata odgovaraju eg zavrenog
c
poziva sa vredno u parametra x i dobijena vrednost se kao rezultat vra a
c
c
prethodnom pozivu.
Generalno, rekurzivni algoritmi reavaju neki zadatak svodenjem tog

zadatka na sli an prostiji zadatak (ili vie njih). Na primer, u algoritmu


c
power2 se problem izra unavanja n-tog stepena nekog broja reava svodec

njem na problem izra unavanja (n 1)-og stepena istog broja, koji je prostiji
c
u smislu da je stepen broja koji se izra unava za jedan manji. Prostiji
c
zadatak se zatim reava rekurzivnim pozivom algoritma koji se denie.
To sa svoje strane dovodi do svodenja tog prostijeg zadatka na jo prostiji

zadatak, a ovaj se onda opet reava rekurzivnim pozivom. Na primer, u


c
algoritmu power2 se problem izra unavanja (n 1)-og stepena broja svodi
na problem izra unavanja (n 2)-og stepena istog broja.
c
Ovaj postupak upro avanja polaznog zadatka se i dalje sli no nastac
c
vlja, pa bi se bez ikakve kontrole dobio beskona an lanac poziva istog algoc
ritma, to je programska greka sli na beskona noj petlji. Da bi se lanac
c
c
rekurzivnih poziva prekinuo na kraju, u svakom rekurzivnom algoritmu

mora se nalaziti bazni slu aj za najprostiji zadatak cije je reenje unapred


c
poznato i koje se ne dobija daljim rekurzivnim pozivima. To je u algoritmu
power2 slu aj kada je stepen n = 0, jer se onda rezultat 1 neposredno dobija
c
bez daljeg rekurzivnog reavanja.
Radi boljeg razumevanja ovih osnovnih elemenata rekurzivne tehnike

programiranja, u nastavku poglavlja cemo pokazati jo neke primere rekurzivnih algoritama.

Primer: rekurzivni Euklidov algoritam


U odeljku 3.2 na strani 60 pokazali smo ekasan iterativni (Euklidov)
algoritam za izra unavanje najve eg zajedni kog delioca nzd(x, y) dva poc
c
c
zitivna cela broja x i y. Podsetimo se da se taj iterativni algoritam zasniva

na cinjenici da je nzd(x, y) = nzd(y, x%y) za x y. Ista cinjenica se moe


iskoristiti i za (ekasan) rekurzivni algoritam za izra unavanje nzd(x, y)
c
ukoliko to izra unavanje podelimo u dva slu aja:
c
c

5.1. Iterativni i rekurzivni algoritmi

111

bazni slu aj: ako je x % y = 0, onda je o igledno nzd(x, y) = y;


c
c
opti slu aj: ako je x % y = 0, onda je nzd(x, y) = nzd(y, x%y).
c
Prema tome, nzd(x, y) se moe rekurzivno denisati na slede i na in:
c
c
nzd(x, y) =

y,

ako je x % y = 0

nzd(y, x % y),

ako je x % y = 0 .

Na osnovu ove rekurzivne denicije sada je lako napisati rekurzivni Euklidov algoritam za izra unavanje nzd(x, y):
c
// Ulaz: celi brojevi x i y takvi da x y > 0
// Izlaz: nzd(x, y)
algorithm euclid(x, y)
if (x % y == 0) then // bazni sluaj
c
return y;
else
// opti sluaj
c
return nzd(y,x % y);

U ovom algoritmu u drugoj naredbi return primetimo da su u rekurzivnom pozivu nzd(y, x % y) oba argumenta manja od polaznih brojeva x
i y. To zna i da se tim pozivom zaista reava prostiji zadatak izra unac
c
vanja najve eg zajedni kog delioca za par manjih brojeva. Ostatak pri
c
c
celobrojnom deljenju u lancu rekurzivnih poziva se dakle stalno smanjuje

i zato u jednom trenutku mora biti nula. Tada ce se lanac prekinuti,


jer se onda rezultat neposredno dobija kao vrednost drugog argumenta
poslednjeg poziva u lancu.

Primer: Fibonacijev niz brojeva


Fibona ijev niz brojeva ima brojne primene u umetnosti, matematici i
c
ra unarstvu. Prva dva broja Fibona ijevog niza brojeva su 1 i 1, a svaki
c
c
slede i broj u nizu se zatim dobija kao zbir prethodna dva broja niza. Tako,
c

tre i broj niza je zbir drugog i prvog, odnosno 1 + 1 = 2; cetvrti broj niza je
c

c
zbir tre eg i drugog, odnosno 2 + 1 = 3; peti broj niza je zbir cetvrtog i tre eg,
c
c
c
odnosno 3 + 2 = 5; i tako dalje. Prema tome, po etni deo Fibona ijevog niza
brojeva je:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, . . .
Za izra unavanje n-tog broja Fibona ijevog niza moe se po eti od prva
c
c
c
dva broja tog niza i zatim primeniti iterativni postupak u kojem se u svakom koraku redom izra unava naredni broj u nizu dok se ne dobije traeni
c

112

Rekurzivni algoritmi

n-ti broj. U nastavku je predstavljen iterativni algoritam u kojem se koriste tri promenljive koje u svakom koraku sadre prethodna dva broja niza
(promenljive x i y) i naredni broj niza (promenljiva z):
// Ulaz: n 1
// Izlaz: n-ti broj Fibonaijevog niza
c
algorithm fib1(n)
x = 1; y = 1; z = 1;
for i = 3 to n do
z = x + y;
x = y;
y = z;
return z;

Ako brojeve Fibona ijevog niza ozna imo sa f 1 , f 2 , f 3 , . . ., onda je o ec


c
c
vidno rekurzivna denicija za n-ti broj Fibona ijevog niza:
c
f 1 = 1, f 2 = 1
f n = f n 1 + f n 2 ,

n > 2.

Drugim re ima, prva dva broja f 1 i f 2 su jednaki 1, a n-ti broj za n > 2 je


c
c
jednak zbiru prethodna dva, tj. (n 1)-og i (n 2)-og, broja Fibona ijevog
niza.
Za izra unavanje n-tog broja Fibona ijevog niza moemo lako napisati
c
c
rukurzivni algoritam ukoliko iskoristimo prethodnu rekurzivnu deniciju
tog broja:
// Ulaz: n 1
// Izlaz: n-ti broj Fibonaijevog niza
c
algorithm fib2(n)
if (n <= 2) then // bazni sluaj
c
return 1;
else
// opti sluaj
c
return fib(n-1) + fib(n-2);

U ovom algoritmu primetimo da se zadatak izra unavanja n-tog broja


c
Fibona ijevog niza svodi na dva sli na prostija zadatka, odnosno izra unac
c
c
c
c
vanje (n 1)-og i (n 2)-og broja Fibona ijevog niza. Zato se pomo u dva
c
rekurzivna poziva fib(n-1) i fib(n-2) izra unavaju vrednosti (n 1)-og
c
c
i (n 2)-og broja Fibona ijevog niza, a njihov zbir se kao rezultat vra a za
n-ti broj Fibona ijevog niza.
c

5.1. Iterativni i rekurzivni algoritmi

113

Primer: Hanojske kule


Problem Hanojskih kula je jednostavna igra u kojoj su na po etku n
c
diskova razli ite veli ine poredani na jednom od tri stuba u opadaju em
c
c
c

redosledu svoje veli ine od podnoja tog stuba ka vrhu. Na slici 5.2 je pric
kazana po etna konguracija ove igre za n = 5 diskova ukoliko zamislimo
c
da su tri stuba trougaono rasporedeni.

S LIKA 5.2: Po etna konguracija igre Hanojskih kula.


c
Cilj igre je da se svi diskovi premeste sa po etnog stuba na drugi stub
c
koriste i tre i stub kao pomo ni. Pri tome, samo disk sa vrha jednog stuba
c
c
c
se moe premestiti na vrh drugog stuba i nikad se ve i disk ne sme postac
viti iznad manjeg diska.
Preciznije re eno, igra Hanojskih kula se sastoji od tri stuba A, B i
c
C, kao i od n diskova razli ite veli ine pre nika d 1 < d 2 < < d n . Svi
c
c
c
diskovi su po etno poredani na stubu A u opadaju em redosledu svoje
c
c

veli ine od podnoja stuba A, odnosno disk najve eg pre nika d n se nalazi
c
c
c
na dnu i disk najmanjeg pre nika d 1 se nalazi na vrhu stuba A. Cilj igre je
c
premestiti sve diskove na stub C koriste i stub B kao pomo ni i potuju i
c
c
c
dva pravila:
Samo se disk sa vrha jednog stuba moe premestiti na vrh drugog
stuba.
Nikad se ve i disk ne moe nalaziti iznad manjeg diska.
c
Primetimo da ova pravila impliciraju da se samo po jedan disk moe
premetati, kao i da se svi diskovi u svakom trenutku moraju nalaziti samo
na stubovima.

114

Rekurzivni algoritmi

Bez mnogo objanjenja navodimo reenje igre koje se dobija iterativnim


postupkom korak po korak: u svakom neparnom koraku, premestiti najmanji disk na naredni disk u smeru kretanja kazaljke na satu; u svakom
parnom koraku, legalno premestiti jedini mogu i disk koji nije najmanji.
c

Ovaj postupak je ispravan, kao to se u to paljivi citaoci mogu sami uveriti, ali je teko razumeti zato je to tako i jo je tee do i do njega.
c

Igra Hanojskih kula je primer problema cije se reenje mnogo lake i


prirodnije dobija rekurzivnim postupkom. Zadatak premetanja n diskova
sa stuba A na stub C koriste i B kao pomo ni stub moemo svesti na
c
c
dva sli na prostija zadatka premetanja (n 1)-og diska. Prvi zadatak je
c
c
premetanje n 1 najmanjih diskova sa stuba A na stub B koriste i C kao
pomo ni stub. Drugi zadatak je premetanje n 1 najmanjih diskova sa
c
stuba B na stub C koriste i A kao pomo ni disk. (Ovo su prostiji zadaci u
c
c
smislu da se reava sli an problem za manji broj diskova.) Polazni problem
c
za n diskova onda moemo reiti rekurzivnim postupkom koji se sastoji od
tri koraka:
1. Primenjuju i rekurzivni postupak za reenje prvog zadatka, najpre
c
c
premetamo n 1 najmanjih diskova sa stuba A na stub B koriste i
stub C kao pomo ni.
c
2. Na taj na in nam ostaje samo najve i disk na stubu A. Zatim premec
c
tamo taj najve i disk sa stuba A na slobodni stub C.
c
3. Na kraju, primenjuju i isti rekurzivni postupak za reenje drugog
c
zadatka, svih n 1 najmanjih diskova koji se nalaze na stubu B
premetamo na stub C koriste i stub A kao pomo ni.
c
c
Ovaj rekurzivni postupak je ilustrovan na slici 5.3. Na toj slici su
prikazani rezultati prethodna tri koraka od po etne konguracije za n = 5
c
diskova.
Obratite panju na to koliko je rekurzivno reenje problema Hanojskih kula konceptualno jednostavnije za razumevanje. Moda jo vanije,

verovatno su i sami citaoci relativno lako doli do njega. Ova jednostav


nost rekurzivnog postupka je prevashodno ono to cini rekurzivnu tehniku
vanom, mada su u mnogim slu ajevima dobijeni rekurzivni algoritmi i
c
ekasniji od klasi nih.
c
Pretpostavimo da na raspolaganju imamo algoritam move(x,y) kojim
se jedan disk na vrhu stuba x premeta na vrh diskova na stubu y. Ovaj algoritam je trivijalan, ali ga ne navodimo jer njegova implementacija veoma
zavisi od konkretnog programskog jezika. Onda se slede im jednostavnim
c

5.1. Iterativni i rekurzivni algoritmi


1.

115

2.

3.

4.

S LIKA 5.3: Rekurzivno reenje problema Hanojskih kula.

rekurzivnim algoritmom odreduje niz poteza kojima se premetaju n di


skova sa stuba A na stub C koriste i B kao pomo ni stub:1
c
c

// Ulaz: n 1, poetni, pomoni i ciljni stub


c
c
// Izlaz: niz poteza za n diskova problema Hanojskih kula
algorithm toh(n, a, b, c)
if (n == 1) // bazni sluaj
c
move(a,c);
else
// opti sluaj
c
toh(n-1,a,c,b);
move(a,c);
toh(n-1,b,a,c);
return;

1 Ime algoritma toh je skra enica od engleskog naziva za igru Hanojskih kula: the
c
Towers of Hanoi.

116

Rekurzivni algoritmi

5.2

Analiza rekurzivnih algoritama

U poglavlju 3 smo pokazali kako se analiziraju iterativni algoritmi i


objasnili smo da se to svodi, u sutini, na prebrojavanje jedini nih inc
strukcija koje se izvode za vreme izvravanja takvih algoritama. Kod rekurzivnih algoritama je dinamika njihovog izvravanja sloenija i puko
prebrojavanje jedini nih instrukcija moe biti prili no komplikovano. Zbog
c
c
toga se vreme izvravanja rekurzivnih algoritama odreduje na druga iji
c

na in i predstavlja se u obliku rekurentnih jedna ina. Te jedna ine opisuju


c
c
c
ukupno vreme izvravanja rekurzivnog algoritma za ulaz veli ine n na
c
osnovu vremena izvravanja istog algoritma za ulaze veli ine manje od
c
n. Poto za reavanje rekurentnih jedna ina postoji razvijen matemati ki
c
c
aparat, time se na relativno lak na in mogu dobiti i ocene performansi
c
rekurzivnih algoritama.
Radi ilustracije, razmotrimo algoritam toh iz prethodnog odeljka za
reavanje problema Hanojskih kula i neka je T(n) njegovo vreme izvr
avanja za n diskova. (Citaoci bi do sada trebalo da prepoznaju da je
veli ina ulaza za ovaj problem predstavljena brojem diskova.) Nije se teko
c
ubediti da se algoritam move u svakoj konkretnoj realizaciji izvrava za
konstantno vreme, pa ga radi jednostavnosti moemo smatrati jedini nom
c
instrukcijom. Kako se u algoritmu toh za n = 1 izvrava samo algoritam
move, to je T(1) = 1. Za n > 1 se u algoritmu toh izvravaju dva rekurzivna
poziva istog algoritma za n 1 disk, kao i algoritam move, pa je u tom
slu aju ukupno vreme T(n) = 2T(n 1) + 1. Vreme izvravanja algoritma
c
toh moe se dakle kra e zapisati u obliku jedna ine:
c
c
T(n) =

1,

ako je n = 1

2T(n 1) + 1, ako je n > 1 .

(5.1)

Ovo je primer rekurentne jedna ine u kojoj se vrednost funkcije T(n)


c
denie tako to se navodi po etni uslov za odredenu vrednost argumenta
c

n, a za druge vrednosti argumenta n se T(n) denie na osnovu vrednosti


iste funkcije kada je argument manji od n. Na primer, u konkretnom
slu aju rekurentne jedna ine (5.1) za vreme izvravanja algoritma toh,
c
c
po etni uslov je T(1) = 1, dok se T(n) za n > 1 predstavlja izrazom u kojem
c
u estvuje vrednost za T(n 1).
c
Reavanje rekurentne jedna ine u optem slu aju sastoji se u odredic
c

vanju zatvorenog izraza za T(n) u funkcijskom obliku samo od argumenta


c
n, bez ijednog pojavljivanja vrednosti T(m) za neko m < n. Jedan na in za

5.2. Analiza rekurzivnih algoritama

117

dobijanje reenja neke rekurentne jedna ine je primena tzv. postupka viec
struke zamene u kojem se sukcesivno zamenjuje opti izraz za T(n) umesto
c
vrednosti T(m) za neko m < n na desnoj strani rekurentne jedna ine, sve
dok se ne eliminiu sve takve vrednosti i ne dobije po etni uslov.
c
Na primer, ukoliko se primeni ovaj postupak na rekurentnu jedna inu
c
(5.1) za vreme izvravanja algoritma toh, opti izraz za T(n) treba zameniti
c
umesto T(n 1), T(n 2), . . ., T(2) na desnoj strani rekurentne jedna ine
c
(5.1) za n > 1. Na kraju treba zameniti po etni uslov T(1) i pojednostaviti
rezultuju u formulu. Na taj na in se dobija slede e reenje za T(n):
c
c
c
T(n) = 2 T(n 1) + 1
= 2 2T(n 2) + 1 + 1 = 22 T(n 2) + 2 + 1
= 22 2T(n 3) + 1 + 2 + 1 = 23 T(n 3) + 22 + 2 + 1

.
.
.
= 2n1 T(1) + 2n2 + + 22 + 2 + 1
= 2 n 1 1 +

n 2
i =0

2 i = 2 n 1 +

2 n 1 1
= 2 2 n 1 1
21

= 2 1.

Primetimo da je reenje T(n) = 2n 1 zapravo broj poteza u reenju problema Hanojskih kula za n diskova, jer izvravanje algoritma move predstavlja upravo jedan potez u reenju.
Da bismo bolje uvebali rekurzivni na in reavanja problema i analizu
c

odgovaraju ih rekurzivnih algoritama, u nastavku cemo pokazati jo neke


c
primere rekurzivne tehnike.

Primer: sortiranje objedinjavanjem (merge-sort)


Mada smo problem sortiranja denisali za nizove brojeva, algoritam
za njegovo reavanje o kome govorimo u ovom odeljku se najbolje moe
objasniti preko liste brojeva. Ne postoje sutinske prepreke za primenu tog
algoritma na nizove, nego je prosto lake opisati i razumeti algoritam na
apstraktnijem nivou liste brojeva. Naime, u slu aju nizova bismo morali da
c
nepotrebno posvetimo panju nevanim detaljima manipulisanja indeksa
nizova, to nije slu aj kod listi.
c
Metod sortiranja neuredene (jednostruko povezane) liste brojeva, koji

se popularno naziva sortiranje objedinjavanjem (engl. merge-sort), zasniva

118

Rekurzivni algoritmi

se na tri glavna koraka. U prvom koraku se najpre deli data lista l od n


brojeva u dve manje liste l 1 i l 2 od otprilike n/2 elemenata u svakoj. U
drugom koraku se zatim rekurzivno sortiraju ove dve polovi ne liste poc
sebno. Na kraju, u tre em koraku se dve sortirane polovi ne liste dobijene
c
c

u drugom koraku objedinjuju u zavrnu sortiranu celu listu. Sada cemo


ove korake redom detaljnije objasniti.
Da bismo datu listu l podelili u dve polovi ne liste l 1 i l 2 u prvom
c
koraku, redom uklanjamo glavu date liste i dodajemo je naizmeni no na
c
po etak prve ili druge liste. Ako iskoristimo operacije za rad sa listom iz
c
odeljka 4.3, realizacija ovog postupka na pseudo jeziku je:
// Ulaz: lista l
// Izlaz: liste l 1 i l 2 formirane od naizmeninih elemenata liste l
c
algorithm list-split(l, l1, l2)
l1 = null; l2 = null;
pd = true; // indikator dodavanja prvoj ili drugoj listi
while (l != null) do
x = l;
// uklanjanje glave liste l
l = list-delete(null,l);
if (pd) then // dodavanje glave liste l na poetak liste l 1
c
l1 = list-insert(x,null,l1);
else
// dodavanje glave liste l na poetak liste l 2
c
l2 = list-insert(x,null,l2);
pd = !pd;
return l1, l2;

Objediniti dve sortirane liste u tre em koraku sortiranja objedinjavac


njem zna i proizvesti jedinstvenu sortiranu listu koja sadri sve elemente
c
datih listi (i nijedan drugi element). Na primer, ako su date dve sortirane
liste 1, 2, 3, 7, 8 i 1, 2, 6, 9, jedinstvena sortirana lista dobijena njihovim
objedinjavanjem je 1, 1, 2, 2, 3, 6, 7, 8, 9. Obratite panju na to da se kod
objedinjavanja dve liste uvek podrazumeva da su one ve sortirane.
c
Jednostavan postupak za objedinjavanje dve sortirane liste jeste da se
obe liste paralelno ispituju redom od po etka do kraja. Pri tome se u svac
kom koraku uporeduju glave dve liste, bira se manji element od njih (ako su

oba elementa jednaka, uzima se bilo koji) za naredni element objedinjene


liste i, na kraju, uklanja se izabrani element iz njegove liste. Realizacija
ovog postupka na pseudo jeziku je:
// Ulaz: sortirane liste l 1 i l 2
// Izlaz: sortirana lista l formirana objedinjavanjem l 1 i l 2

5.2. Analiza rekurzivnih algoritama

119

algorithm list-merge(l1, l2, l)


l = null; // glava liste l
r = null; // rep liste l
while ((l1 != null) && (l2 != null)) do
if (l1.klju <= l2.klju) then
c
c
x = l1;
l1 = list-delete(null,l1);
else
x = l2;
l2 = list-delete(null,l2);
l = list-insert(x,r,l);
r = x;
while (l1 != null) do
x = l1;
l1 = list-delete(null,l1);
l = list-insert(x,r,l);
r = x;
while (l2 != null) do
x = l2;
l2 = list-delete(null,l2);
l = list-insert(x,r,l);
r = x;
return l1, l2;

Upotrebom prethodna dva algoritma u prvom i tre em koraku postupka


c
za sortiranje objedinjavanjem i dva rekurzivna poziva za sortiranje manjih
lista brojeva u drugom koraku, kompletan algoritam za sortiranje objedinjavanjem na pseudo jeziku je:
// Ulaz: neureena lista l
d
// Izlaz: sortirana lista l
algorithm merge-sort(l)
if (l.sled != null) then // lista ima vie od jednog elementa
l1, l2 = list-split(l,l1,l2);
l1 = merge-sort(l1);
l2 = merge-sort(l2);
l = list-merge(l1,l2,l);
return l;

Pokaimo kako radi algoritam merge-sort na jednom primeru liste


c
jednocifrenih brojeva 8, 6, 9, 2, 2, 1, 1, 7, 3. Radi kra eg zapisa, da bismo
predstavili liste u ovom primeru, izostavljamo zagrade i zapete izmedu

cifara. Tako, ulazna lista je l = 869221173. Ova lista se najpre algoritmom

120

Rekurzivni algoritmi

list-split deli u dve liste l 1 i l 2 . Ove liste se sastoje od svakog drugog

elementa polazne liste, odnosno prva lista sadri neparne, a druga parne
elemente polazne liste. Konkretno, l 1 = 89213 i l 2 = 6217. Zatim se ove
polovi ne liste rekurzivno sortiraju istim algoritmom, to kao rezultat daje
c
liste l 1 = 12389 i l 2 = 1267. Na kraju, algoritam list-merge proizvodi
objedinjenu sortiranu listu l = 112236789.
Nema, naravno, nita magi nog kod sortiranja dve manje liste, ve se
c
c
to dobija sistemati nom primenom rekurzivnog algoritma. Naime, algoritc
mom merge-sort se najpre deli ulazna lista na dve manje liste, a zatim
se nastavlja ovo rekurzivno deljenje manjih lista sve dok se ne dobije to da
svaka lista ima po jedan element. Na slici 5.4(a) je prikazano ovo rekurzivno deljenje listi iz primera. Zatim se dobijene manje liste objedinjuju
u parovima, idu i odozdo uz stablo, dok se cela lista ne dobije sortirana.
c
Ovaj proces je prikazan na slici 5.4(b). Medutim, vredno je uo iti da je ovo
c

deljenje i objedinjavanje manjih listi isprepletano, tj. sva objedinjavanja


ne slede iza svih deljenja. Na primer, za manju listu l 1 = 89213 se izvravaju sva deljenja i objedinjavanja pre nego to se bilo ta uradi sa drugom
manjom listom l 2 = 6217.
112236789

869221173

89213

823

83

91

12389

6217

61

238

27

38

(a) deljenje

1267

19

16

27

(b) objedinjavanje

S LIKA 5.4: Rekurzivno deljenje i objedinjavanje listi.

Analiza algoritma merge-sort. Neka je T(n) vreme izvravanja algoritma merge-sort za ulaznu listu l od n elemenata. Na osnovu dizajna
tog algoritma moemo zaklju iti da vreme njegovog izvravanja zavisi od
c
dva slu aja: kada ulazna lista ima jedan element (n = 1) i kada ima vie od
c
jednog elementa (n > 1).
Ako je n = 1, u tom algoritmu se izvrava konstantan broj instrukcija
za proveravanje uslova naredbe if i izvravanje naredbe return. Ukoliko

5.2. Analiza rekurzivnih algoritama

121

u ovom slu aju pojednostavimo analizu zanemarivanjem ta nog broja tih


c
c
jedini nih instrukcija, pod pretpostavkom da se sve one zbirno izvravaju
c
za konstantno vreme c 1 dobijamo da je T(1) = c 1.
Ako je n > 1, u algoritmu merge-sort se izvrava deo then naredbe
if, odnosno izvravaju se algoritmi list-split i list-merge i dva rekurzivna poziva samog algoritma merge-sort za sortiranje dve manje liste od

otprilike n/2 elemenata. Nije se teko uveriti, to ostavljamo citaocima da


provere, da je vreme izvravanja oba algoritma list-split i list-merge
proporcionalno duini ulazne liste n. Prema tome, ako su faktori te proporcionalnosti konstante c 2 i c 3 , onda su njihova vremena izvravanja c 2 n
i c 3 n.
Na osnovu dosadanje analize moe se dakle zaklju iti da je rekurentna
c
jedna ina za T(n) data izrazom:
c
T(n) =

ako je n = 1

c1,

2T(n/2) + c 2 n + c 3 n, ako je n > 1 .

U ovoj jedna ini ta ne vrednosti konstanti c 1 , c 2 i c 3 nisu bitne, jer nas


c
c
interesuje asimptotsko vreme izvravanja u najgorem slu aju. Zbog toga
c
c
moemo pretpostaviti da su one sve jednake, tj. c 1 = c 2 = c 3 = c (uzimaju i

recimo najve u od njih), cime se dobija rekurentna jedna ina za T(n) koja
c
c
je prostija za reavanje:
T(n) =

c,

ako je n = 1

2T(n/2) + 2cn, ako je n > 1 .

(5.2)

Uzgred, obratite panju na jo jedno suptilno pojednostavljenje u jedna ini (5.2). Naime, duina listi l 1 i l 2 u rekurzivnim pozivima algoritma
c

merge-sort nije uvek jednaka n/2. Paljivi citaoci mogu lako proveriti da
c
su te duine zapravo n/2 1 i n/2 , pa bi u jedna ini (5.2) za n > 1 na desnoj strani trebalo da stoji T n/2 1 + T n/2 + 2cn. Kako je uvek n/2
1 n/2 , ovu desnu stranu moemo pojednostaviti piu i 2T n/2 + 2cn.
c
(Ovde prirodno pretpostavljamo da je T(n) rastu a funkcija i, radi jednoc
stavnosti, koristimo jednakost umesto preciznije nejednakosti .) U stvari,

ovo cemo dalje pojednostaviti i potpuno zanemariti rad sa celobrojnim delovima realnih vrednosti, kako u jedna ini (5.2) tako i u preostalom delu
c
knjige. To ima opravdanja jer se paljivijom analizom moe pokazati da to
moemo uvek uraditi bez gubitka optosti, pa radi jednostavnosti namerno
biramo da budemo malo neprecizniji nautrb formalne ta nosti.
c

122

Rekurzivni algoritmi

Ako se sada vratimo reavanju rekurentne jedna ine (5.2), podsetimo


c
se da metodom viestruke zamene treba opti oblik za T(n) zamenjivati na
desnoj strani umesto vrednosti funkcije T za argumente manje od n, sve
dok se ne dode do po etnog uslova. Tako, pod pretpostavkom n/2 > 1 i obac

vljaju i jednu takvu zamenu u jedna ini (5.2) na desnoj strani, dobijamo:
c
c
T(n) = 2 2T n/22 + 2c n/2 + 2cn
= 22 T n/22 + 4cn .

U ovoj jedna ini zamenjuju i dalje optu jedna inu za T n/22 na desnoj
c
c
c
strani dobijamo novu jedna inu:
c
T(n) = 22 2T n/23 + 2c n/22 + 4cn
= 23 T n/23 + 6cn .

Nastavljaju i ovaj postupak zamene na desnoj strani prethodnih jednac

cina, nije teko prepoznati obrazac po kojem se dobija opti oblik na desnoj
strani izraza za T(n):
T(n) = 2 i T n/2 i + 2icn,

i = 1, 2, 3, . . .

Po etni uslov T(1) = c na desnoj strani ove jedna ine dobija se kada je
c
c
i
i
n/2 = 1, odnosno n = 2 , ili i = log n. Zamenom tog uslova na desnoj strani
najzad dobijamo reenje jedna ine (5.2) u zatvorenom obliku:
c
T(n) = nT(1) + 2cn log n = cn + 2cn logn .
Ako se podsetimo asimptotske notacije iz odeljka 3.2, nije teko pokazati da se ovo reenje moe dalje izraziti O-zapisom u obliku T(n) =
O(n log n). Drugim re ima, vreme izvravanja algoritma merge-sort je
c
linearno-logaritamsko, to je asimptotski mnogo bre od kvadratnog vremena izvravanja jednostavnih algoritama za sortiranje o kojima smo govorili u odeljku 2.3 na strani 34.

Primer: sortiranje razdvajanjem (quick-sort)

U ovom odeljku cemo pokazati jo jedan rekurzivan na in za reavanje


c
problema sortiranja. Taj metod za sortiranje neuredenog niza brojeva, koji

se popularno naziva sortiranje razdvajanjem (engl. quick-sort), jedan je od


naj e e kori enih metoda u praksi. Mada u najgorem slu aju nije bolji od
c c
c
c
sporih, kvadratnih metoda sortiranja, u prakti nim primenama se pokazao
c

5.2. Analiza rekurzivnih algoritama

123

toliko ekasnim da je cak na engleskom dobio ime koje u prevodu zna i


c
brzo sortiranje.
Algoritam za sortiranje niza razdvajanjem sastoji se od dva glavna
koraka. U prvoj fazi se ulazni niz koji treba sortirati deli u dva podniza
tako to se bira jedan element datog niza oko kojeg se dati niz razdvaja.
Taj izabrani element se naziva pivot, a najbolji slu aj se dobija kada se
c
ulazni niz preuredi tako da pivot podeli taj niz u dva priblino jednaka
dela.
Konkretno, neka je ulazni niz a od n elemenata koji treba sortirati.
Ako je p vrednost izabranog pivot elementa, tada se pivot smeta na svoje
pravo mesto u sortiranom nizu, svi elementi niza koji su manji ili jednaki
pivotu premetaju se tako da se nalaze levo od njega, a svi elementi koji su
ve i od pivota se premetaju tako da se nalaze desno od njega. To formalno
c
zna i da se elementi niza permutuju tako da budu zadovoljena slede a tri
c
c
uslova:
a k = p za neko k izmedu 1 i n;

a i p za svako i tako da je 1 i k; i
a i > p za svako i tako da je k + 1 i n.
Na slici 5.5 je prikazan rezulat ove permutacije elemenata u prvoj fazi
algoritma.
1

k +1

a
ai p

ai > p

S LIKA 5.5: Podela niza kod sortiranja razdvajanjem.


U drugoj fazi sortiranja razdvajanjem se rekurzivno sortiraju dve oblasti originalnog niza koje se nalaze sa obe strane pivota. Time se, u stvari,
automatski dobija ceo niz potpuno sortiran, jer su svi elementi u prvoj
oblasti levo od pivota manji od svih elemenata u drugoj oblasti desno od
pivota.
Izbor dobrog pivota je klju ni korak u algoritmu, jer ukoliko je veli ina
c
c
dve oblasti sa obe strane pivota podjednaka, vreme potrebno za njihovo

sortiranje ce biti otprilike isto. To onda izbalansirano sa vremenom za


podelu niza dovodi do ekasnog sortiranja. Najbolji kandidat od elemenata
niza da bude pivot, jeste, dakle, onaj element niza koji je ve i od otprilike
c

124

Rekurzivni algoritmi

polovine elemenata i manji od otprilike druge polovine elemenata niza. Taj


element koji je u sredini sortiranog niza naziva se medijana niza. Medu
tim, nalaenje medijane niza nije jednostavno i zahteva vie vremena nego
to se to isplati. Zbog toga, pivot se obi no bira na jednostavan na in, u
c
c
nadi da je izabrani element blizu medijane. Ono to je iznenaduju e je da
c

se ovaj pristup pokazao dobrim u praksi, jer je sortiranje razdvajanjem vrlo


ekasno u proseku.
Mogu i na ini za jednostavan izbor pivota koji se primenjuju u praksi
c
c

obuhvataju izbor prvog, poslednjeg, srednjeg, ili cak slu ajnog elementa
c

(pod)niza. U nastavku ovog odeljka cemo opisati postupke za razdvajanje


podniza izborom njegovog prvog i poslednjeg elementa za pivota, dok se

izbor srednjeg elementa niza za pivota ostavlja citaocima za laku vebu.


Razmotrimo najpre razdvajanje niza kada se bira njegov prvi element
za pivota. Pretpostavimo da elimo da podelimo podniz a l , . . ., a r , gde je
1 l r n, i neka je pivot prvi element tog podniza p = a l . Da bismo
preuredili elemente oko pivota p, elemente podniza redom ispitujemo samo
jednom, ali to radimo od oba kraja. Ako je i indeks ispitanih elemenata
idu i od levog kraja i j indeks ispitanih elemenata idu i od desnog kraja,
c
c
to zna i da oni na po etku imaju vrednosti l + 1 i r, tim redom. Zatim se
c
c
indeks i uve ava za 1 sve dok ne naidemo na element takav da je a i > p,
c

a indeks j se smanjuje za 1 sve dok ne naidemo na element takav da je

a j p. Na slici 5.6 je ilustrovan ovaj postupak.


l

p
p

>p

>p

S LIKA 5.6: Pivotiranje sa prvim elementom podniza.


Prema tome, od levog kraja podniza se preska u svi elementi koji su
c
c
manji ili jednaki p dok se ne otkrije element a i koji je ve i od p. Zatim od
desnog kraja podniza se preska u svi elementi koji su ve i od p dok se ne
c
c
otkrije element a j koji je manji ili jednak p. Dodatno, da bi se elementi a i i
a j premestili na pravu stranu u odnosu na pivota, medusobno se zamenjuju

njihove vrednosti. Ovaj isti postupak se ponavlja sve dok je i < j. Kada se
c
indeksi i i j preklope (tj. i j), to zna i da je ispitan ceo podniz. Ono to
preostaje je da se medusobno zamene elementi a l i a j da bi se pivot element

premestio na njegovo pravo mesto.

5.2. Analiza rekurzivnih algoritama

125

Ovaj postupak na pseudo jeziku je u nastavku predstavljen algoritmom


partition kojim se razdvaja podniz a l , . . ., a r oko njegovog prvog elementa
izabranog za pivota i vra a indeks tog pivota u rezultuju em preuredenom
c
c

podnizu.
// Ulaz: podniz niza a ogranien indeksima od l do r
c
// Izlaz: preureen podniz i njegov indeks u kome se nalazi pivot
d
algorithm partition(a, l, r)
// Pretpostavlja se da je a r+1 = +
p = a[l];
i = l + 1; j = r;
while (i < j) do
while (a[i] <= p) do i = i + 1;
while (a[j] > p) do j = j - 1;
swap(a[i],a[j]);
swap(a[l],a[j]);
return j;

U algoritmu partition imamo jedan tehni ki problem koji smo razrec


ili tako to smo ga ignorisali. Naime, kada se po prvi put redom ispituje
podniz, po inju i od levog kraja i trae i element koji je ve i od pivota p,
c
c
c
c
postoji mogu nost da se prede preko desnog kraja podniza. To se deava
c

ukoliko je pivot najve i element podniza ili su svi elementi podniza jednaki.
c
Da bismo u algoritmu partition izbegli proveravanje ovih uslova i tako
pokvarili njegovu jednostavnost, unapred smo pretpostavili da uvek postoji
grani ni element podniza na desnom kraju tako da je a r+1 = +. Aktuelni
c

detalji reenja ovog tehni kog problema se preputaju citaocima za laku


c
vebu.
Razmotrimo sada razdvajanje niza kada se bira njegov poslednji element za pivota. U ovom slu aju se niz redom ispituje samo u jednom
c

smeru (sleva na desno) i deli u cetiri (mogu e prazne) oblasti kao to je


c
to prikazano na slici 5.7.
r

a
p

>p

=p

S LIKA 5.7: Pivotiranje sa poslednjim elementom podniza.

Svaka od cetiri oblasti niza na slici 5.7 zadovoljava odreden uslov koji

126

Rekurzivni algoritmi

je nazna en ispod odgovaraju e oblasti. Imaju i to na umu, nije se teko


c
c
c
uveriti da naredna verzija algoritma partition ispravno razdvaja dati
podniz oko njegovog poslednjeg elementa izabranog za pivota, jer ovi uslovi
zapravo predstavljaju invarijantu for petlje u algoritmu.
// Ulaz: podniz niza a ogranien indeksima od l do r
c
// Izlaz: preureen podniz i njegov indeks u kome se nalazi pivot
d
algorithm partition(a, l, r)
p = a[r];
i = l - 1;
for j = l to r-1 do
if (a[j] <= p) then
i = i + 1;
swap(a[i],a[j]);
swap(a[i+1],a[r]);
return i+1;

Bilo koju od dve prethodne verzije algoritma partition moemo koristiti da bismo napisali algoritam quick-sort(a,l,r) koji razdvajanjem
elemenata sortira podniz a l , . . ., a r , gde je 1 l r n. Eksplicitne granice
podniza su potrebne kao parametri ovog algoritma zbog njegove rekurzivne
prirode. Naravno, ukoliko elimo da sortiramo ceo niz a duine n, to moemo u programu uraditi pozivom quick-sort(a,1,n).
// Ulaz: podniz niza a ogranien indeksima od l do r
c
// Izlaz: sortiran podniz
algorithm quick-sort(a, l, r)
if (l < r) then
k = partition(a,l,r);
quick-sort(a,l,k-1);
quick-sort(a,k+1,r);
return a;

Analiza algoritma quick-sort. Izvravanje algoritma quick-sort zavisi od toga da li su razdvojeni delovi podnizova uravnoteeni po veli ini,
c
to sa svoje strane zavisi od ranga2 elementa izabranog za pivota. Ako
su podnizovi na svakom nivou stabla rekurzije otprilike jednako podeljeni,
sortiranje razdvajanjem se asimptotski izvrava kao i sortiranje objedinjavanjem za vreme O(n log n). Sa druge strane, ako je razdvajanje podnizova
2 Rang nekog elementa jednak je njegovoj poziciji u sortiranom nizu.

5.2. Analiza rekurzivnih algoritama

127

vrlo neuravnoteeno, vreme za sortiranje razdvajanjem moe degradirati


c
do O n2 . Sre om, u proseku, dobre podele preovladuju u odnosu na

loe podele, pa je ovo brzo sortiranje zaista ekasno i tipi no vreme


c
izvravanja iznosi O(n log n).
Poto vreme izvravanja sortiranja razdvajanjem nije uvek isto, razmotrimo najbolji i najgori mogu i slu aj. Pre svega, primetimo da se obe
c
c
verzije algoritma partition izvravaju za vreme koje je proporcionalno
duini ulaznog podniza. Naime, u oba slu aja, svaki element ulaznog podc
niza se ispituje samo jednom. U prvom slu aju kada se za pivota bira prvi
c
element podniza, elementi podniza se ispituju od oba kraja, ali se pri tome

staje cim se odgovaraju i indeksi preklope. U drugom slu aju kada se za


c
c
pivota bira poslednji element podniza, elementi podniza se prosto ispituju
redom od levog kraja do desnog kraja. Dakle, vreme izvravanja algoritma
partition(a,l,r) je c(r l + 1). Speci no, po etno razdvajanje (l = 1,
c
c
r = n) celog ulaznog niza se izvrava za vreme cn.
Najgori slu aj za performanse sortiranja razdvajanjem jeste kada u
c
svim slu ajevima razdvajanja podniza izabrani pivot bude najve i element
c
c
podniza. To se deava u prvoj verziji algoritma partition kada je ulazni
niz po etno sortiran u opadaju em redosledu, a u drugoj verziji kada je
c
c
ulazni niz ve sortiran u rastu em redosledu. Tada u svakom rekurzivc
c
nom pozivu, podniz delimo na dva dela od kojih se jedan sastoji od jednog (pivot) elementa, a drugi od svih ostalih elemenata podniza. Prema
tome, rekurentna jedna ina koja opisuje vreme izvravanja T(n) algoritma
c
quick-sort u najgorem slu aju je:
c
T(n) = T(n 1) + T(1) + cn
= T(n 1) + cn ,

jer je vreme izvravanja algoritma T(1) za jedan element o igledno neka


c
konstanta. Lako je dobiti, na primer, postupkom viestruke zamene da je
reenje ove rekurentne jedna ine O(n2 ). Prema tome, vreme izvravanja
c
za sortiranje razdvajanjem u najgorem slu aju nije nita bolje od vremena
c
izvravanja jednostavnijih postupaka sortiranja.
U najboljem slu aju razdvajanja podnizova, kada se na svakom rec
kurzivnom nivou algoritma ulazni podniz deli na otprilike dve jednake
polovine, rekurentna jedna ina za vreme izvravanja postaje:
c
T(n) = 2T(n/2) + cn .

128

Rekurzivni algoritmi

Ova jedna ina je identi na rekurentnoj jedna ini za vreme izvravanja kod
c
c
c
sortiranja objedinjavanjem, pa vreme izvravanja za sortiranje razdvajanjem u najboljem slu aju iznosi O(n log n).
c
Prose an slu aj vremena izvravanja sortiranja razdvajanjem je mnogo
c
c
blii najboljem slu aju nego najgorem slu aju. Poto formalni dokaz ove
c
c

cinjenice zahteva sloeniji matemati ki aparat, ovde cemo samo intuitivno


c
objasniti zato je sortiranje razdvajanjem ekasan metod u praksi. Pretpostavimo da algoritam partition uvek deli ulazni podniz u odnosu, recimo,
90-10 procenata. To izgleda kao vrlo neuravnoteeno deljenje i za vreme
c
izvravanja algoritma quick-sort dobijamo rekurentnu jedna inu:
T(n) = T(9n/10) + T(n/10) + cn .
Ali reenje ove rekurentne jedna ine je i dalje T(n) = O(n log n), to se moe
c
proveriti indukcijom, mada sa ve om konstantom skrivenom u asimptotc

skoj notaciji. Dakle, cak i kada se u postupku sortiranja razdvajanjem


dobijaju naizgled vrlo nejednake veli ine podnizova, asimptotsko vreme
c
izvravanja je i dalje O(n log n) isto ono koje se dobija kada su podele
ta no po sredini. U stvari, sve podele izvrene u konstantnoj proporciji na
c

svakom nivou rekurzije, cak i za 99-1 procenata, daju vreme izvravanja


O(n log n).

Iako nije mnogo verovatno da cemo za slu ajni ulazni niz uvek dobiti
c

proporcionalne podele, o ekujemo da ce neke podele biti dobro uravnotec

ene i da ce neke biti prili no neuravnoteene. Drugim re ima, dobre i loe


c
c

podele ce se smenjivati na svim nivoima rekurzije. Medutim, o ekujemo


c

da dobijemo mnogo vie dobrih podela nego loih, poto naa neformalna

analiza nagovetava da su naizgled loe podele zapravo dobre. Dakle, cak i


kada se neka vrlo loa podela dobije pre dobrih podela, odgovaraju i podniz
c

ce se brzo sortirati. Naime, dodatni posao zbog loe podele se ne odraava


na dodatne rekurzivne pozive, nego je dominiran dodatnim razdvajanjem
koje se apsorbuje u ukupno vreme izvravanja.

5.3 Rekurentne jednacine


U primerima u prethodnom odeljku uverili smo se da se u analizi rekurzivnih algoritama obi no sre emo sa rekurentnim jedna inama koje na
c
c
c
neki na in treba reiti. Drugim re ima, ukoliko funkcija T(n) kod tih algoc
c
ritama ozna ava maksimalno vreme izvravanja za ulaz veli ine n, onda
c
c
se T(n) izraava jedna inom u kojoj u estvuju vrednosti te iste funkcije za
c
c


5.3. Rekurentne jednacine

129

veli ine ulaza manje od n. Zadatak je na i formulu (ili bar gornju granicu)
c
c
za T(n) izraenu samo pomo u veli ine ulaza n.
c
c
Kroz primere u prethodnom odeljku smo upoznali i metod viestruke
zamene za reavanje nekih rekurentnih jedna ina. Pokazali smo da se
c
metod viestruke zamene sastoji od zamenjivanja vrednosti T(m) za m < n
optim oblikom rekurentnog dela jedna ine za T(n). Pri tome nakon nec
koliko zamena o ekujemo da moemo odrediti opti obrazac za T(n) i da
c
moemo odrediti kada taj opti oblik prelazi u bazni slu aj.
c
Sa matemati ke ta ke gledita, postoji trenutak kada kod metoda vic
c
estruke zamene dolazi do malo opasnog logi kog skoka. To se dogada u
c

trenutku kada o optem obliku reenja zaklju ujemo na osnovu obrasca


c

koji dobijamo nakon niza zamena. Cesto je taj logi ki skok sasvim opravc
dan, ali ponekad to nije ba o igledno i moe biti podlono grekama. Da
c
bismo bili potpuno sigurni u takvim slu ajevima, opti oblik reenja treba
c
dalje verikovati, obi no indukcijom. Kombinovan sa ovom verikacijom,
c
metod viestruke zamene je sasvim korektan na in za dobijanje reenja
c
rekurentnih jedna ina.
c
Poto se u optem slu aju analize rekurzivnih algoritama mogu dobiti
c

rekurentne jedna ine koje su tee za reavanje, u ovom odeljku cemo upoc
znati jo neke matemati ke metode za reavanje rekurentnih jedna ina
c
c
rekurzivnih algoritama.

Metod stabla rekurzije


Metod viestruke zamene se sastoji od zamenjivanja rekurentnog dela

jedna ine za T(n), a zatim od cesto sloenog sredivanja dobijenog izraza u


c

oblik iz koga moemo prepoznati opti obrazac. Medutim, kod teih pri
mera se lako moemo izgubiti u svom tom simboli kom manipulisanju, pa
c
se zato upotrebom stabla rekurzije obezbeduje slikovitiji na in za pra enje
c
c

ta se dogada na svakom nivou rekurzije. Kod primene metoda stabla

rekurzije, rekurentna jedna ina se predstavlja stablom u kojem nas svaka


c
zamena rekurentnog dela polazne jedna ine dovodi do jednog nivoa dublje
c
u stablu.
Glavnu ideju metoda stabla rekurzije za reavanje rekurentnih jedna
cina objasni emo na primeru rekurentne jedna ine (5.2) za vreme izvrac
c
vanja algoritma merge-sort na strani 121 (koju smo dalje pojednostavili

130

Rekurzivni algoritmi

uzimaju i da je konstanta c = 1):


c
T(n) =

ako je n = 1

1,

(5.3)

2T(n/2) + n, ako je n > 1 .

Podsetimo se algoritamske interpretacije ove jedna ine: da bismo niz duc


ine n sortirali objedinjavanjem, moramo sortirati objedinjavanjem dva
podniza duine n/2 i uraditi n jedinica dodatnog posla za njihovo nerekurzivno objedinjavanje. Za rekurentnu jedna inu sortiranja objedinjavanjem
c
crtamo stablo rekurzije sa korenom koji predstavlja polazni problem i koren ozna avamo vremenom za reavanje tog problema u nerekurzivnom
c

delu, koje iznosi n. Cinjenicu da polazni problem delimo u dva potpro


blema predstavljamo crtanjem dvoje dece korenog cvora. Tu decu takode

ozna avamo vremenom za njihovo reevanje u nerekurzivnom delu, koje


c

sada iznosi n/2. Na slede em nivou imamo cetiri cvora, poto se svaki od
c
dva potproblema na prethodnom nivou dalje deli u dva potproblema. Svaki

od ova cetiri cvora ima oznaku n/4, jer je to vreme potrebno za reavanje svakog od ovih potproblema u nerekurzivnom delu. Ovaj postupak se

nastavlja sve do poslednjeg nivoa na dnu stabla, koje sadri cvorove za


probleme veli ine 1 i koji su ozna eni vremenom za njihovo reavanje iz
c
c
baznog slu aja. Na slici 5.8 je prikazano rezultuju e stablo rekurzije za
c
c
rekurentnu jedna inu (5.3) koja opisuje funkciju vremena izvravanja za
c
sortiranje objedinjavanjem.
Veli ina
c
problema

Stablo rekurzije

n/4

n/4

2 (n/2) = n

1n = n

n/2

n/2

Jedinice
rada

n/2
n/4

n/4

4 (n/4) = n

n/4

n/2 i
1

i
i

2 (n/2 ) = n

log n + 1
nivoa

n1 = n

S LIKA 5.8: Stablo rekurzije za rekurentnu jedna inu (5.3).


c
Primetimo da smo u krajnje desnoj koloni na slici 5.8 naveli ukupno
vreme za svaki nivo rekurzije. Ako nivo na samom vrhu ozna imo da bude
c
c
nivo 0, onda na nivou i imamo 2 i potproblema veli ine n/2 i i dodatno vreme


5.3. Rekurentne jednacine

131

za reavanje svakog od njih u nerekurzivnom delu je n/2 i . To zna i da je


c
i
i
za i-ti nivo potrebno ukupno vreme jednako 2 (n/2 ) = n. Poto stablo ima
log n + 1 nivoa (0, 1, 2, . . ., log n), a svaki nivo doprinosi istu vrednost od n
jedinica dodatnog vremena, ukupno vreme je T(n) = n(log n +1) = n log n + n.
Ovo reenje rekurentne jedna ine sortiranja objedinjavanjem je ta no ono
c
c
koje smo dobili metodom viestruke zamene.
Vano zapaanje je da ta no znamo koliko ima nivoa u stablu rekurc
zije, kao i to koliko vremena nam je potrebno za svaki nivo. Poto ovo
znamo, ukupno vreme moemo dobiti ukoliko saberemo sva vremena po
svim nivoima. To ukupno vreme je reenje rekurentne jedna ine (5.3),
c
poto stablo rekurzije samo slikovito modelira postupak odvijanja rekurzivnog izvravanja algoritma. Prema tome, reenje rekurentne jedna ine
c
(5.3) je T(n) = n log n + n.
Primetimo da je reavanje rekurentne jedna ine metodom stabla rekurc
zije ekvivalentno primeni metoda viestruke zamene, iako vizuelno prua
bolju sliku o tome kako se dolazi do reenja. Da bismo ovo bolje utvrdili,
posmatrajmo jo jednu rekurentnu jedna inu (gde je c > 0 neka konstanta):
c
T(n) =

c,

ako je n = 1

3T(n/2) + n2 , ako je n > 1 .

(5.4)

Ukoliko zanemarimo bazni slu aj, rekurentnu jedna inu (5.4) moemo inc
c
terpretirati na slede i na in: da bismo reili problem veli ine n, reavamo
c
c
c
3 potproblema veli ine n/2 i radimo n2 jedinica dodatnog posla. Kada
c

crtamo stablo rekurzije, svaki cvor opet ozna avamo iznosom dodatnog (nec
rekurzivnog) vremena za odgovaraju u veli inu potproblema. Na najviem
c
c
nivou 0, za dodatni posao treba n2 jedinica vremena. Na nivou 1 imamo

tri cvora po (n/2)2 jedinica dodatnog vremena, to za taj nivo daje ukupno

vreme 3(n/2)2 = (3/4)n2 . Na nivou 2 imamo devet cvorova po (n/4)2 jedinica


dodatnog vremena, to za taj nivo daje ukupno vreme 9(n/4)2 = (3/4)2 n2 .
2

Ovo je lako nastaviti za nivo i, gde imamo 3 i cvorova po n/2 i jedinica


2
dodatnog vremena, to za taj nivo daje ukupno vreme 3 i n/2 i = (3/4) i n2 .
Nivo na dnu je druga iji od ostalih nivoa. U ostalim nivoima, vreme po
c

cvoru dobijamo na osnovu rekurzivnog dela T(n) = 3T(n/2) + n2 rekurentne

jedna ine. U najniem nivou, vreme po cvoru dobijamo na osnovu baznog


c
c
slu aja T(1) = c rekurentne jedna ine. Na slici 5.9 je prikazano stablo
c
rekurzije koje se dobija za rekurentnu jedna inu (5.4).
c
Naravno, da bismo dobili ukupno vreme za celo stablo rekurzije, tj.
reenje jedna ine (5.4), sabiramo vremena po svim nivoima stabla. Poto je
c

132

Rekurzivni algoritmi

Veli ina
c
problema

Stablo rekurzije

Jedinice
rada

1 n2 = n2

n/2

(n/2)2

(n/2)2

n/4

(n/2)2

(n/4)2 (n/4)2 (n/4)2

3(n/2)2 = (3/4)n2
9(n/4)2 = (3/4)2 n2
3 i (n/2 i )2 = (3/4) i n2

n/2 i
1

3log n c

S LIKA 5.9: Stablo rekurzije za rekurentnu jedna inu (5.4).


c

ukupan broj nivoa jednak log n + 1 (to su nivoi 0, 1, 2, . . ., log n) i broj cvorova
na najniem nivou je jednak 3log n , zbir vremena po svim nivoima stabla je:
T(n) = n2 + (3/4)n2 + (3/4)2 n2 + + (3/4)log n1 n2 + c3log n
= n2

log n1

i =0

(3/4) i + c3log n

(3/4)log n 1
+ c3log n
3/4 1
1 nlog 3 /n2
= n2
+ cnlog3
1/4
= 4n2 4nlog 3 + cnlog3
= n2

= 4n2 + (c 4)nlog3 .

U ovom izvodenju smo koristili jednakost alogb n = nlogb a , kao i formulu za

zbir geometrijskog reda:


m
i =0

xi =

x m +1 1
,
x1

(x = 1) .

Prema tome, ta no reenje rekurentne jedna ine (5.4) je T(n) = 4n2 +


c
c
(c 4)nlog3 . Ako nas interesuje samo asimptotska vrednost tog reenja,
kako je log2 3 1.58 to je T(n) = O n2 .

Metod nagadanja

Mada zvu i nesistemati no, metod nagadanja je sasvim legalan na in


c
c
c

za reavanje rekurentnih jedna ina. Osnovna ideja tog pristupa sastoji se


c


5.3. Rekurentne jednacine

133

u tome da se najpre promiljeno pretpostavi reenje date rekurentne jedna ine, a zatim da se ta pretpostavka potvrdi, obi no indukcijom. Naravno,
c
c
primenom ovog metoda moda moramo da probamo nekoliko reenja dok
ne dobijemo dobru gornju granicu za datu rekurentnu jedna inu. Drugim
c
re ima, ako ne uspevamo da verikujemo aktuelno pretpostavljeno reenje,
c
verovatno treba probati neku funkciju koja bre raste. Ali i ako uspemo u
tome uz relativno malo truda, verovatno treba probati i neku funkciju koja
sporije raste.
Na primer, posmatrajmo slede u rekurentnu jedna inu (gde su a i b
c
c
neke pozitivne konstante):
T(n) =

a,

ako je n = 1

2T(n/2) + bn log n, ako je n > 1 .

(5.5)

Ovo izgleda vrlo sli no rekurentnoj jedna ini za sortiranje objedinjavac


c
njem, pa naa prva pretpostavka moe biti da je reenje T(n) = O(n log n).
Zatim, u slede em koraku elimo da verikujemo indukcijom da je reenje
c
rekurentne jedna ine (5.5) zaista T(n) cn log n za neku pozitivnu konc
stantu c i dovoljno veliko n.
Sigurno moemo izabrati dovoljno velike konstante c i n 0 tako da nae
pretpostavljeno reenje zadovoljava bazni slu aj n = n 0. Naime, ako uzc
memo c = a + b i n 0 = 2, tada je:
T(2) = 2T(1) + b 2 log 2 = 2a + 2b = 2(a + b) = 2c = c 2 log 2 .
Za indukcijski korak kada je n > n 0, ako po indukcijskoj pretpostavci uzmemo da je nae prvo reenje ta no za vrednosti argumenta manjih od n,
c
tada za argument jednak n moemo pisati:
T(n) = 2T(n/2) + bn log n
n
n
2 c log
+ bn log n
2
2
= cn(log n log 2) + bn log n
= cn log n cn + bn log n .

Prema tome, da bismo dokazali indukcijski korak, moramo pokazati da


vai nejednakost:
cn log n cn + bn log n cn log n ,
odnosno bn log n cn, ili ekvivalentno log n c/b. Ali poslednja nejedc
nakost nikako ne moe biti ta na za svako n 2. To zna i da nae prvo
c
naslu eno reenje nije dobro.
c

134

Rekurzivni algoritmi

Zato kao drugo reenje za T(n) moramo probati neku funkciju koja bre
c
raste, na primer, T(n) = O n2 . U tom slu aju, da bismo pokazali T(n)
cn2 za neku pozitivnu konstantu c i dovoljno veliko n, moemo uzeti c =
2(a + b) i n 0 = 1 i lako videti da bazni slu aj vai. Za indukcijski korak kada
c
je n > n 0 , ako po indukcijskoj pretpostavci uzmemo da je nae drugo reenje
ta no za vrednosti argumenta manjih od n, tada za argument jednak n
c
imamo:
T(n) = 2T(n/2) + bn log n
n2
+ bn log n
4
n2 c 2
c
+ n
2 2
= cn2 .
2 c

Dakle u ovom slu aju indukcija prolazi. Medutim, poto izgleda da je ovo
c

reenje lako dobiti, proba emo jo jednu (tj. pravu) funkciju koja ne raste
c
tako brzo: T(n) = O n log2 n . Sada, da bismo pokazali T(n) cn log2 n za
neku pozitivnu konstantu c i dovoljno veliko n, moemo uzeti c = a + b i
c
n 0 = 2 i opet lako videti da bazni slu aj vai. Za indukcijski korak kada je
n > n 0 imamo:
T(n) = 2T(n/2) + bn log n
n
n
2 c log2
+ bn log n
2
2
= cn(log2 n 2 log n + 1) + bn log n
cn log2 n 2cn log n + cn + cn log n
= cn log2 n cn log n + cn
= cn log2 n cn(log n 1)
cn log2 n .

Ovo dokazuje da je T(n) zaista O n log2 n .

Opti metod
Prethodni na ini za reavanje rekurentnih jedna ina zahtevaju odrec
c
deno matemati ko predznanje (recimo, primenu indukcije) da bi se mogli
c

uspeno primeniti. Za neke citaoce je moda laki slede i metod o kome


c
govorimo, jer taj metod zahteva samo prepoznavanje tri karakteristi na
c


5.3. Rekurentne jednacine

135

slu aja i neposredno daje reenje u svakom od njih. Ovaj opti metod sadri
c
formulu na osnovu koje se moe odrediti asimptotsko reenje velike klase
rekurentnih jedna ina u obliku:
c
T(n) = aT(n/b) + f (n) ,
gde su a 1 i b > 1 konstante, a f (n) je asimptotski pozitivna funkcija.
Ovaj oblik rekurentne jedna ine opisuje vreme izvravanja rekurzivnog
c
algoritma u kome se problem veli ine n deli u a nezavisnih potproblema
c
veli ine najvie n/b svaki, zatim reava svaki od ovih potproblema rec
kurzivno i, na kraju, kombinuju reenja ovih potproblema u reenje celog
problema. Ukupno vreme za deljenje polaznog problema u potprobleme i
za kombinovanje njihovih reenja je izraeno funkcijom f (n). Prema tome,
ovo je zaista opti oblik za rekurentne jedna ine rekurzivnih algoritama.
c
Opti metod zahteva prepoznavanje tri slu aja u jednoj teoremi, ali se
c

zato reenje mnogih rekurentnih jedna ina dobija prili no lako i cesto se
c
c
svodi samo na ispisivanje odgovora. Odgovaraju i slu aj na osnovu koga
c
c
se dobija reenje prepoznaje se poredenjem funkcije f (n) sa specijalnom

c
funkcijom nlogb a . Pomenutu teoremu medutim ne emo navoditi u njenoj

punoj optosti, jer je prili no tehni ke prirode i ima vie teorijski zna aj.
c
c
c
c
U praksi se ce e koristi njena pojednostavljena verzija u kojoj je f (n) u
sutini polinomska funkcija po n.
T EOREMA Neka je nenegativna funkcija T(n) denisana rekurentnom jedna inom
c
d,
n n0
T(n) =
k
aT(n/b) + cn , n > n 0
gde je n 0 1 celobrojna konstanta, a a 1, b > 1, c > 0, d > 0 i k 0 su
realne konstante.
Slucaj 1: Ako je a = b k , tada je T(n) = n k log n .

Slucaj 2: Ako je a < b k , tada je T(n) = n k .

Slucaj 3: Ako je a > b k , tada je T(n) = nlogb a .

Dokaz: Radi jednostavnosti pretpostavljamo da je n stepen broja b i n 0 =


1, kako ne bismo zamaglili osnovnu sliku nepotrebnim detaljima. Ipak
naglaavamo da time ne gubimo na optosti i ideja dokaza se prenosi za
bilo koje n. Ako radi lakeg pisanja uvedemo oznaku f (n) = cn k , primenom
viestruke zamene na datu rekurentnu jedna inu dobijamo:
c
T(n) = aT(n/b) + f (n)

136

Rekurzivni algoritmi
= a aT n/b2 + f (n/b) + f (n)
= a2 T n/b2 + a f (n/b) + f (n)
= a3 T n/b3 + a2 f n/b2 + a f (n/b) + f (n)

.
.
.
= alogb n T(1) +
= nlogb a d +

logb n1

a i f n/b i

i =0

logb n1

a i f n/b i ,

i =0

gde smo u poslednjoj jednakosti iskoristili formulu alogb n = nlogb a .3 Ako


sada vratimo f (n) = cn k , dobijamo:
T(n) = dnlogb a +

logb n1

i =0

= dnlogb a + cn k

a i c n/b i

logb n1

i =0

bk

Poto sumiranje na desnoj strani predstavlja geometrijski zbir, tvrdenje

teoreme cemo pokazati posmatranjem slu ajeva za vrednost koli nika a/b k .
c
c
Prvo, ako je a = b k , tj. k = log b a, onda je
T(n) = dn k + cn k logb n = n k log n .
Drugo, ako je a = b k , onda je
T(n) = dn

logb a

+ cn

a/b k

logb n

a/b k 1

Dakle, ako je a < b k , odnosno k > logb a i 0 < a/b k < 1, onda je
T(n) = dnlogb a + cn k (1) = n k ,
m
i
i =0 x

poto je drugi izraz dominantan i

= (1) za 0 < x < 1.

U tre em slu aju, ako je a > b odnosno a/b k > 1, poto za x > 1 imamo
c
c
m
i
m
i=0 x = (x ), dobijamo:
T(n) = dnlogb a + cn k a/b k

logb n

3 To je razlog zato se koristi specijalna funkcija nlogb a za prepoznavanje reenja u


optem slu aju.
c


5.3. Rekurentne jednacine

137

= dnlogb a + cn k
= n

logb a

nlogb a
nk

cime je dokaz zavren.


Da bismo reili neku rekurentnu jedna inu optim metodom, jednoc
stavno odredujemo (ako moemo) slu aj prethodne teoreme koji je u pitanju
c

i odmah dobijamo odgovor. Na primer, razmotrimo rekurentnu jedna inu:


c
T(n) = 4T(n/2) + n .
Poto a = 4, b = 2 i k = 1 implicira a > b k , na osnovu prvog slu aja pretc
log2 4
= n2 .
hodne teoreme odmah moemo zaklju iti da je T(n) = n
c
Kao drugi primer, razmotrimo rekurentnu jedna inu:
c
T(n) = 2T

n + log n = 2T n1/2 + log n .

Naalost, ova jedna ina nije u onom obliku u kojem moemo primeniti
c
opti metod. Medutim, tu jedna inu moemo transformisati u eljeni oblik
c

smenom m = log n. Tada je n = 2m , pa moemo pisati:


T 2m = 2T 2m/2 + m .
c
Ukoliko ozna imo S(m) = T (2m ) dobijamo rekurentnu jedna inu za funkc
ciju S(m):
S(m) = 2S (m/2) + m .
Sada je oblik ove jedna ine onaj koji omogu ava primenu opteg metoda,
c
c
pa lako dobijamo reenje S(m) = (m log m). Ponovnom upotrebom smene
da bismo se vratili na T(n) dobijamo reenje T(n) = (log n loglog n).

Primer: mnoenje velikih celih brojeva


Prakti niju primenu opteg metoda za reavanje rekurentnih jednac

cina cemo pokazati na problemu mnoenja dva velika n-bitna cela broja.
Pretpostavimo da je broj bitova n vrlo veliki (recimo, n > 100), tako da se
celi brojevi ne mogu direktno pomnoiti u aritmeti koj jedinici standardnih
c
ra unara. Drugim re ima, ne moemo pretpostaviti da uobi ajene aritmec
c
c
ti ke operacije nad velikim celim brojevima predstavljaju jedini ne operac
c
cije koje se izvravaju za konstantno vreme. O igledno, to vreme zavisi
c
od broja bitova u reprezentaciji velikih celih brojeva u binarnom sistemu.

138

Rekurzivni algoritmi

Mnoenje velikih celih brojeva ima primenu, na primer, u kriptograji, jer


se veliki celi brojevi koriste u raznim postupcima ifrovanja.
Ako su data dva velika cela broja X i Y predstavljena u binarnom
sistemu sa po n bitova, njihov zbir X + Y i razliku X Y moemo lako
izra unati koriste i uobi ajene postupke za ru no sabiranje i oduzimanje.
c
c
c
c
Jasno je da vreme izvravanja ovih postupaka iznosi O(n) ukoliko sabiranja i oduzimanja pojedina nih cifara ra unamo kao jedini ne operacije.
c
c
c
Medutim, ako se podsetimo da se uobi ajeni postupak za mnoenje brojeva
c

X i Y sastoji od izra unavanja n delimi nih proizvoda duine n, nije se


c
c
teko uveriti da je njegovo vreme izvravanja O(n2 ) ukoliko mnoenja i
sabiranja pojedina nih cifara ra unamo kao jedini ne operacije. Ali, kao
c
c
c

to cemo pokazati, jednim rekurzivnim algoritmom se moe dobiti bri


na in za mnoenje dva n-bitna broja.
c
Radi jednostavnosti, pretpostavimo da je n stepen broja 2. Ako to
nije slu aj, brojevima X i Y moemo dodati nevae e nule sa leve strane.
c
c
Da bismo primenili rekurzivni metod za mnoenje brojeva X i Y , n-bitne
reprezentacije oba ta broja delimo u dve polovine po n/2 bitova. Jedna
polovina predstavlja cifre ve e vanosti, a druga predstavlja cifre manje
c
vanosti. Ako polovine ve e vanosti brojeva X i Y ozna imo sa A i C, tim
c
c
redom, i sli no polovine manje vanosti sa B i D, moemo pisati:
c
X = A2n/2 + B

i Y = C2n/2 + D .

Ovo polovljenje brojeva je ilustrovano na slici 5.10 za X = 6385242189

i Y = 1900132000. Radi bolje citljivosti, na toj slici su ovi desetocifreni


brojevi prikazani u decimalnom brojnom sistemu, a ne u binarnom.
A

Y=

63852

42189

X=

19001

32000

6385242189 = 63852 105 + 42189

1900132000 = 19001 105 + 32000

S LIKA 5.10: Polovljenje velikih brojeva.


Proizvod brojeva X i Y se dakle moe napisati u obliku
X Y = A2n/2 + B C2n/2 + D ,
ili
X Y = AC 2n + (AD + BC) 2n/2 + BD .

(5.6)


5.3. Rekurentne jednacine

139

Ova formula nagovetava jednostavan rekurzivni algoritam za izra unavac


nje proizvoda A B : podeliti n-bitne brojeve X i Y na pola, zatim rekurzivno
izra unati proizvode u kojima u estvuju te polovine u (5.6) (naime AC, AD,
c
c
BC i BD) i, na kraju, dobijene meduproizvode pomnoiti i sabrati prema

formuli (5.6). Rekurzivni postupak se zavrava kada se dode do mnoenja

dva broja od po jednog bita, to je trivijalno.


Primetimo da je mnoenje binarnog broja stepenom broja 2, recimo 2m ,
vrlo jednostavno to se moe posti i prostim pomeranjem broja za m pozic
cija ulevo (ili dodavanjem m nula na kraju broja). To zna i da se mnoenje
c
n-bitnog celog broja nekim stepenom 2m moe obaviti za vreme O(n + m)
ukoliko pomeranje pojedina nih cifara smatramo jedini nim operacijama.
c
c
c
Prema tome, ako proizvod X Y rekurzivno ra unamo prema formuli

(5.6), ukupno moramo obaviti cetiri mnoenja n/2-bitnih celih brojeva (proizvodi AC, AD, BC i BD u formuli), tri sabiranja celih brojeva od najvie
2n bitova (to odgovara znakovima + u formuli) i dva pomeranja brojeva
od otprilike n bitova (mnoenje sa 2n i 2n/2 u formuli). Poto vreme za
svako od ovih sabiranja i pomeranja brojeva iznosi O(n), vreme izvravanja rekurzivnog algoritma za mnoenje T(n) moemo opisati rekurentnom
jedna inom:
c
c,
n=1
T(n) =
4T(n/2) + cn, n > 1 ,
za neku konstantu c.
Da bismo reili ovu rekurentnu jedna inu, moemo primeniti pojednoc
stavljenu optu teoremu za a = 4, b = 2 i k = 1. Poto nam to daje prvi slu aj
c
log2 4
2
= n . Naalost, ovo nije
teoreme, odmah dobijamo da je T(n) = n
nita bolje od uobi ajenog algoritma za mnoenje.
c
Na osnovu opteg metoda ipak moemo ste i uvid u to kako da ubrzamo
c
rekurzivni algoritam. Ako bismo nekako uspeli da smanjimo broj rekurzivnih poziva a, tada bismo dobili sporiju specijalnu funkciju nlogb a koja
u estvuje u reenju rekurentne jedna ine, odnosno vremenu izvravanja.
c
c
Moda zvu i iznenaduju e ako kaemo da to zaista moemo posti i, ali
c
c
c

posmatrajmo slede i proizvod dva cela broja od n/2 cifara:


c
(A B) (D C) = AD BD AC + BC .

(5.7)

Mora se priznati da zaista deluje cudno zato se posmatra ba ovaj proizvod, ali uporeduju i formulu (5.6) vidimo da proizvod (5.7) u razvijenoj
c

formi sadri zbir dva meduproizvoda koji treba da izra unamo (AD + BC),
c

kao i dva meduproizvoda (BD i AC) koje ionako ra unamo rekurzivno.


c

140

Rekurzivni algoritmi

Prema tome, proizvod dva n-bitna cela broja X i Y moemo napisati u


obliku:
X Y = AC 2n + (A B) (D C) + BD + AC 2n/2 + BD .

(5.8)

Iz ove formule na desnoj strani vidimo da je za izra unavanje X Y potrebno


c
samo tri mnoenja n/2-bitnih celih brojeva (AC, (A B) (D C) i BD), est
sabiranja ili oduzimanja i dva pomeranja brojeva. Poto vreme za sve ove
operacije osim mnoenja iznosi O(n), vreme izvravanja T(n) rekurzivnog
algoritma za mnoenje dva n-bitna cela broja prema formuli (5.8) dato je
rekurentnom jedna inom:
c
T(n) =

c,

n=1

3T(n/2) + cn,

n > 1.

Reenje ove jedna ine na osnovu pojednostavljene opte teoreme je


c
T(n) = O nlog2 3 = O n1.585 ,
to je bolje od O n2 .
Pisanje aktuelnog rekurzivnog algoritma na pseudo jeziku za mnoenje

dva n-bitna cela broja po formuli (5.8) ostavljamo citaocima za laku vebu.

Zadaci
1. Jedna igra sa etonima se sastoji od ukupno n etona podeljenih u nekoliko grupa. Pretpostavlja se da je broj etona n neki stepen broja 2 i
da je broj grupa u koje su etoni podeljeni proizvoljan. Jedan potez ove
igre se sastoji od toga da se najpre biraju dve grupe etona A i B i zatim
ako grupa A ima a etona i grupa B ima b etona i ako je, recimo, a b,
premeta se b etona iz grupe A u grupu B. Cilj igre je da se odredenim

nizom ovakvih poteza svi etoni premeste u samo jednu grupu na kraju.
Navedite algoritam kojim se reava problem ove igre i odredite njegovo
vreme izvravanja (tj. broj poteza) izraeno u funkciji broja etona n.
2. Napiite algoritam partition za sortiranje razdvajanjem kojim se za

pivota bira srednji element podnizova. Obrazloite cinjenicu da ovakav


izbor pivot elementa ne uti e na smanjenje vremena izvravanja algoc
ritma za sortiranje razdvajanjem.


5.3. Rekurentne jednacine

141

3. Napiite rekurzivni algoritam kojim se odreduje najve i i drugi najve i


c
c

element niza a od n brojeva. Koliko se poredenja parova elemenata niza

a obavlja u tom algoritmu?


4. Problem poznate li nosti. Pretpostavimo da se grupa od n 1 osoba
c
nalazi u jednoj sobi. Poznata li nost u toj grupi je ona osoba koja ne
c
poznaje nijednu drugu osobu u grupi (osim naravno sebe), a sve druge
osobe poznaju tu osobu. Ako su poznanstva osoba predstavljena na
odgovaraju i na in, problem poznate li nosti se sastoji u nalaenju poc
c
c
znate li nosti ako takva osoba postoji, ili se otkriva da takva osoba ne
c
c
postoji. Ako sa x1 , x2 , . . ., xn ozna imo n osoba i njihova poznanstva
predstavimo n n matricom a tako da je
a i, j =

1, ako x i poznaje x j
0, ako x i ne poznaje x j

za i, j = 1, 2, . . ., n, napiite rekurzivni algoritam koji kao rezultat daje


indeks poznate li nosti medu ovih n osoba. Ako ne postoji poznata
c

li nost, rezultat algoritma treba da bude 0. Koliko je vreme izvravanja


c
tog algoritma? (Savet: Primetite da ako x poznaje y, tada x nije poznata
li nost, a u suprotnom slu aju, y nije poznata li nost.)
c
c
c
5. Najpre pokaite da Fibona ijevi brojevi f 1 , f 2 , f 3 , . . . zadovoljavaju slec
de e jedna ine za svako k 1:
c
c
f 2k1 = ( f k )2 + ( f k1 )2
f 2k = ( f k )2 + 2 f k f k1 ,
a zatim napiite rekurzivni algoritam kojim se izra unava n-ti Fibonac

cijev broj primenom prethodnih jedna ina. Koliko je vreme izvravanja


c
tog algoritma?
6. Koriste i matricu
c
M=

0 1
1 1

i njen n-ti stepen M n , napiite jo jedan rekurzivni algoritam kojim


se izra unava n-ti Fibona ijev broj. Koliko je vreme izvravanja tog
c
c
algoritma?

142

Rekurzivni algoritmi

7. U neuredenom nizu a od n razli itih brojeva, par razli itih elemenata


c
c

a i i a j cini jednu inverziju ako je i < j i a i > a j . Na primer, u nizu


[5, 3, 10, 2, 8, 9, 20] nalazimo 6 inverzija: (5, 3), (5, 2), (3, 2), (10, 2), (10, 8) i
(10, 9).
a) Napiite rekurzivni algoritam kojim se izra unava ukupan broj
c
inverzija u datom nizu a duine n.
b) Navedite i reite rekurentnu jedna inu za vreme izvravanja tog
c
algoritma.
8. Napiite i analizirajte rekurzivni algoritam za problem maksimalne sume podniza koji je opisan na strani 29 u poglavlju 2. (Savet: Podelite
ulazni niz u dve polovine i primetite da se podniz sa maksimalnom
sumom nalazi ili potpuno u prvoj polovini, ili potpuno u drugoj polovini,
ili mu je po etak u prvoj i zavretak u drugoj polovini. U poslednjem
c
slu aju, nadite ga od srednjeg elementa idu i u oba smera.)
c
c

9. Ako je dat skup od n timova u nekom sportu, kruni turnir je kolekcija


me eva u kojima se svaki tim sastaje sa svakim drugim timom ta no
c
c
jedanput. Napiite i analizirajte rekurzivni algoritam kojim se konstruiu me evi parova timova krunog turnira pretpostavljaju i da je
c
c
n stepen broja 2.
10. Pretpostavljaju i da je n stepen broja 3, reite rekurentnu jedna inu
c
c
T(n) =

n<3

1,
2

4T(n/3) + n ,

n3

koriste i metod
c
a) viestruke zamene;
b) stabla rekurzije;
c) opte teoreme.
11. Posmatrajmo slede i algoritam koji izra unava proizvod dva nenegac
c
tivna cela broja x i y:
// Ulaz: celi brojevi x 0 i y 0
// Izlaz: x y


5.3. Rekurentne jednacine

143

algorithm multiply(x, y)
p = 0;
while (x > 0) do
if (x % 2 != 0) then
p = p + y;
x = x / 2;
y = 2 * y;

// p = x y
// x je neparan

return p;

a) Pokaite da ovaj algoritam ispravno izra unava proizvod brojeva x


c
i y.
b) Koliko je vreme izvravanja ovog algoritma ako su ulazni brojevi
mali, a koliko je ako su ti brojevi veliki?
c) Napiite rekurzivni algoritam koji koristi istu ideju za mnoenje
brojeva x i y.
d) Koliko je vreme izvravanja tog rekurzivnog algoritma ako su ulazni brojevi mali, a koliko je ako su ti brojevi veliki?
12. Napiite algoritam za deljenje velikih celih brojeva. Preciznije, ako
su dati veliki pozitivni celi brojevi x i y, algoritam treba da izra una
c
koli nik q i ostatak r tako da je x = q y + r uz uslov 0 r < b. Koliko je
c
vreme izvravanja tog algoritma?
13. Napiite rekurzivni algoritam multiply(x,y,n) kojim se proizvod brojeva X i Y od n decimalnih cifara izra unava primenom formule (5.6).
c
14. Napiite rekurzivni algoritam multiply(x,y,n) kojim se proizvod brojeva X i Y od n decimalnih cifara izra unava primenom formule (5.8).
c
15. Ako su data dva linearna polinoma ax + b i cx + d, njihov se proizvod
(ax + b)(cx + d) = acx2 + (ad + bc)x + bd
moe izra unati pomo u cetiri mnoenja njihovih koecijenata: ac, ad,
c
c
bc i bd.
a) Koriste i ovo zapaanje, napiite rekurzivni algoritam kojim se
c
izra unava proizvod dva polinoma stepena n:
c
A n (x) = a n x n + a n1 x n1 + + a 1 x + a 0

144

Rekurzivni algoritmi
i

B n (x) = b n x n + b n1 x n1 + + b 1 x + b 0 .

Pretpostavljaju i da su polinomi A n (x) i B n (x) dati nizovima svojih


c
koecijenata, rezultat algoritma treba da bude poseban niz koji
redom sadri koecijente polinoma A n (x) B n (x).
b) Navedite i reite rekurentnu jedna inu za vreme izvravanja algoc
ritma pod a).
c) Pokaite kako se proizvod dva linearna polinoma ax + b i cx + d
moe izra unati sa samo tri mnoenja njihovih koecijenata.
c
d) Na osnovu reenja pod c), navedite drugi rekurzivni algoritam kojim se izra unava proizvod dva polinoma stepena n.
c
e) Navedite i reite rekurentnu jedna inu za vreme izvravanja algoc
ritma pod d).

G LAVA

6
Stabla

Stablo je nelinearna struktura podataka koja predstavlja hijerarhijski odnos izmedu elemenata. Dobro poznati primeri strukture stabla iz

svakodnevnog ivota su izgled sadraja neke knjige na njenom po etku,


c
rodoslovi familija i razne organizacione eme. Stabla se u raznim oblicima

vrlo cesto koriste i u ra unarstvu. Na primer, skoro svi operativni sistemi


c
organizuju sistem datoteka i foldera na na in koji odgovara strukturi stac
bla. Druga primena strukture stabla je za predstavljanje izraza u programima prilikom njihovog prevodenja od strane prevodilaca. Ove sintaksne

kategorije se kod prevodilaca interno predstavljaju u obliku stabla izraza.


Pored ovih neposrednih primena stabala, vana je i njihova indirektna
primena za predstavljanje drugih struktura podataka kao to su disjunktni
skupovi, redovi sa prioritetima i tako dalje.

6.1

Korenska stabla

Najoptije govore i, stabla su samo specijalni slu aj grafova o kojima


c
c
se detaljnije govori u poglavlju 7. Medutim, u ovom poglavlju ne emo punu
c

panju posvetiti ovim optim stablima, nego njihovoj ograni enoj verziji
c
koja se nazivaju binarna stabla. Ipak radi potpunosti, pojmove u vezi
sa stablima navodimo u optijem slu aju korenskih stabala (ili stabala sa
c
korenom). Korensko stablo se sastoji od skupa elemenata koji se nazivaju

cvorovi, kao i skupa uredenih parova razli itih cvorova povezanih linijama

koje se nazivaju grane. Jedan od cvorova korenskog stabla je poseban

146

Stabla

po tome to ozna ava koren stabla. Na crteima se cvorovi stabla obi no


c
c
ozna avaju krui em, a koren stabla se obi no prikazuje na vrhu hijerarc
c
c

hijske strukture koju cini stablo. Na slici 6.1 je prikazan primer korenskog

stabla sa 11 cvorova, gde je cvor v1 koren stabla. Poto u nastavku ovog


poglavlja govorimo isklju ivo o korenskim stablima, radi jednostavnosti
c

cemo ih kra e zvati prosto stablima.


c

v1

v3

v2

v6

v7

v5

v4

v8

v9

v10

v11

S LIKA 6.1: Korensko stablo.

Stablo se neformalno najlake predstavljaju crteom njihovih cvorova i


grana koje ih povezuju, ali je potrebno razjasniti jo neke detalje u vezi sa

stablima. Pre svega, jedna grana stabla je ureden par dva razli ita cvora x i
c

y. U tekstu se ta grana ozna ava sa (x, y), a na crteima linijom koja spaja
c

cvorove x i y. Primetimo da bi pravilnije bilo da na crteima koristimo

strelicu od x do y, jer je vano koji cvor je prvi a koji drugi u uredenom

paru koji predstavlja granu. Ipak se radi lakeg crtanja koristi linija za

granu, a ne strelica, jer se redosled cvorova grane ukazuje time to se prvi

cvor na crteima uvek prikazuje iznad drugog cvora. Tako se na slici 6.1
podrazumeva da je, recimo, (v2 , v7 ) grana stabla, a ne obrnuto.
Terminologija u vezi sa stablima je uglavnom pozajmljena iz njihove
primene u predstavljanju rodoslova neke porodice, gde se granama uspo
stavlja medusobni odnos roditelj-dete izmedu pojedinih clanova porodice.

Tako se u ra unarstvu za granu (x, y) u stablu kae da je prvi cvor x roditelj


c

cvora y, odnosno da je drugi cvor y dete cvora x. Na primer, u stablu na

slici 6.1 je cvor v2 roditelj cvora v7 i v7 je dete cvora v2 .

Cvor u stablu moe imati nula ili vie dece, ali svaki cvor razli it od
c

korena ima ta no jednog roditelja i koren stabla je jedini cvor bez roditelja.
c
Ova osobina je upravo ona koja karakterie stablo i koristi se za formalnu

deniciju (korenskog) stabla: stablo T je skup cvorova i skup grana izmedu

6.1. Korenska stabla

147

njih (tj. uredenih parova cvorova) sa slede im svojstvima:


c

1. Ako je T neprazno stablo, ono ima jedinstven poseban cvor (koren) koji

nema roditeljski cvor.

2. Svaki cvor u u T osim korena ima jedinstven roditeljski cvor v.


Primetimo da na osnovu ove formalne denicije stablo moe biti pra
zno, to zna i da takvo stablo nema nijedan cvor (i nijednu granu). To
c
omogu ava da se stablo denie i rekurzivno na na in kojim se ve a stabla
c
c
c

konstruiu od manjih: stablo T je prazno ili se sastoji od cvora r, koji se

naziva koren stabla T, i (mogu e praznog) skupa stabala T1 , T2 , . . ., T k ciji


c
vora r. Na slici 6.2 je ilustrovana ova rekurzivna denicija
su koreni deca c
stabla.
T

r1

r2
T2

T1

rk

Tk

S LIKA 6.2: Rekurzivna denicija stabla T.


Ostali pojmovi u vezi sa stablima su prili no prirodni, mada mnogoc

brojni. Deca istog cvora (tj. cvorovi sa zajedni kim roditeljem) nazivaju se
c

bra a (sestre). Cvorovi koji imaju bar jedno dete su unutranji, a cvorovi
c

bez dece su spoljanji. Spoljanji cvorovi se cesto nazivaju i listovi. Na

c
primer, u stablu na slici 6.1 cvorovi v2 , v3 , v4 i v5 su bra a, a svi listovi tog
stabla su v3 , v6 , v7 , v8 , v9 i v11 .
Pojam puta u stablu je na neki na in uoptenje pojma grane. Put
c

izmedu dva razli ita cvora x i y je niz cvorova x = v1 , v2 , . . ., vm = y ukoliko


c

postoji grana izmedu svih susednih cvorova (v i , v i+1 ) za 1 i < m. Duina

tog puta je broj grana na putu, odnosno m 1. Za svaki cvor se podrazu


meva da postoji put duine 0 od tog cvora do samog sebe. Na primer, put

u stablu na slici 6.1 od cvora v5 do v11 sastoji se od cvorova v5 , v10 i v11 , a


duina tog puta je dva.

Bitna osobina stabla je da za svaki cvor u stablu postoji jedinstven put

od korena do tog cvora. Da bismo ovo pokazali, lako je najpre videti da uvek

148

Stabla

postoji put od korena do nekog cvora x. Naime, ukoliko uzimamo cvorove od

cvora x prate i u svakom koraku jedinstvenog roditelja pojedinih cvorova,


c

dobijamo niz cvorova koji u obrnutom redosledu formira put od korena do

cvora x. Jedinstvenost tog puta se pokazuje kontradikcijom: ako bi postojao


jo jedan razli it put, onda bi ta dva puta od korena morali da se kod nekog
c

cvora najpre razdvoje i zatim ponovo spoje u bar jednom zajedni kom cvoru
c
y (ina e bi divergirali i jedan od puteva nikad ne bi stigao do x). Ali to bi
c

zna ilo da cvor y ima dva roditelja, to je nemogu e kod stabla.


c
c

Svaki cvor u na jedinstvenom putu od korena do nekog cvora v se

naziva predak cvora v. Obrnuto, cvor v je potomak cvora u ukoliko je

u predak cvora v. Podrazumeva se da je svaki cvor u stablu sam sebi

predak i potomak. Odnos predak-potomak za cvorove stabla se kra e moe


c

denisati rekurzivno: cvor u je predak cvora v ako je u = v ili je u predak

roditelja cvora v. Na primer, u stablu na slici 6.1 cvorovi v1 , v4 i v8 su preci

cvora v8 , a potomci cvora v5 su cvorovi v5 , v9 , v10 i v11 .

Podstablo sa cvorom v kao korenom je stablo koje se sastoji od tog cvora


v i svih njegovih potomaka, zajedno sa nasledenim granama. Na primer,

sva stabla T1 , T2, . . ., T k na slici 6.2 su podstabla stabla T sa korenima,


redom, r 1 , r 2, . . ., r k .

Dubina cvora je duina jedinstvenog puta od korena do tog cvora. Zato

je, rekurzivno, dubina korena jednaka 0, a dubina svakog drugog cvora je


za jedan ve a od dubine njegovog roditelja. Visina cvora se takode moe
c

denisati rekurzivno: visina lista je 0, a visina cvora koji nije list je za


jedan ve a od maksimalne visine njegove dece. Visina stabla je visina
c

njegovog korena. Na primer, visina stabla na slici 6.1 je tri, a visina cvora
v5 je dva i njegova dubina je jedan.

Stablo kao struktura podataka


Sli no kao u slu aju osnovnih struktura podataka (nizova, listi, stec
c
kova, redova), da bismo stabla koristili u programima za organizaciju kolekcije podataka, moramo imati na in za predstavljanje stabala u ra unaru
c
c
i implementirati skup korisnih operacija nad stablima.
U radu sa stablima se moe pojaviti potreba za vrlo raznolikim operacijama. Na primer, pored osnovnih operacija za dodavanje, uklanjanje ili

odredivanje deteta datog cvora, moemo imati i operacije koje kao rezultat

daju roditelja, sasvim levog deteta ili desnog brata datog cvora. Radi lakeg
programiranja korisno bi bilo realizovati i upitne operacije koje odreduju

da li je dato stablo prazno, ili da li je dati cvor koren, interni, eksterni i

6.1. Korenska stabla

149

sli no. Najzad, treba imati na umu i pomo ne operacije koje obuhvataju
c
c

postupke konstruisanja novog stabla, odredivanja broja cvorova (veli ine)


c

stabla, odredivanje visine stabla i tako dalje. Medutim, ukoliko se koristi

odgovaraju a reprezentacija stabla, sve ove operacije se mogu relativno


c
lako implementirati i zato ne emo i i u konkretne detalje njihove prakti ne
c
c
c

realizacije. Zato cemo u ovom odeljku malo detaljnije razmotriti samo


na ine za predstavljanje korenskih stabala.
c
Pre svega, stablo predstavlja kolekciju podataka tako to se pojedina ni
c

podaci u kolekciji nalaze u cvorovima stabla. Na primer, stablo na slici 6.3


c
predstavlja aritmeti ki izraz (a + b) (a c) na prirodan na in: koren tog
c
stabla sadri operator za mnoenje, a njegova deca su koreni dva podstabla koja predstavljaju podizraze a + b i a c.

S LIKA 6.3: Stablo izraza (a + b) (a c).

Sli no kao kod osnovnih struktura podataka, pojedina ni podaci u cvoc


c
rovima stabla se na optem nivou poistove uju sa jednozna nom vredno u
c
c
c
koja se naziva njihov klju i tako radi jednostavnosti zanemaruju dodatni
c

podaci koje cvorovi u stvarnosti moda sadre. Najprirodnija reprezentacija stabla, koja najo iglednije odraava njegovu logi ku strukturu, bila bi
c
c

da se svaki cvor stabla predstavlja objektom koji obuhvata polje klju a, vie
c

polja u kojima se nalaze pokaziva i na svako dete tog cvora i, eventualno,


c

polje za pokaziva na roditelja cvora. Medutim, poto je ovde re o optim


c
c

stablima, odnosno broj dece po cvoru moe biti vrlo razli it i nije unapred
c
ograni en, ovaj pristup nije najbolji jer proizvodi loe iskori enje memoc
c
rijskog prostora. Zato se obi no koriste dva druga na ina za predstavljanje
c
c
optih stabala o kojima govorimo u nastavku.

Predstavljanje stabla listama dece cvorova. Jedan na in za prevac


vora u optem stablu je
zilaenje problema nepoznatog broja dece nekog c

formiranje povezane liste dece svakog cvora. Ovaj pristup je vaan, jer se
moe lako generalizovati za predstavljanje sloenijih struktura kao to su

150

Stabla

grafovi. U desnom delu slike 6.4 prikazano je kako se stablo T u levom


delu te slike moe predstaviti na ovaj na in.
c
t

2
5

6
5

10

7
8
9

10

10

S LIKA 6.4: Predstavljanje stabla listama dece cvorova.

Kao to se vidi sa slike 6.4, u ovoj reprezentaciji stabla imamo jedan niz

pokaziva a t ciji elementi predstavljaju cvorove i zato je njegova veli ina


c
c

jednaka ukupnom broju cvorova u stablu. Pored toga, svaki element niza

t pokazuje na po etak povezane liste cvorova stabla. Pri tome, elementi


c

liste na koju pokazuje element niza t i su cvorovi-deca cvora i tako da


poredak elemenata u listi odgovara poretku dece sleva na desno u stablu.

Na primer, na slici 6.4 element t 5 pokazuje na listu 8 9 poto su cvorovi

8 i 9, time redom, deca cvora 5.


Jedan nedostatak ovog na ina predstavljanja stabla je to to ne moc
emo lako da konstruiemo ve a stabla od manjih. To je posledica toga
c

to svako stablo ima svoj niz pokaziva a za svoje cvorove. Prema tome, da
c

bismo napravili novo stablo, recimo, od datog cvora kao korena i dva data
c
podstabla T1 i T2 , morali bismo da kopiramo T1 i T2 u tre e stablo i da

dodamo listu za novi koren cija su deca koreni za T1 i T2 .

Predstavljanje stabla pomocu sasvim levog deteta i desnog brata

cvorova. Drugo reenje za problem predstavljanja optih stabala je pred


stavljanje sasvim levog deteta i desnog brata svakog cvora stabla. U ovoj

reprezentaciji svaki cvor pored klju a sadri samo jo dva pokaziva a: jec
c
dan pokazuje na njegovog sasvim levog deteta i drugi na njegovog desnog
brata. Naravno, ovi pokaziva i imaju specijalnu vrednost null ukoliko
c

cvor nema dece ili nema desnog brata.


Ovaj na in predstavljanja opteg stabla je ilustrovan u desnom delu na
c
slici 6.5 za stablo koje je prikazano u levom delu. Na toj slici je za svaki

6.2. Binarna stabla

151

cvor stabla strelicom nadole ozna en pokaziva na sasvim levog deteta, a


c
c
strelicom nadesno je ozna en pokaziva na desnog brata.
c
c
A

S LIKA 6.5: Predstavljanje stabla pokaziva ima na sasvim levog deteta i


c

desnog brata cvorova.

Sve operacije nad stablima, osim odredivanja roditelja datog cvora,

mogu se ekasno realizovati ako je stablo predstavljeno pomo u sasvim


c

levog deteta i desnog brata svih cvorova. A ako je potrebno i da operacija


odredivanja roditelja bude ekasna, to se moe lako reiti dodavanjem

jo jednog pokaziva a svakom cvoru koji direktno pokazuje na njegovog


c
roditelja.

6.2 Binarna stabla

Binarno stablo je stablo u kojem nijedan cvor nema vie od dvoje dece.
Ova deca se zovu levo dete i desno dete, poto se na crteima prikazuju levo

i desno od cvora koji je njihov roditelj. Formalno, binarno stablo je stablo u

kojem svaki cvor ili nema decu, ili ima samo levo dete, ili ima samo desno
dete, ili ima i levo i desno dete.
Obratite panju na to da pojam binarnog stabla nije isti kao za obi no
c
stablo koje smo denisali u prethodnom odeljku, jer svako dete u binarnom
stablu mora biti levo dete ili desno dete. Ovo zapaanje je ilustrovano na
slici 6.6, gde imamo dva razli ita binarna stabla i jedno obi no stablo koje
c
c
izgleda vrlo sli no ovim binarnim stablima.
c
Primetimo da stabla pod (a) i (b) na slici 6.6 nisu ista binarna stabla,
niti je neko od njih uporedivo sa obi nim stablom pod (c). Na primer, u
c

binarnom stablu pod (a) cvor 2 je levo dete cvora 1, a cvor 1 nema desno
vor 1 nema levo dete ali ima cvor 2 kao

dete, dok u binarnom stablu pod (b) c


desno dete. Sa druge strane, u obi nom stablu pod (c) nemamo denisano
c

levo ili desno dete cvor 2 je samo dete cvora 1, niti levo niti desno.

152

Stabla

1
2

4
5

(a)

(b)

(c)

S LIKA 6.6: Razlike izmedu binarnih i obi nih stabala.


c

Uprkos ovim malim konceptualnim razlikama, osnovna terminologija


optih stabala prenosi se i na binarna stabla. Svi osnovni pojmovi koje smo
denisali za obi na stabla imaju smisla i za binarna stabla.
c
Predstavljanje binarnog stabla je umnogome pojednostavljeno zahva
ljuju i cinjenici da svaki cvor binarnog stabla ima najvie dvoje dece. U
c
praksi se za predstavljanje binarnih stabala skoro isklju ivo koriste poc
kaziva i, jer je takva njihova reprezentacija prirodna i jednostavna. Precic
znije, binarno stablo je organizovano u obliku povezane strukture podataka

u kojoj je svaki cvor predstavljen jednim objektom. Taj objekat ima polje
klju, koje sadri klju cvora, kao i dva pokaziva ka polja levo i desno,
c
c
c

koja pokazuju na objekte koji predstavljaju levo i desno dete cvora. Ako
neko dete nije prisutno, odgovaraju e pokaziva ko polje sadri vrednost
c
c
null. Stablu T se kao celini pristupa preko posebnog spoljanjeg pokac
ziva a t koji nije deo stabla i koji pokazuje na koren stabla. Ovaj na in
c
predstavljanja binarnog stabla je ilustrovan u desnom delu na slici 6.7 za
stablo koje je prikazano u levom delu.
t

levo
desno
klju
c

2
3

2
4

S LIKA 6.7: Predstavljanje binarnog stabla.

6.2. Binarna stabla

153

Obilazak binarnog stabla


Vana operacija nad nelinearnom strukturom stabla je neka aktivnost

koja se izvrava nad podacima (klju evima) svih cvorova binarnog stabla.
c
Ta operacija se neutralno naziva obilazak binarnog stabla i sastoji se kre

tanja du grana stabla od cvora do cvora radi sistemati nog pose ivanja
c
c
vorova stabla kako se neki cvor ne bi ponovio. Konkretna aktivnost

svih c

koja se obavlja nad podacima u cvoru v prilikom njegovog pose ivanja zac
visi od primene operacije obilaska stabla i moe obuhvatati sve od samog

prikazivanja podataka cvora v do neke mnogo sloenije obrade podataka

cvora v.
Tri naj e a sistemati na postupka za obilazak binarnog stabla T od
c c
c

njegovog korena jesu obilazak cvorova u preorder, inorder i postorder redosledu. Oni se razlikuju samo po redosledu po kojem se pose uju naredni
c

cvor i njegovo levo i desno podstablo. Na slici 6.8 su ilustrovana ova tri
na ina tako to je brojevima 1, 2 i 3 ozna en redosled po kojem se pose uju
c
c
c

naredni cvor r (aktuelni koren) i njegovo levo i desno podstablo T i T d .


1

3
T

Td

preorder

3
T

Td

inorder

2
T

Td

postorder

S LIKA 6.8: Tri na ina obilaska binarnog stabla.


c
Formalna rekurzivna denicija preorder, inorder i postorder obilaska
binarnog stabla T je:

1. Ako je stablo T prazno, nita se ne obilazi jer T nema nijedan cvor.


2. Ina e, neka je r koren stabla T sa (mogu e praznim) levim i desnim
c
c

podstablima T i T d ciji su koreni deca od r. Onda:

preorder obilazak cvorova stabla T sastoji se najpre od posete

korena r, zatim od rekurzivnog obilaska cvorova stabla T u

preorder redosledu i na kraju od rekurzivnog obilaska cvorova


stabla T d u preorder redosledu;

inorder obilazak cvorova stabla T sastoji se najpre od rekur vorova stabla T u inorder redosledu, zatim
zivnog obilaska c

od posete korena r i na kraju od rekurzivnog obilaska cvorova


stabla T d u inorder redosledu;

154

Stabla

postorder obilazak cvorova stabla T sastoji se najpre od rekur


zivnog obilaska cvorova stabla T u postorder redosledu, zatim

od rekurzivnog obilaska cvorova stabla T d u postorder redosledu i na kraju od posete korena r.

Na slici 6.9 su ilustrovana prethodna tri na ina obilaska svih cvorova


c
na konkretnom primeru jednog binarnog stabla.
T

preorder:

inorder:

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

postorder:

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

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

S LIKA 6.9: Lista cvorova binarnog stabla T dobijena na preorder, inorder


i postorder na in.
c
Imaju i u vidu standardni na in predstavljanja binarnih stabala poc
c
mo u pokaziva a, lako moemo napisati algoritme za preorder, inorder i
c
c

postorder obilaske cvorova binarnog stabla. U nastavku cemo pokazati

samo algoritam za inorder obilazak binarnog stabla, pri cemu se za svaki

cvor prikazuje njegov klju . Algoritmi za ostala dva na ina obilaska binarc
c

nog stabla ostavljaju se citaocima za vebu.


// Ulaz: vor t binarnog stabla
c
// Izlaz: lista kljueva podstabla sa korenom t u inorder redosledu
c
algorithm bt-inorder(t)
if (t != null) then
bt-inorder(t.levo);
print(t.klju);
c
bt-inorder(t.desno);
return;

Obratite panju na to da je rekurzivni algoritam bt-inorder neposredna implementacija rekurzivne denicije inorder obilaska binarnog sta
bla. Pri tome, obrada svakog cvora prilikom njegovog pose ivanja sastoji
c
se od prostog prikazivanja klju a cvora.
c

6.3. Binarna stabla pretrage

155

Nije teko pokazati da vreme izvravanja algoritma bt-inorder za

binarno stablo od n cvorova iznosi O(n). (U stvari, to je ta no i za druga


c

dva algoritma ostalih na ina obilaska.) To sledi na osnovu cinjenice da se


c

c
algoritam bt-inorder poziva ta no dva puta za svaki cvor stabla jednom
za njegovo levo dete i jednom za njegovo desno dete. Poto se deo algoritma
bt-inorder koji ne obuhvata ove rekurzivne pozive izvrava za konstantno
vreme, ukupno vreme izvravanja bi e 2n O(1) = O(n).
c
Ovo je dobra prilika da se osvrnemo i na na stil programiranja.

Cesto cemo jednostavne algoritme, kao to je to algoritam bt-inorder,


izraavati u rekurzivnom obliku. Naravno, svaki rekurzivni algoritam se
moe napisati iterativno, ako nita drugo simuliraju i rekurziju pomo u
c
c
steka. U stvari, u praksi je bolje pisati algoritme na iterativni nego na
rekurzivni na in, jer se tako dobija na ekasnosti izbegavanjem dodatnih
c
implicitnih operacija koje svaka rekurzija name e. Na primer, iterativnu
c
c
c
verziju istog algoritma bt-inorder moemo napisati na slede i na in:
// Ulaz: vor t binarnog stabla
c
// Izlaz: lista kljueva podstabla sa korenom t u inorder redosledu
c
algorithm bt-inorder(t)
stack-make(s); // inicijalizacija praznog steka s
repeat
while (t != null) do
push(t,s);
t = t.levo;
t = pop(s);
print(t.klju);
c
t = t.desno;
until (stack-empty(s) && (t == null));
return;

Nije teko razumeti kako ovaj iterativni algoritam radi on u sutini


simulira rekurziju pomo u steka s. Ipak, iako su rekurzivni algoritmi
c
manje ekasni (samo u apsolutnom smislu, ali ne i asimptotski), nama
je blia rekurzija poto se dobijaju algoritmi koji su skoro uvek laki za
razumevanje i analiziranje.

6.3

Binarna stabla pretrage

Binarno stablo pretrage je binarno stablo u kojem svaki cvor v ima

slede e BSP svojstvo: svi cvorovi u levom podstablu cvora v imaju klju eve
c
c

156

Stabla

koji su manji od klju a cvora v, a svi cvorovi u desnom podstablu cvora v


c
imaju klju eve koji su ve i od klju a cvora v. BSP svojstvo binarnog stabla
c
c
c

T moemo dakle izraziti na slede i na in: za svaki cvor v stabla T, ako je


c
c

c
c
u cvor u levom podstablu cvora v, onda je v.klju > u.klju; a ako je

c
c
w cvor u desnom podstablu cvora v, onda je v.klju < w.klju. (Ovde
pretpostavljamo pojednostavljen slu aj da su svi klju evi razli iti.)
c
c
c
Obratite panju na to da u binarnom stablu pretrage implicitno podra
zumevamo da se klju evi cvorova mogu medusobno uporedivati. To zna i
c
c

da klju evi pripadaju nekom totalno uredenom skupu, tj. skupu nad cijim
c

elementima je denisana relacija manje od. Primeri ovih skupova obuhvataju skupove celih i realnih brojeva sa uobi ajenom relacijom poretka
c
brojeva, kao i skup znakovnih stringova sa leksikografskim poretkom.
Na slici 6.10 su prikazana dva binarna stabla pretrage koja sadre isti

skup vrednosti klju eva. Kao to cemo videti, vreme izvravanja ve ine
c
c
operacija nad binarnim stablom pretrage je proporcionalno visini stabla.
U tom smislu, desno stablo na slici 6.10 je manje ekasno.
3
7
5
3

5
8

8
9

S LIKA 6.10: Dva binarna stabla pretrage sa istim klju evima.


c

BSP operacije
Tipi ne operacije nad binarnim stablom pretrage su traenje, dodavac

nje i uklanjanje cvora iz takvog stabla.

Traenje cvora. Najpre cemo panju posvetiti problemu traenja cvora


sa datim klju em x u binarnom stablu pretrage T. Da bismo brzo locirali
c

cvor sa klju em x u stablu T, ili utvrdili da se cvor sa tim klju em ne nalazi


c
c
u stablu, koristimo BSP svojstvo. Naime, ukoliko uporedimo x sa klju em
c
korena stabla T, razlikuju se tri slu aja.
c

6.3. Binarna stabla pretrage

157

Prvi, najlaki slu aj je ako je klju korena stabla T jednak x, jer smo
c
c

onda nali traeni cvor i moemo zavriti pretragu. U drugom slu aju, ako
c
je klju korena stabla T ve i od x, prema BSP svojstvu moemo zaklju iti
c
c
c

da se cvor sa klju em x moe na i samo u levom podstablu korena stabla T,


c
c
jer su u desnom podstablu svi klju evi ve i od klju a korena, pa time i od x.
c
c
c
Zbog toga pretragu rekurzivno nastavljamo na isti na in od korena levog
c
podstabla korena stabla T. Najzad, u tre em slu aju koji je simetri an
c
c
c

drugom, ako je klju korena stabla T manji od x, onda se cvor sa klju em x


c
c
moe na i samo u desnom podstablu korena stabla T. Zbog toga pretragu
c
rekurzivno nastavljamo na isti na in od korena desnog podstabla korena
c
stabla T.

Ovaj neformalni opis operacije traenja cvora u binarnom stablu pretrage preciziran je rekurzivnim algoritmom bst-search u nastavku. Ako

su dati pokaziva t na neki cvor u binarnom stablu pretrage i klju x,


c
c

c
c
c
algoritam bst-search kao rezultat vra a pokaziva na cvor sa klju em

x, ukoliko se takav cvor nalazi u podstablu ciji je koren t; u suprotnom

slu aju, ukoliko takav cvor ne postoji, ovaj algoritam vra a pokaziva null.
c
c
c
// Ulaz: vor t binarnog stabla pretrage, klju x
c
c
// Izlaz: pokaziva na vor sa kljuem x, ili null
c
c
c
algorithm bst-search(t, x)
if ((t == null) || (t.klju == x)) then
c
return t;
else if (t.klju > x) then
c
bst-search(t.levo, x);
else
bst-search(t.desno, x);

Na slici 6.11 je ilustrovan na in rada algoritma bst-search na primeru


c
jednog binarnog stabla pretrage.
17
5
4
2

21
11

9
7

18

23

15
13

16

S LIKA 6.11: Traenje cvora 13 u datom binarnom stablu pretrage.

158

Stabla

Kao to se vidi sa slike 6.11, u algoritmu bst-search se pretraga zapo

cinje od korena stabla i prelazi se odreden put nadole du grana i cvorova

u stablu. Za svaki cvor na tom putu, u algoritmu se uporeduje klju tog


c

cvora sa traenom vredno u. Ako su oni jednaki, pretraga se zavrava.


c
U suprotnom slu aju, pretraga se nastavlja u levom ili desnom podstablu
c

cvora zavisno od toga da li je klju cvora ve i ili manji od traene vrednosti.


c
c
vorovi na koje se rekurzivno dolazi tokom pretrage obrazuju put u
Poto c
stablu od korena pa do nekog lista u najgorem slu aju, vreme izvravanja
c
algoritma bst-search je O(h) za stablo visine h.

Dodavanje cvora. Operacija dodavanja (kao i uklanjanja) cvora modikuje binarno stablo pretrage tako da moramo paziti da ne naruimo BSP

svojstvo u rezultuju em stablu. Imaju i to u vidu, dodavanje novog cvora


c
c
u binarno stablo pretrage moe se ipak uraditi na relativno jednostavan
na in.
c

Da bismo novi cvor p dodali u binarno stablo pretrage T, u sutini


najpre pokuavamo da lociramo klju cvora p u T primenjuju i postupak
c
c
traenja tog klju a. Ako ga nademo, ne treba nita drugo da radimo, jer
c

ne dodajemo duplikat cvora u stablo u skladu sa naom pojednostavljenom


pretpostavkom da su svi klju evi stabla T razli iti. U suprotnom slu aju,
c
c
c

prema proceduri traenja klju a dolazimo do cvora koji nema levo ili desno
c

dete to ukazuje da cvor p nije u stablu T. Nije teko videti da je to pravo

mesto u stablu T za dodavanje novog cvora. Zbog toga na tom mestu do


dajemo p kao novi cvor-list u T i povezujemo p tako da bude odgovaraju e
c

dete cvora u kojem se zaustavila procedura traenja.

U ispravnost ovog postupka citaoci se verovatno mogu lake uveriti

ukoliko se operacija dodavanja cvora formulie u rekurzivnom obliku. Ako

je T prazno stablo, ono postaje stablo koje se sastoji samo od novog cvora
c
c
p. Ako stablo T nije prazno, a njegov koren ima klju jednak klju u cvora
p, tada se p ve nalazi u stablu i zato nita dodatno ne treba uraditi. Sa
c
druge strane, ako stablo T nije prazno i njegov koren nema isti klju kao
c

cvor p, cvor p dodajemo u levo podstablo korena ako je klju korena ve i od


c
c
klju a cvora p, ili dodajemo p u desno podstablo korena ako je klju korena
c
c
manji od klju a cvora p.
c
Rekurzivni algoritam bst-insert u nastavku predstavlja realizaciju

ovog neformalnog opisa operacije dodavanja cvora. Ako su dati pokaziva


c

t na cvor binarnog stabla pretrage i pokaziva na novi cvor p, tim algoritc

mom se dodaje cvor p u podstablo ciji je koren t. Pri tome se pretpostavlja

6.3. Binarna stabla pretrage

159

da polje p.klju ve sadri eljeni klju i da polja p.levo i p.desno sadre


c c
c
vrednost null.
// Ulaz: vor t binarnog stabla pretrage, novi vor p
c
c
// Izlaz: vor p dodat u podstablo sa korenom t
c
algorithm bst-insert(t, p)
if (t == null) then
t = p;
else if (p.klju < t.klju) then
c
c
t.levo = bst-insert(t.levo, p);
else if (p.klju > t.klju) then
c
c
t.desno = bst-insert(t.desno, p);
else
; // duplikati se ne dodaju
return t;

Na slici 6.12 je ilustrovan na in rada algoritma bst-insert na primeru


c
jednog binarnog stabla pretrage. Sa te slike se vidi da rad ovog algoritma
po inje od korena stabla i da se prelazi odreden put nadole u stablu ba
c

kao u slu aju traenja cvora. Taj put se zavrava u cvoru cije levo ili desno
c

dete treba da bude novi cvor. Stoga, ba kao u slu aju operacije traenja
c

cvora, vreme izvravanja algoritma bst-insert je O(h) za stablo visine h.


17
5
4

23
11

27

21
19

22

25

S LIKA 6.12: Dodavanje cvora 25 datom binarnom stablu pretrage.

c
c
c
U algoritmu bst-insert se sre emo sa jednom tehni kom poteko om

koja se sastoji u tome to kada novi cvor treba zameniti umesto trenutno

praznog cvora, potrebno je vratiti se i aurirati jedno od pokaziva kih polja


c

u cvoru roditelja novog cvora. To je razlog zato prenosimo povratnu infor


maciju o rezultuju em podstablu posle dodavanja cvora. Drugim re ima,
c
c
c
c
algoritam bst-insert vra a pokaziva na koren podstabla sa novododatim

cvorom. Medutim, to je istovremeno jedan od uzroka relativne neekasno

sti rekurzivne implementacije, budu i da samo poslednji cvor treba da se


c

160

Stabla

aurira. Kod svih ostalih cvorova algoritam vra a isti pokaziva koji je
c
c

primio, tako da kod tih cvorova fakti ki nema stvarnih promena.


c

Uklanjanje cvora. Uklanjanje cvora p iz binarnog stabla pretrage

malo komplikovanije od traenja ili dodavanja cvora. Pre svega, ako


vor (list) u stablu, moemo jednostavno ukloniti taj cvor

p spoljanji c

stabla. Na slici 6.13 je prikazano uklanjanje spoljanjeg cvora (lista)


jednog binarnog stabla pretrage.
17

17

23

11
10

je
je
iz
iz

21
19

27
22

23
11

25

21
20

27
22

25

20

S LIKA 6.13: Uklanjanje spoljanjeg cvora (lista) 10 iz datog binarnog


stabla pretrage.

Medutim, ako je p unutranji cvor, ne moemo ga prosto ukloniti jer

cemo time prekinuti strukturu stabla. Zbog toga, stablo se mora restruk
turirati tako da cvor p bude uklonjen, ali i da BSP svojstvo za preostale

cvorove ne bude narueno. A da bi se to postiglo, razlikuju se dva opta

slu aja. U prvom slu aju, kada cvor p ima samo jedno dete q, cvor p
c
c
moe se zameniti tim detetom. Preciznije, dete q se povezuje tako da bude

novo dete roditelja cvora p umesto starog deteta cvora p. Ova opta
transformacija binarnog stabla pretrage je ilustrovana na slici 6.14.

S LIKA 6.14: Opti slu aj uklanjanja unutranjeg cvora p sa jednim


c
detetom iz binarnog stabla pretrage.

6.3. Binarna stabla pretrage

161

Na slici 6.15 je prikazan konkretan primer uklanjanja unutranjeg cvora


sa jednim detetom iz binarnog stabla pretrage.
17

17

23

11

21

10

19

27
22

23

11

25

10

21
20

27
22

25

20

S LIKA 6.15: Uklanjanje unutranjeg cvora 19 sa jednim detetom iz datog


binarnog stabla pretrage.

U drugom slu aju, kada unutranji cvor p ima dvoje dece, jedan nac

cin za njegovo uklanjanje je da se najpre nade najmanji cvor q u desnom

podstablu cvora p. (Druga mogu nost je da se nade najve i cvor u levom


c
c

podstablu cvora p.) Zatim se zamenjuje cvor p cvorom q i uklanja se cvor


q iz desnog podstabla. Ovaj opti pristup je ilustrovan na slici 6.16.
p

<p

<q
>p

q
>q

>q

q
>q

S LIKA 6.16: Opti slu aj uklanjanja unutranjeg cvora p sa dvoje dece iz


c
binarnog stabla pretrage.
Primetimo da BSP svojstvo nije narueno u dobijenom stablu, jer je

cvor p ve i od svih cvorova u njegovom levom podstablu, a cvor q je ve i


c
c

od cvora p, kao i bilo koji drugi cvor iz desnog podstabla cvora p. Dakle,

to se ti e levog podstabla cvora p, cvor q moe zameniti cvor p. Ali q je


c

odgovaraju i cvor i to se ti e desnog podstabla cvora p, jer je q najmanji


c
c

cvor u tom desnom podstablu.

Na slici 6.17 je ilustrovan konkretan primer uklanjanja cvora sa dvoje


dece iz binarnog stabla pretrage.

162

Stabla

17

19

23

11
10

5
27

21
19

22

25

23

11
10

27

21
20

22

25

20

S LIKA 6.17: Uklanjanje unutranjeg cvora 17 sa dvoje dece iz datog


binarnog stabla pretrage.

Pre predstavljanja kompletnog algoritma za operaciju uklanjanja cvora


iz binarnog stabla pretrage, navodimo pomo ni algoritam koji uklanja najc

manji cvor iz nepraznog podstabla sa korenom t. Najmanji cvor u podsta


blu sa korenom t je lako ukloniti, poto taj cvor sigurno nema levo dete (jer
bi ono moralo biti manje) i zato uvek imamo jedan od dva prosta slu ajeva
c

za uklanjanje cvora koji je bez dece ili ima samo jedno dete.
// Ulaz: vor t binarnog stabla pretrage
c
// Izlaz: uklonjen najmanji vor p iz podstabla sa korenom t
c
algorithm bst-deletemin(t)
if (t.levo == null) then
p = t;
return t.desno;
else
t.levo = bst-deletemin(t.levo);
return t;

U rekurzivnom algoritmu bst-deletemin se u podstablu sa korenom

t trai najmanji cvor tako to se prate leva deca od cvora t dok se ne

naide na cvor p koji nema levo deto. To se prepoznaje time to je za

taj cvor pokaziva p.levo jednak null. Slika 6.18 sugerie zato je taj
c

cvor najmanji. Naime, prate i put od t do p, koji predstavlja levu ivicu


c

podstabla sa korenom t, znamo da svi preci cvora p na tom putu, kao i

cvorovi u njihovim desnim podstablima, jesu ve i od p. Ve i su i svi cvorovi


c
c

u desnom podstablu cvora p, cime su iscrpljeni svi cvorovi razli iti od p u


c
podstablu sa korenom t.
c
c
U algoritmu bst-deletemin se kao rezultat vra a i pokaziva na uklo
njeni najmanji cvor preko globalne promenljive p. Razlog za to je da bi
algoritam u kome se poziva bst-deletemin mogao da eventualno iskoristi

6.3. Binarna stabla pretrage

163
t

>p

p
>p

S LIKA 6.18: Nalaenje najmanjeg cvora u binarnom stablu pretrage.

taj najmanji cvor za svoje potrebe. Jedan takav algoritam je rekurzivni


algoritam bst-delete prikazan u nastavku. On predstavlja kompletnu

realizaciju operacije uklanjanja cvora sa datim klju em x iz binarnog stac

bla pretrage na ciji koren ukazuje pokaziva t. Primetimo da algoritam


c

bst-delete ne radi nita ukoliko se cvor sa datim klju em ne nalazi u


c
stablu.
// Ulaz: vor t binarnog stabla pretrage, klju x
c
c
// Izlaz: uklonjen vor sa kljuem x iz stabla sa korenom t
c
c
algorithm bst-delete(t, x)
if (t != null) then // neprazno stablo, nai klju x
c
c
if (t.klju > x) then
c
t.levo = bst-delete(t.levo, x);
else if (t.klju < x) then
c
t.desno = bst-delete(t.desno, x);
else
// t.klju = x, ukloniti vor t
c
c
p = t;
if (t.levo == null) then
return t.desno;
else if (t.desno == null) then
return t.levo;
else
// vor sa dva deteta
c
t.desno = bst-deletemin(t.desno);
t.klju = p.klju;
c
c
return t;

U algoritmu bst-delete se takode po inje od korena binarnog stabla


c

pretrage i prelazi odreden put niz stablo da bi se najpre naao cvor koji

treba ukloniti. U algoritmu se zatim uklanja taj cvor primenjuju i odgovac

raju i postupak zavisno od broja njegove dece. Najgori slu aj je kada cvor
c
c
za uklanjanje ima dvoje dece, jer se tada u algoritmu prelazi dodatni put

dalje niz stablo da bi se pronaao najmanji cvor u desnom podstablu cvora

164

Stabla

koji se uklanja. U svakom slu aju dakle, put koji se prelazi nije dui od
c

visine stabla. Prema tome, kao i za operacije traenja i dodavanja cvora,


vreme izvravanja algoritma bst-delete je O(h) za stablo visine h.
Ekasnost BSP operacija. Pokazali smo da se sve tri osnovne operacije

nad binarnim stablom pretrage izvravaju za vreme O(h), pri cemu je h


visina stabla. Medutim, visina binarnog stabla pretrage se menja kako se

cvorovi dodaju i uklanjaju. Da bismo zato nau analizu u inili preciznijom,


c

moramo oceniti visinu tipi nog binarnog stabla pretrage sa n cvorova.


c

U najgorem slu aju, svi cvorovi stabla se mogu nalaziti na jednom


c
putu. To bismo dobili, na primer, kada bismo n klju eva dodali u rastu em
c
c
redosledu u po etno prazno stablo. Drugi degenerativni slu ajevi su putevi
c
c

koji vijugaju levo ili desno kod nekih unutranjih cvorova. Na slici 6.19 su
prikazana dva primera ovih najgorih scenarija.

S LIKA 6.19: Najgora binarna stabla pretrage.

Visina svih ovih degenerativnih binarnih stabla pretrage sa n cvorova


c
je o igledno n 1. Na osnovu toga moemo zaklju iti da se osnovne BSP
c
operacije izvravaju za linearno vreme O(n) u najgorem slu aju.
c
U najboljem slu aju, binarno stablo pretrage predstavlja puno binarno
c
stablo. U takvom stablu, svi listovi se nalaze samo na poslednjem nivou

i svi unutranji cvorovi imaju ta no dvoje dece. Na slici 6.20 je prikazano


c

puno binarno stablo sa 15 cvorova.

S LIKA 6.20: Puno binarno stablo.

6.4. Binarni hipovi

165

U punom binarnom stablu visine h, jednostavnom indukcijom po visini

stabla moe se pokazati da je njegov broj cvorova jednak n = 2h+1 1.


Dakle, u takvom stablu je n + 1 = 2h+1 ili, ekvivalentno, h + 1 = log (n + 1),
odnosno h = log (n + 1) 1. Drugim re ima, vreme izvravanja osnovnih
c
BSP operacija je O(log n) u najboljem slu aju.
c

U praksi nije cest nijedan od ova dva slu aja, pa se moe postaviti pitac
nje ta je tipi an slu aj izmedu ova dva ekstrema? To jest, da li je tipi no
c
c
c

vreme blie linearnom ili logaritamskom vremenu u odnosu na broj cvorova


stabla? Odgovor na to pitanje moe se dobiti sloenijom matemati kom
c
analizom koju ovde izostavljamo: uz relativno razumne pretpostavke verovatniji je bolji slu aj, pa se osnovne BSP operacije tipi no izvravaju za
c
c
logaritamsko vreme.

6.4 Binarni hipovi

Binarni hipovi su binarna stabla kod kojih svi cvorovi zadovoljavaju


specijalno svojstvo, sli no kao kod binarnih stabala pretrage. Ali uz to,
c
odgovaraju a binarna stabla kod binarnih hipova moraju dodatno imati
c
specijalan oblik i biti to vie razgranata (balansirana).

Preciznije, binarno stablo se naziva kompletno ako ima cvorove na svim


nivoima osim moda poslednjem. Na poslednjem nivou, na kojem neki

cvorovi mogu nedostajati, svi postoje i cvorovi moraju biti levo od onih
c
koji nedostaju. Na slici 6.21 su prikazani opti oblik i konkretan primer
kompletnog binarnog stabla.
1

11 10

S LIKA 6.21: Kompletno binarno stablo.


Binarni hip (ili kra e samo hip) je kompletno binarno stablo u kojem
c

je klju svakog cvora manji od klju eva dece tog cvora. Drugim re ima,
c
c
c

za svaki cvor v kompletnog stabla T, ako su u i w deca cvora v, onda je

166

Stabla

v.klju < u.klju i v.klju < w.klju. Ovo svojstvo se naziva hip
c
c
c
c

svojstvo.

Obratite panju na to da hip svojstvo implicira da je klju svakog cvora


c

v u hipu manji od klju eva svih cvorova u podstablu sa korenom v. Pored


c

toga, najmanji cvor (tj. cvor sa minimalnim klju em) mora biti koren hipa,
c

ali manji cvorovi ne moraju biti na manjoj dubini od ve ih cvorova. Na


c

primer, u binarnom hipu na slici 6.21 cvorovi 4, 5 i 6 se nalaze na ve oj


c

dubini od cvora 7. Drugo zapaanje je da se cvorovi na svakom putu od

nekog cvora nadole niz stablo nalaze u sortiranom rastu em redosledu.


c
U stvari, hipovi koji zadovoljavaju prethodno navedeno hip svojstvo
nazivaju se preciznije min-hipovi. Mogli bismo isto tako da deniemo

max-hipove kod kojih je klju svakog cvora ve i od klju eva njegove dece.
c
c
c
Nema nita posebno to izdvaja min-hipove u odnosu na max-hipove. Oba
oblika hipova se ravnopravno koriste u praksi i sva zapaanja uz o igledne
c
izmene vae u oba slu aja.
c

Hip operacije

Tipi ne operacije nad hipom su uklanjanje najmanjeg cvora (i vra anje


c
c

njegovog klju a), dodavanje novog cvora u hip, kao i stvaranje hipa od
c

kompletnog binarnog stabla ciji se cvorovi nalaze u proizvoljnom poretku.


U nastavku ovog odeljka govorimo o tome kako se ove operacije mogu
realizovati.

Uklanjanje najmanjeg cvora. Najmanji cvor u binarnom hipu je lako

prona i, jer smo zapazili da taj cvor mora biti koren stabla. Medutim,
c

ako prosto uklonimo koren, vie ne emo imati stablo. Zbog toga moramo
c
nekako na i novi klju za koren tako da stablo i dalje bude skoro puno, ali i
c
c
da hip svojstvo ne bude narueno. Ovo obezbedujemo slede im postupkom
c

koji se sastoji od dve faze.


U prvoj fazi, da bi se stablo sa uvalo da bude skoro puno, najpre se
c
uzima klju sasvim desnog lista na poslednjem nivou, zatim se uklanja taj
c
list i na kraju se klju korena privremeno zamenjuje sa uzetim klju em
c
c
sasvim desnog lista. Time je kompletnost rezultuju eg stabla o evidno
c
c
sa uvana, ali hip svojstvo novog korena moe biti narueno. Zato u drugoj
c
fazi, da bi se obnovila vanost hip svojstva, klju novog korena se pomera
c
nadole niz stablo do njegovog pravog mesta. To zna i da se taj klju gura
c
c
nadole niz stablo sve dok se moe zameniti sa klju em jednog od deteta
c

aktuelnog cvora koje ima manji klju .


c

6.4. Binarni hipovi

167

Preciznije, pretpostavimo da je x aktuelni cvor koji naruava hip svojstvo. To zna i da je x ve i od jednog ili oba svoja deteta. Klju cvora
c
c
c
x moemo zameniti klju em jednog od njegova dva deteta, ali pri tome
c
moramo biti paljivi. Ako x zamenimo sa manjim od njegova dva deteta,
sigurno ne emo naruiti hip svojstvo izmedu dva ranija deteta, od kojih je
c

jedan sada postao roditelj drugog. Ponavljaju i ovaj postupak za po etni


c
c
e na kraju do i ili do nekog lista ili do cvora cija oba

klju , taj klju c


c
c
c
deteta imaju ve i klju . Na slici 6.22 je ilustrovan ovaj postupak uklanjanja
c
c

najmanjeg cvora iz hipa sa slike 6.21.


1

10

11 10

zameniti
stari koren

11

spustiti
novi koren

10

11

S LIKA 6.22: Uklanjanje najmanjeg cvora iz hipa.

Primetimo da se operacija uklanjanja najmanjeg cvora iz hipa izvrava

za vreme O(log n) ukoliko hip ima n cvorova. Ovo sledi otuda to se postupak potiskivanja privremenog klju a korena ponavlja najvie h puta, gde je
c
h visina stabla. A poto je h log (n + 1) u kompletnom binarnom stablu od

n cvorova i svaki korak sputanja klju a se izvrava za konstantno vreme


c

po cvoru, ukupno vreme je O(log n).

Dodavanje cvora. Razmotrimo sada kako se moe dodati novi cvor u


binarni hip, imaju i u vidu da dobijeni hip mora biti skoro pun i da hip
c

svojstvo u njemu mora ostati na snazi. Jedan na in je da se novi cvor doda


c
na poslednjem nivou na prvom mestu koje je sasvim levo mogu e, po inju i
c
c
c
novi nivo ako je poslednji nivo trenutno popunjen.
Time je kompletnost rezultuju eg stabla sa uvana, ali hip svojstvo roc
c

ditelja novog cvora moe biti narueno. Zato se opet pokuava da se to


neutralie guranjem navie novog klju a uz stablo. To zna i da se meduc
c

sobno zamenjuju novi klju aktuelnog cvora i klju roditelja tog cvora, ako
c
c
roditelj ima manji klju . Ovo zamenjivanje se ponavlja sve dok novi klju
c
c

ne dode ili do korena ili do cvora ciji roditelj ima manji klju . Na slici 6.23
c

je ilustrovan postupak dodavanja cvora 2 hipu sa slike 6.21.

168

Stabla
1

11 10

podi i
c

novi cvor

11 10

S LIKA 6.23: Dodavanje novog cvora u hip.

Vreme izvravanja potrebno za operaciju dodavanja cvora u hip je pro


porcionalno duini puta koji novi cvor prelazi od po etnog mesta na posledc
njem nivou do svog pravog mesta. Ta duina puta je o igledno ograni ena
c
c
visinom stabla hipa, pa je vreme izvravanja jednako O(log n) za hip od n

cvorova.
Konstruisanje hipa. Pretpostavimo da je dato kompletno binarno sta

blo ciji su cvorovi proizvoljno razmeteni tako da njihovi klju evi ne zadoc
voljavaju hip svojstvo. Operacija konstruisanja hipa sastoji se od preuredi
vanja klju eva tog stabla tako da ono na kraju bude hip.
c
Jedan o igledan na in da se ovo postigne je da se po ne od praznog
c
c
c

hipa i da mu se zatim redom dodaju cvorovi datog kompletnog binarnog

stabla jedan po jedan. (Pri tome se, recimo, cvorovi datog stabla uzimaju
tokom obilaska tog stabla jednim od tri standardna metoda.) Kako svaka

operacija dodavanja cvora u hip proizvodi stablo koje je takode binarni hip,

to ce se posle dodavanja svih cvorova na kraju dobiti traeni hip.


Medutim, ovaj postupak nije mnogo ekasan, jer bi za stablo od n

cvorova njegovo vreme izvravanja bilo O(n log n). To je zato to se njime

obavlja n operacija dodavanja cvora, a svaka od tih operacija se izvrava


za vreme O(log n) (to smo pokazali u prethodnom odeljku). Postoji bolje

reenje za ovaj problem cije je vreme izvravanja samo O(n). O njemu

cemo vie govoriti u narednom odeljku koje je posve eno jednoj konkretnoj
c
realizaciji binarnog hipa.

Predstavljanje hipa pomocu niza


Poto je hip skoro puno binarno stablo, ono se moe ekasno predstaviti
na neobi an na in pomo u niza. Ideja ove reprezentacije je pozajmljena
c
c
c

od na ina na koji bi se cvorovi stabla poredali po nivoima. To zna i da


c
c

6.4. Binarni hipovi

169

elementi jednog niza predstavljaju cvorove binarnog hipa nivo po nivo,


po inju i od korena i idu i sleva na desno unutar jednog nivoa. Preciznije,
c
c
c
prvi element niza sadri koren stabla, drugi element niza sadri levo dete

korena, tre i element niza sadri desno dete korena, cetvrti element niza
c
sadri levo dete levog deteta korena i tako dalje. Primer ovakve reprezen
tacije hipa sa 10 cvorova pomo u niza a je prikazan na slici 6.24.
c
a[1]

a[2]

a[4]

a[8]

a[3]

a[5]

a[9]

a[6]

a[7]

a[10]

S LIKA 6.24: Predstavljanje hipa sa 10 cvorova pomo u niza.


c

U optem slu aju dakle, ako za i 1 postoji levo dete cvora a[i], ono je
c
predstavljeno elementom a[2*i], a njegovo desno dete, ako postoji, predstavljeno je elementom a[2*i+1]. Ekvivalentna interpretacija je da se

roditelj cvora a[i] nalazi u elementu a[i/2] za i > 1.

Radi jednostavnosti, za klju eve cvorova hipa pretpostavljamo da su


c

celi brojevi i zanemarujemo dodatne podatke koje cvorovi mogu imati. Na


taj na in se binarni hip moe jednostavno predstaviti celobrojnim nizom.
c

Naravno, u praksi cesto ovakva jednostavna reprezentacija nije mogu a,


c
ali se hip onda moe predstaviti nizom objekata odgovaraju eg tipa. Ili
c
jo bolje, poto se sve operacije nad hipom zasnivaju na mnogobrojnim za
menama podataka pojedinih cvorova, hip bismo mogli predstaviti u obliku
niza pokaziva a na objekte- vorove i onda bi se zapravo zamenjivali samo
c
c
ovi pokaziva i.
c
Prema tome, u daljem izlaganju algoritama kojima se realizuju operacije nad hipom pretpostavljamo da je binarni hip predstavljen pomo u
c
celobrojnog niza a ta no onako kako je to prikazano na slici 6.24. Da ne bic

smo preopteretili listu parametara algoritama o kojima cemo govoriti, dalje

pretpostavljamo da se aktuelna veli ina hipa cuva u globalnoj promenljivoj


c

170

Stabla

n. Na kraju, podrazumevamo i da je veli ina niza uvek dovoljno velika za


c

hip od n cvorova, kako u algoritmima ne bismo morali da proveravamo da


li je prekora ena gornja granica niza.
c

Za operaciju dodavanja cvora u hip smo pokazali da se ona zasniva na

postupku pomeranja novog cvora navie uz stablo prema njegovom pravom

mestu. Uobi ajeno je da se za to kae da novi cvor isplivava na svoje pravo


c
mesto u stablu. Naredni rekurzivni algoritam predstavlja realizaciju tog

postupka isplivavanja cvora a[i] u hipu koji je predstavljen nizom a.


// Ulaz: vor a i hipa predstavljenog nizom a
c
// Izlaz: vor a i pomeren navie do svog pravog mesta u hipu
c
algorithm heap-bubbleup(a, i)
j = i / 2;

// a j je roditelj vora a i
c

if ((j > 0) && (a[i] < a[j])) then


swap(a[i],a[j]);
heap-bubbleup(a,j);
return;

Algoritam heap-bubbleup se koristi u narednom algoritmu kojim se

realizuje operacija dodavanja cvora x u hip od n cvorova koji je predstavljen


nizom a.

// Ulaz: hip predstavljen nizom a, cvor x


// Izlaz: hip predstavljen nizom a proiren za vor x
c
algorithm heap-insert(a, x)
n = n + 1;
a[n] = x;
heap-bubbleup(a,n);
return;

Operacija uklanjanja najmanjeg cvora pomera privremeni koren niz


stablo do njegovog pravog mesta. Uobi ajeno je da se za to kae da se pric

vremeni cvor prosejava kroz stablo do svog pravog mesta u stablu. Naredni rekurzivni algoritam predstavlja realizaciju tog postupka prosejavanja

cvora a[i] u hipu od n cvorova koji je predstavljen nizom a.


// Ulaz: vor a i hipa predstavljenog nizom a
c
// Izlaz: vor a i pomeren nadole do svog pravog mesta u hipu
c
algorithm heap-siftdown(a, i)
j = 2 * i;

// a j je levo dete vora a i


c

6.4. Binarni hipovi

171

if ((j < n) && (a[j+1] < a[j])) then


j = j + 1;

// a j je manje dete cvora a i


if ((j <= n) && (a[i] > a[j])) then
swap(a[i],a[j]);
heap-siftdown(a,j);
return;

Sada je lako napisati algoritam kojim se iz min-hipa od n cvorova pred


stavljenog nizom a uklanja najmanji cvor (koren) i vra a njegov klju .
c
c
// Ulaz: hip predstavljen nizom a
// Izlaz: klju uklonjenog korena hipa predstavljenog nizom a
c
algorithm heap-deletemin(a)
x = a[1];
a[1] = a[n];
n = n - 1;
heap-siftdown(a,1);
return x;

Preostalo je da pokaemo kako se moe formirati hip od niza ciji se


elementi nalaze u proizvoljnom poretku. Pomenuli smo jedan o igledan,
c
mada neekasan postupak kojim se po inje od praznog hipa i zatim mu
c
se redom dodaju elementi niza jedan po jedan. Ovo reenje preputamo

citaocima za vebu.
Bolji pristup je da se postupno konstruiu sve ve i hipovi po inju i od
c
c
c

cvorova na poslednjem nivou. Svi ovi cvorovi na poslednjem nivou su listovi


stabla i svaki od njih trivijalno predstavlja hip sam za sebe. Zatim se

konstruiu hipovi od podstabala ciji su koreni oni cvorovi koji se nalaze na


pretposlednjem nivou. Za ovo je, u stvari, potrebno prosejati samo korene
tih podstabala.

U narednom koraku se konstruiu hipovi od podstabala ciji su koreni

oni cvorovi koji se nalaze na prvom nivou iznad prethodnog. Za ovaj korak
je opet potrebno prosejati samo korene ovih podstabala. To je dovoljno
poto su njihova leva i desna podstabla ve formirani hipovi. Nastavljaju i
c
c
ovaj postupak nivo po nivo i idu i nagore dok se ne dode do globalnog
c

korena celog stabla, na kraju ce se formirati citav hip. Na slici 6.25 je

ilustrovan ovaj na in konstruisanja hipa od stabla neuredenih cvorova.


c

172

Stabla
4. korak

prosejati
3. korak

prosejati
2. korak

prosejati
1. korak

prosejati

10

prosejati

S LIKA 6.25: Konstruisanja hipa od stabla neuredenih cvorova.

Ova strategija je primenjena u upe atljivo jednostavnom i ekasnom


c
algoritmu u nastavku kojim se konstruie hip od n elemenata niza a koji
se nalaze u proizvoljnom redosledu.
// Ulaz: niz a od n neureenih elemenata
d
// Izlaz: preureen niz a tako da predstavlja binarni hip
d
algorithm heap-make(a)
for i = n/2 downto 1 do
heap-siftdown(a,i);
return;

Analiza algoritma heap-make nije jednostavna, jer se u njemu n/2 puta


poziva rekurzivni algoritam heap-siftdown.1 Sa druge strane, vreme izc
vravanja algoritma heap-siftdown nije lako oceniti na standardan na in

reavanjem neke rekurentne jedna ine o cemu smo govorili u odeljku 5.2.
c

Zbog toga cemo postupiti na drugi, rede primenjivan na in i izra unac


c

cemo blisku gornju granicu za broj poziva algoritma heap-siftdown tokom


rada algoritma heap-make za ulazni niz duine n. Nije se teko uveriti
da je taj ukupan broj poziva dominantan za vreme izvravanja algoritma
heap-make, jer se deo algoritma heap-siftdown van rekurzivnog poziva
izvrava za konstantno vreme.
Ukoliko se dakle primeni ovaj pristup, pokazuje se da je vreme izvravanja algoritma heap-make linearno, odnosno T(n) = O(n). Da bismo dokazali ovaj pomalo iznenaduju i rezultat, posmatra emo najgori slu aj kada
c
c
c

se radi o hipu koji je dat punim binarnim stablom visine h za neko h 0.


1 Ovde je ta nije re i da se algoritam heap-siftdown poziva n/2 puta, ali smo ve
c
c
c
napomenuli da radi jednostavnosti zanemarujemo ovu malu nepreciznost.

6.4. Binarni hipovi

173

Ekvivalentno, duina niza a koji predstavlja to stablo iznosi n = 2h+1 1.


c
Pored toga, mada algoritam heap-make po etno ne prosejava listove tog
stabla, pretpostavi emo da ih on ne preska e u svom radu. Drugim re ima,
c
c
c
to je kao da u algoritmu heap-make imamo da for petlja po inje od n, a ne
c
od n/2.
Za ovaj najgori slu aj moemo dakle zaklju iti da se najpre algoritam
c
c

heap-siftdown poziva za svaki od 2h listova. Zatim, za 2h1 cvorova


na pretposlednjem nivou, algoritam heap-siftdown se poziva najvie dva
puta, poto se u ovoj fazi prosejavaju koreni podstabala visine jedan. Na

slede em gornjem nivou, koji ima 2h2 cvorova, za svaki od njegovih cvoc
rova se algoritam heap-siftdown poziva najvie tri puta, poto se tada
prosejavaju koreni podstabala visine dva. Nastavljaju i rezonovanje na
c
ovaj na in, zaklju ujemo da se na nultom nivou korena celog stabla algoric
c
tam heap-siftdown poziva najvie h + 1 puta, poto se na kraju prosejava

ovaj koren citavog stabla koje ima visinu h. Na slici 6.26 je ilustrovana ova
argumentacija tako to su prikazani delovi niza a i odgovaraju i brojevi
c

poziva algoritma heap-siftdown za podstabla ciji se koreni nalaze u tim


delovima.
1

n/16 n/8

n/4

n/2

S LIKA 6.26: Ukupan broj poziva algoritma heap-siftdown.

Prema tome, ukoliko sa S(h) ozna imo ukupan broj poziva algoritma
c
heap-siftdown za puno binarno stablo visine h, onda je:

S(h) 2h 1 + 2h1 2 + 2h2 3 + + 21 h + 20 (h + 1)


=

h +1
i =1

2 h +1 i i

= 2 h +1

h +1

i =1

2i

Da bismo ograni ili poslednji zbir, ograni i emo njegovu beskona nu varic
cc
c
jantu 1 (i/2 i ):
i=

i =1

2i

1 2 3 4
+ + +
+
2 4 8 16

174

Stabla

1 1
1 1 1
1
1
1
1
1
+
+
+
+ +
+
+
+
+
+ .
2
4 4
8 8 8
16 16 16 16

A da bismo ograni ili ovaj beskona ni zbir, najpre cemo ga preurediti u


c
c
trougaoni zbir, zatim sabrati redove i, na kraju, sabrati poslednju kolonu
iza znaka jednakosti:
1
1 1 1 1
+ + +
+
+ = 1
2 4 8 16 32
1 1 1
1
1
+ +
+
+ =
4 8 16 32
2
1 1
1
1
+
+
+ =
8 16 32
4
1
1
1
+
+ =
16 32
8
.
.
.
Kako je 1 + 1/2 + 1/4 + 1/8 + = 2, to je

i
i =1 2

i zato

h +1

i =1

2i

i
i =0 2

i =1

2i

=2 ,

=2 .

Stoga, vreme izvravanja algoritma heap-make je:


T(n) = S(h) O(1)
2h+1 2 O(1)
= 2(n + 1) O(1)
= O(n) ,

to je trebalo pokazati.

6.5

Primene stabala

Od mnogobrojnih primena stabala u ra unarstvo u ovom odeljku navoc


dimo samo dva primera koja koristimo u daljem tekstu u poglavlju 8.

6.5. Primene stabala

175

Redovi sa prioritetima

Red za cekanje sa prioritetima elemenata predstavlja strukturu podataka u kojoj je svakom elementu ove strukture pridruena odredena

numeri ka vrednost koja se naziva njegov prioritet (ili klju ). Klasi nu


c
c
c
primenu ove strukture podataka nalazimo u operativnom sistemu sa de
ljenjem vremena ciji je osnovni zadatak da rasporeduje razli ite procese u
c

sistemu radi izvravanja od strane procesora. U realizaciji tog zadataka

takav operativni sistem koristi red ciji su elementi pojedini procesi u ra uc

narskom sistemu koji cekaju za izvravanje od strane procesora.


Medutim, svi trenutno aktivni procesi u sistemu ne moraju imati istu

vanost i zato se klasikuju prema svom prioritetu. Najvii prioritet verovatno imaju sistemski procesi kao to su upravlja ki programi za tastaturu
c
ili mrenu karticu. Zatim po vanosti dolaze korisni ki procesi u kojima se
c
izvravaju interaktivne aplikacije. Na kraju dolaze pozadinski procesi kao
to su neki program za pravljenje rezervnih kopija datoteka ili program za
neko duga ko izra unavanje koji je namenski predviden da radi sa niskim
c
c

prioritetom.
Svaki proces u sistemu se zato predstavlja jednim objektom koji pored
ostalih polja koja blie opisuju proces sadri jo dva polja: jedno celobrojno
polje za identikacioni broj procesa i jedno celobrojno polje za prioritet
procesa. Operativni sistem sa deljenjem vremena rasporeduje ove procese

radi izvravanja na osnovu njihovog prioriteta. Kada se u sistemu pokrene


novi proces koji treba izvriti, on najpre dobija svoj identikacioni broj i
prioritet. Ovaj proces se ne izvrava odmah, jer moda po svom prioritetu
to ne zasluuje, nego se dodaje u strukturu podataka reda svih procesa sa

prioritetima koji cekaju na izvravanje. Kada procesor postane besposlen,


ili kada proces koji se trenutno izvrava iskoristi svoj kvantum vremena,
operativni sistem odreduje proces najvieg prioriteta u redu procesa koji

cekaju na izvravanje i taj proces dodeljuje procesoru radi izvravanja.


Na osnovu ovog primera moe se zaklju iti da su osnovne operacije nad
c
redom sa prioritetima iste one koje se koriste za rad sa obi nim redovima
c

za cekanje ili stekovima. To su operacije dodavanja i uklanjanja elemenata,


s tom razlikom to se iz reda sa prioritetima uklanja element koji ima najmanji prioritet. (Podsetimo se da se kod obi nih redova uklanja najstariji
c
element, dok se kod stekova uklanja najnoviji element.)
Red sa prioritetima Q je dakle struktura podataka koja se sastoji od
skupa elemenata u kojem svaki element sadri polje klju a koje ozna ava
c
c
prioritet elementa reda. Dve osnovne operacije nad redom sa prioritetima

176

Stabla

Q su:
1. Operacija dodavanja pq-insert(Q,x) kojom se se u red sa prioritetima Q dodaje novi element x.
2. Operacija uklanjanja pq-deletemin(Q) kojom se u redu sa prioritetima Q najpre pronalazi element najnieg prioriteta, a zatim se taj
element uklanja iz reda Q i kao dodatni rezultat vra a se prioritet
c
tog najmanjeg elementa.
Jedan ekasan na in za implementaciju reda sa prioritetima je pomo u
c
c
binarnog hipa o kome smo govorili u odeljku 6.4. Osnovne operacije dodavanja i uklanjanja elemenata za red sa prioritetima odgovaraju bez izmena algoritmima heap-insert i heap-deletemin, odnosno operacijama
dodavanja i uklanjanja elemenata za binarni hip. Primetimo i da je vreme
izvravanja ovih operacija logaritamsko, odnosno O(log n) za red sa prioritetima od n elemenata.
U praksi je struktura podataka reda sa prioritetima obi no sloenija
c
zbog toga to treba obezbediti dodatne operacije za sloenije algoritme koji
koriste neki red sa prioritetima. Nepotpun spisak ovih dodatnih operacija
je:
pq-make(Q,a): formirati red sa prioritetima Q od datih elemenata u
nizu a.
pq-changekey(Q,x,p): promeniti prioritet datog elementa x u redu
sa prioritetima Q tako da bude jednak p.
pq-delete(Q,x): ukloniti dati proizvoljni element x iz reda sa prioritetima Q.
Ako se podsetimo strukture podataka binarnog hipa iz odeljka 6.4, moemo primetiti da se sve ove dodatne operacije mogu ekasno realizovati
ukoliko je red sa prioritetima predstavljen binarnim hipom u obliku niza.
Naime, da bismo konstruisali red sa prioritetima od datih elemenata, moemo iskoristiti algoritam heap-make koji se izvrava za linearno vreme.
Da bismo promenili prioritet datog elementa koji se nalazi negde unutar
binarnog hipa, moemo iskoristiti algoritam heap-siftdown za njegovo pomeranje nadole ako mu se prioritet pove ava, ili algoritam heap-bubbleup
c
za njegovo pomeranje navie ako mu se prioritet smanjuje. Da bismo uklonili proizvoljni element iz binarnog hipa, moemo primeniti postupak sli
can onom koji se koristi za uklanjanje minimalnog elementa. Obratite
panju na to da u svim ovim operacijama dolazi do zamenjivanja elemenata
du jednog puta u hipu, u najgorem slu aju od vrha hipa pa sve do njegovog
c

6.5. Primene stabala

177

dna ili obrnuto. To zna i da je vreme izvravanja ovih operacija takode


c

logaritamsko.

Disjunktni skupovi
U nekim primenama je potrebno da podaci budu organizovani u vie

grupa pri cemu su vane dve operacije: jedna kojom se odreduje kojoj grupi

pripada neki podatak i druga kojom se objedinjuju dve date grupe u jednu.
U tim slu ajevima dolazi do izraaja struktura podataka disjunktnih skuc
pova.
Apstraktna struktura podataka disjunktnih skupova predstavlja n elemenata grupisanih u kolekciju od najvie n disjunktnih skupova. Svaki
skup u kolekciji sadri dakle medusobno razli ite elemente koji su objekti
c

istog tipa. Ekasne operacije potrebne za rad sa ovom strukturom podataka su:
Konstruisanje skupa od jednog elementa. Operacijom ds-make(x)

se konstruie novi skup ciji je jedini clan dati element x. Poto su


skupovi u kolekciji disjunktni, podrazumeva se da se x ne nalazi ve
c
u nekom drugom skupu.
Odredivanje mati nog skupa. Operacijom ds-find(x) se dobija idenc

tikacija jedinstvenog skupa u kolekciji koji sadri dati element x.


Objedinjavanje dva skupa. Za data dva elementa x i y koji pripadaju
razli itim disjunktnim skupovima S x i S y u kolekciji, operacijom
c
ds-union(x,y) objedinjuju se skupovi S x i S y u jedan novi skup
koji predstavlja njihovu uniju. Preciznije, formira se tre i skup S z
c
takav da je S z = S x S y , a kako skupovi u kolekciji moraju biti
disjunktni, skupovi S x i S y se uklanjaju iz kolekcije nakon njihovog
objedinjavanja.
Primenom operacije odredivanja mati nog skupa datog elementa kao
c

rezultat se dobija identikacija (ili ime) tog skupa. Ta na priroda idenc


tikacije skupova u kolekciji disjunktnih skupova je prili no eksibilna
c
pod uslovom da je dosledna. To zna i da rezultat operacija ds-find(x) i
c
ds-find(y) mora biti jednak ukoliko elementi x i y pripadaju istom skupu,
a razli it u suprotnom slu aju. Obi no se svaki skup u kolekciji identikuje
c
c
c

nekim svojim clanom koji se naziva predstavnik tog skupa.

178

Stabla

Predstavljanje disjunktnih skupova pomocu stabala. Jedan ekasan na in za predstavljanje disjunktnih skupova je pomo u kolekcije (opc
c

tih) korenskih stabala, pri cemu svaki cvor stabla predstavlja jednog clana
nekog skupa i svako stablo predstavlja jedan skup iz kolekcije. U svakom

stablu ove reprezentacije jedan cvor sadri, pored elementa skupova koga
predstavlja, jo samo pokaziva na svog roditelja. Skup koga neko stablo
c
predstavlja identikuje se preko predstavnika koji se nalazi u korenu tog
stabla. Na slici 6.27 je ilustrovana ovakva reprezentacija za kolekciju
disjunktnih skupova {a, b, c, d }, { e, f , g}, { h, i, j } i { k}.

e
c

h
i

k
j

S LIKA 6.27: Disjunktni skupovi predstavljeni kolekcijom stabala.


Tri karakteristi ne operacije za rad sa disjunktnim skupovima predstac
vljenim kolekcijom stabala mogu se algoritamski realizovati se na slede i
c
na in:
c
c
U algoritmu ds-make(x) se za dati objekat x sa odgovaraju im ele
mentom skupa prosto konstruie jedan cvor stabla.

c
U algoritmu ds-find(x) se prate roditeljski pokaziva i od cvora x
dok se ne dode do korena stabla. Za identikaciju (predstavnika)

mati nog skupa cvora x vra a se kao rezultat element koji se nalazi
c
c
u korenu stabla.
U algoritmu ds-union(x,y) se objedinjuju dva disjunktna skupa
predstavljena pomo u dva stabla sa korenima x i y tako to se koren
c
stabla manje visine vezuje za koren stabla ve e visine. Drugim rec

cima, koren stabla ve e visine postaje roditeljski cvor za koren stabla


c
manje visine. (U slu aju dva stabla iste visine proizvoljno se bira
c

koren jednog stabla da bude roditeljski cvor drugog.) Ovaj na in


c
objedinjavanja stabala naziva se objedinjavanje po visini.
Ovaj neformalni opis algoritamske realizacije operacija za rad sa dis
junktnim skupovima pokazuje da svakom cvoru u stablima kolekcije treba

6.5. Primene stabala

179

pridruiti informaciju o njegovoj visini. Zbog toga svaki cvor x sadri ce

lobrojno polje h za visinu tog cvora. Pored toga, svaki cvor x sadri polje
klju u kome se nalazi odgovaraju i element skupa, kao i polje p u kome
c
c

se nalazi pokaziva na roditelja cvora x. Naravno, ovo pokaziva ko polje


c
c
korena svakog stabla sadri vrednost null.

c
Kada se operacijom ds-make konstruie stablo od jednog cvora, po etna

visina tog cvora je 0. Operacijom ds-find se visine cvorova stabla uopte


c
ne menjaju. Kod primene operacije ds-union mogu se desiti dva slu aja
zavisno od visina korena stabala koja se objedinjuju. U prvom slu aju u
c
kojem ovi koreni imaju nejednake visine, koren ve e visine postaje roditelj
c
korena manje visine, ali same visine ostaju nepromenjene. U drugom
slu aju u kojem ovi koreni imaju jednake visine, proizvoljno se bira jedan
c
od korena da bude roditelj drugog, ali se njegova visina uve ava za jedan.
c
// Ulaz: objekat x sa odgovarajuim elementom skupa
c
// Izlaz: vor x stabla u kolekciji stabala
c
algorithm ds-make(x)
x.h = 0;
x.p = null;
return x;

// Ulaz: vor x u kolekciji stabala


c
// Izlaz: predstavnik (identifikacija) skupa koji sadri element x
algorithm ds-find(x)
while (x.p != null) do
x = x.p;
return x;

// Ulaz: koreni x i y dva stabla u kolekciji stabala


// Izlaz: stablo koje objedinjuje stabla koja sadre x i y
algorithm ds-union(x, y)
if (x.h > y.h) then
y.p = x;
return x;
// x je koren rezultujueg stabla
c
else
x.p = y;
if (x.h == y.h) then
y.h = y.h + 1;
return y;
// y je koren rezultujueg stabla
c

180

Stabla

Algoritmi ds-make i ds-union o evidno se izvravaju za konstantno


c
vreme. Poto vreme izvravanja algoritma ds-find zavisi od visina stabala u kolekciji, pokaza emo da visina nekog stabla moe rasti najvie
c

logaritamski u odnosu na broj cvorova u tom stablu. Zbog toga kada se

prelazi put od nekog cvora u stablu do njegovog korena radi nalaenja


predstavnika odgovaraju eg skupa, vreme izvravanja tog postupka je proc

porcionalno najvie logaritmu broja cvorova u datom stablu. Ova logaritamska granica visine nekog stabla u kolekciji stabala koja predstavljaju
disjunktne skupove preciznije se izraava na slede i na in.
c
c
c
L EMA Neka je T jedno stablo u kolekciji stabala koje je po etno konstruisano algoritmom ds-make i zatim formirano (viestrukom) primenom algoritma ds-union. Ako je visina stabla T jednaka h, onda T ima bar 2h
cvorova.

Dokaz: U dokazu koristimo indukciju po h. Bazni slu aj h = 0 je o iglec


c

dan, jer stablo mora imati samo jedan cvor i 20 = 1. Pretpostavimo da je


tvrdenje leme ta no za neko h 0 i posmatrajmo stablo T u kolekciji koje
c

ima visinu h +1. U nekom trenutku tokom formiranja stabla T operacijama


objedinjavanja po visini, visina tog stabla je prvi put dostigla vrednost h+1.
Jedini na in na koji je moglo da se tada dobije stablo visine h + 1 je da
c
je jedno stablo T1 visine h postalo dete korena drugog stabla T2 jednake
visine h. Stablo T se sastoji dakle od stabala T1 i T2 , i moda nekih drugih
stabala koja su dodata kasnije. Izgled stabla T je ilustrovan na slici 6.28.
T

T2

T1

S LIKA 6.28: Stablo T visine h + 1 obrazovano operacijama objedinjavanja


po visini.

Stabla T1 i T2 po indukcijskoj pretpostavci imaju bar po 2h cvorova. S

vorove stabala T1 i T2 , i moda dodatne cvorove,


obzirom na to da T sadri c
h
h
h +1
cvorova. Ovim je dokazan indukcijski
T mora imati bar 2 + 2 = 2
korak, a time i tvrdenje leme.

6.5. Primene stabala

181

Na osnovu ovog zapaanja sledi da ako neko stablo u kolekciji sta


bala koja predstavljaju disjunktne skupove ima m cvorova i visinu h, onda
mora biti m 2h . Logaritmovanjem obe strane ove nejednakosti dobijamo

h log m. Stoga vreme potrebno za prelaenje puta od nekog cvora u


tom stablu do njegovog korena je O(log m). Prema tome, ako kolekcija
disjunktnih skupova sadri ukupno n elemenata, onda je naravno m n,
pa je vreme izvravanja algoritma ds-find jednako O(log n).

Zadaci
1. Odogovorite na slede a pitanja u vezi sa stablom na slici 6.29.
c

a) Koji cvorovi su listovi?

b) Koji cvor je koren?

c) Koji cvor je roditelj cvora C?

d) Koji cvorovi su deca cvora C?

e) Koji cvorovi su preci cvora E?

f) Koji cvorovi su potomci cvora E?

g) Koja je dubina cvora C?

h) Koja je visina cvora C?


A
B
D

C
E

F
J

I
M

H
K

S LIKA 6.29.

2. Navedite listu cvorova stabla na slici 6.29 u preorder, inorder i postoder


redosledu.
3. Nacrtajte reprezentaciju izraza (a + b) + c (d + e) + f (g + h) u obliku
stabla.

182

Stabla

4. Napiite i analizirajte algoritam za izra unavanje dubine cvora v u stac


blu T.
5. Pokaite da je visina stabla T jednaka maksimalnoj dubini nekog lista
u stablu T.
6. Dokaite slede a tvrdenja o stablima:
c

a) Svako stablo sa n cvorova ima n 1 grana.


b) Stepen cvora u stablu je broj njegove dece. U svakom binarnom

stablu je broj listova za jedan ve i od broja cvorova stepena dva.


c

c) Binarno stablo je pravilno binarno stablo ako svaki cvor ima nula

ili dvoje dece. Ako takvo stablo ima n cvorova koji nisu listovi,
tada ono ima n + 1 list. Dakle, svako pravilno binarno stablo ima

neparan broj cvorova.


d) Podsetimo se da puno binarno stablo ima listove samo na posled
njem nivou, a svaki cvor koji nije list ima ta no dvoje dece. Ako
c
je visina punog binarnog stabla jednaka h, tada je broj njegovih

cvorova jednak 2h+1 1.


7. Ako je binarno stablo predstavljeno na standardan na in pokaziva ima
c
c

na cvorove, napiite i analizirajte algoritme za preorder i postorder obi


laske cvorova binarnog stabla.
8. Za svaku od slede ih sekvenci klju eva odredite binarno stablo pretrage
c
c
koje se dobija kada se ti klju evi dodaju po etno praznom stablu, redom
c
c
jedan po jedan u datom redosledu.
a) 1, 2, 3, 4, 5, 6, 7.
b) 4, 2, 1, 3, 6, 5, 7.
c) 1, 6, 7, 2, 4, 3, 5.
9. Za svako od binarnih stabla pretrage dobijenih u prethodnom zadatku
odredite binarno stablo pretrage koje se dobija kada se ukloni koren.
10. Pretpostavimo da je dat sortiran niz od n klju eva x1 x2 xn i,
c
radi jednostavnosti, pretpostavimo da je n jednak stepenu broja 2.

6.5. Primene stabala

183

a) Koja je minimalna visina binarnog stabla sa n cvorova?


b) Napiite algoritam za konstruisanje binarnog stabla pretrage od
datih klju eva koji se redom dodaju u njega tako da visina dobijec
nog stabla bude minimalna.
c) Koje je vreme izvravanja tog algoritma?
11. U standardnoj reprezentaciji binarnog stabla pretrage pomo u pokac

ziva a, pretpostavimo da svaki njegov cvor dodatno sadri pokaziva


c
c
na svog roditelja. Napiite algoritam bst-successor(t,v) koji kao
rezultat vra a cvor sa klju em koji je prvi slede i iza klju a cvora v u
c
c
c
c
sortiranom rastu em redosledu svih klju eva binarnog stabla pretrage
c
c

T. Koje je vreme izvravanja tog algoritma? (Savet: Sledbenik cvora

v je minimalni cvor u desnom podstablu cvora v, ako ono postoji; u

suprotnom slu aju, to je najnii (prvi) predak cvora v cije je levo dete
c

takode predak cvora v.)

12. Pod istim pretpostavkama kao u prethodnom zadatku, napiite ekac


san algoritam bst-predecessor(t,v) koji kao rezultat vra a cvor sa
klju em koji je prvi prethodni ispred klju a cvora v u sortiranom rastuc
c

cem redosledu svih klju eva binarnog stabla pretrage T. Koje je vreme
c
izvravanja tog algoritma?
13. Napiite ekasan algoritam koji odreduje k-ti najmanji klju u binarc

nom stablu pretrage. Na primer, ako je dato binarno stablo pretrage sa

c
n cvorova, za k = 1 treba odrediti najmanji klju , za k = n treba odrediti
c
najve i klju , a za k = n/2 treba odrediti klju u sredini sortirane liste
c
c
klju eva u rastu em redosledu.
c
c
14. Za svaku od slede ih sekvenci klju eva odredite binarni hip koji se doc
c
bija kada se ti klju evi dodaju po etno praznom hipu, redom jedan po
c
c
jedan u datom redosledu.
a) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
b) 3, 1, 4, 1, 5, 9, 2, 6, 5, 4.
c) 2, 7, 1, 8, 2, 8, 1, 8, 2, 8.
15. Za svako od binarnih hipova dobijenih u prethodnom zadatku odredite

binarni hip koji se dobija kada se ukloni njegov minimalni cvor.

184

Stabla

16. Pretpostavljaju i da je hip predstavljen pomo u niza, napiite algoritam


c
c
koji nalazi najve i klju u min-hipu. Koje je vreme izvravanja tog
c
c
algoritma? (Savet: Najpre pokaite da najve i klju u min-hipu mora
c
c
biti jedan od listova.)
17. Pretpostavimo da se za sortiranje niza neuredenih brojeva a 1 , a 2 , . . ., a n

u rastu em redosledu koristi algoritam u kome se redom izvravaju


c
slede e dve faze:
c

1. Faza dodavanja: Redom dodati cvorove sa klju evima a 1 , a 2 , . . ., a n


c
u po etno prazno binarno stablo pretrage.
c
2. Faza listanja:

Izlistati klju eve cvorova zavrnog stabla.


c

a) U kojem redosledu treba izlistati cvorove u drugoj fazi ovog algoritma preorder, inorder ili postorder?
b) Koliko je vreme izvravanja za fazu listanja?
c) Ako je ulazni niz brojeva ve sortiran, koliko je ukupno vreme
c
izvravanja ovog algoritma?
d) Ako se koristi binarni hip umesto binarnog stabla pretrage, koliko
je vreme izvravanja za fazu dodavanja ovog algoritma?
e) Kako treba modikovati fazu listanja u slu aju binarnog hipa?
c
f) Koliko je vreme izvravanja za ovu modikovanu fazu listanja?
18. Napiite algoritam heap-sort(a,n) kojim se niz a od n neuredenih

brojeva sortira u rastu em redosledu kori enjem strukture podataka


c
c
binarnog hipa. Koliko je vreme izvravanja ovog na ina sortiranja niza?
c
19. Implementirajte operacije nad redom sa prioritetima o kojima smo govorili na strani 176. Konkretno, ukoliko je red sa prioritetima Q predstavljen pomo u binarnog min-hipa u obliku niza, na pseudo jeziku nac
piite algoritme:
pq-insert(Q,x)
pq-deletemin(Q)
pq-make(Q,a)
pq-changekey(Q,x,p)
pq-delete(Q,x)

G LAVA

7
Grafovi

U raznim primenama cesto treba predstaviti neke objekte i uzajamne


odnose koji postoje izmedu tih objekata. Grafovi su prirodan model za

takvu reprezentaciju. Jedan primer je auto-karta na kojoj se gradovi predstavljaju ta kama, a medusobni odnos povezanosti tih gradova putevima
c

predstavlja se linijama koje povezuju odgovaraju e ta ke. Drugi primer je


c
c

lokalna mrea ra unara u kojoj se pojedini ra unari predstavljaju cvoroc


c
vima, a direktni zi ki linkovi izmedu ra unara predstavljaju se linijama
c
c

koje povezuju odgovaraju e cvorove. U stvari, skoro u svim oblastima svac


c
kodnevnog ivota nailazimo na grafove, dodue ce e pod imenom mree:
transportne mree, komunikacione mree, informacione mree, socijalne
mree i tako dalje. Nije daleko od istine konstatacija da to se vie radi sa
grafovima, to se sve vie grafovi prepoznaju u svemu.
Zbog svoje iroke prakti ne primene, grafovi su sveprisutni model poc
dataka u ra unarstvu, a algoritmi sa grafovima su osnovni gradivni elec
menti sloenijih algoritama. Iako grafovi matemati ki predstavljaju obi ne
c
c
binarne relacije, oni se skoro uvek vizuelno predstavljaju pomo u skupa
c
ta aka povezanih linijama ili strelicama. U tom smislu je grafovski model
c
podataka uoptenje strukture podataka stabla koju smo izu avali u poglac
vlju 6.
U ovom poglavlju se najpre deniu osnovni pojmovi koji se odnose na
grafove. Zatim se govori o nekoliko elementarnih grafovskih algoritama
koji su zna ajni u primenama grafova. O sloenijim grafovskim algoritc

mima ce biti vie re i na kraju ovog poglavlja, kao i u celom narednom


c
poglavlju.

186

Grafovi

7.1 Osnovni pojmovi i denicije


Povezane strukture podataka o kojima smo do sada govorili, kao to

su liste i korenska stabla, sastoje se od cvorova koji se povezuju na ta no


c
odreden na in. Na primer, binarna stabla pretrage imaju oblik koji je
c

diktiran na inom na koji se obavljaju operacije pretrage, dodavanja i uklac

njanja cvorova u tim stablima. Medutim, priroda mnogih vanih problema

zahteva optiju strukturu koja se sastoji od kolekcije cvorova povezanih na


proizvoljan na in. Te strukture se nazivaju grafovi.
c

Graf se dakle sastoji od skupa cvorova i skupa grana koje povezuju neke

od tih cvorova. Grafovi se neformalno cesto predstavljaju dijagramima u

kojima se cvorovi prikazuju krui ima, a grane se prikazuju linijama (ili


c
strelicama) koje spajaju odgovaraju e krui e. Na slici 7.1 je prikazan
c
c
graf koji predstavlja ve e gradove u Srbiji i njihovu povezanost glavnijim
c
putevima.
SU

NS
ZR

BG

SD
PO
VA
KG
K

CA

NI
KV

S LIKA 7.1: Graf gradova u Srbiji povezanih glavnijim putevima.

Formalno, graf G se sastoji od skupa cvorova V i skupa grana E, pri

cemu svaka grana iz E spaja dva cvora iz V . Graf se ozna ava zapisom
c

G = (V , E) da bi se ukazalo da su V skup cvorova i E skup grana u grafu

G. Svaka grana e u E je dakle dvoelementni podskup cvorova iz V koje


vorove u i v iz V . Za cvorove u i v koje

spaja, odnosno e = { u, v} za neke c

spaja grana e kaemo da su susedni cvorovi ili da je grana e incidentna

cvorovima u i v. Na primer, graf G gradova u Srbiji povezanih putevima

7.1. Osnovni pojmovi i denicije

187

na slici 7.1 sastoji se od skupa V sa 13 cvorova:

V = {BG, NS, NI, KG, SD, PO, VA, CA, KV, K, A, ZR, SU} ,
kao i skupa E sa 23 grane:

E = {BG, NS}, {BG, VA}, {BG, NI}, {KG, CA}, . . . .

Broj grana nekog cvora v koje ga spajaju sa drugim cvorovima grafa

je stepen cvora v. Cvorovi na drugom kraju tih incidentnih grana cvora v

nazivaju se susedi cvora v. Druga ije re eno, stepen nekog cvora je broj
c
c

njegovih suseda. Na primer, u grafu na slici 7.1 stepen cvora BG je 9, a

stepen cvora SU je 1.
U stvari, prethodne denicije se odnose na neusmerene grafove kao to
je to graf na slici 7.1. Kod takvih grafova grane ozna avaju simetri an
c
c

odnos izmedu cvorova na njihovim krajeva. Sa druge strane, cvorovi cesto



stoje u asimetri nom odnosu i za takve slu ajeve se koriste usmereni grac
c

fovi. Na dijagramima usmerenih grafova se grane koje spajaju dva cvora

prikazuju strelicama od jednog do drugog cvora da bi se ukazalo na njihov


asimetri an odnos. Na slici 7.2 je prikazan primer jednog usmerenog grafa.
c
a

S LIKA 7.2: Usmeren graf.

Formalno, usmeren graf G = (V , E) se sastoji od skupa cvorova V i


skupa usmerenih grana E. Svaka usmerena grana e u E je ureden par

dva cvora iz V koje spaja, odnosno e = (u, v) za neke cvorove u i v iz V .

Drugim re ima, uloga cvorova u i v nije zamenjiva u usmerenoj grani e, pa


c

se cvor u zove po etak i cvor v se zove kraj grane e. Isto tako, u slu aju
c
c

grane e = (u, v), cvor v jeste sused cvora u, ali u nije sused cvora v. Na

primer, graf G na slici 7.2 sastoji se od skupa V sa 4 cvora:


V = {a, b, c, d } ,
kao i skupa E sa 7 usmerenih grana:
E = (a, b), (a, c), (a, d), (b, b), (c, b), (c, d) (d, a) .

188

Grafovi

Obratite panju na to da usmerena grana u usmerenom grafu moe

imati po etak i kraj u istom cvoru. Takva jedna grana, koja se naziva
c

petlja, u grafu na slici 7.2 je grana kod cvora b. Sa druge strane, petlje u
neusmerenim grafovima nisu dozvoljene, jer grana u neusmerenom grafu

mora biti podskup od dva razli ita cvora.


c
Kod usmerenih grafova se razlikuje izlazni stepen i ulazni stepen nekog

cvora v: izlazni stepen je broj usmerenih grana koje izlaze iz cvora v i

ulazni stepen je broj usmerenih grana koje ulaze u cvor v. Stepen cvora u

usmerenom grafu je zbir njegovog izlaznog i ulaznog stepena, pri cemu se


petlja broji dvaput.
Nije teko primetiti da se svaki neusmeren graf moe smatrati ekvi

valentnim jednom usmerenom grafu koji ima isti skup cvorova i ciji se
skup grana dobija tako to se svaka grana { u, v} u neusmerenom grafu
zameni dvema usmerenim granama (u, v) i (v, u). Teorijski dakle neusmereni grafovi su specijalan slu aj usmerenih grafova, pa je dovoljno poc
smatrati samo optije usmerene grafove. Uprkos tome u ovoj knjizi, radi

jednostavnosti, uglavnom govorimo o neusmerenim grafovima i zato cemo


pod kra im izrazom graf podrazumevati neusmeren graf ukoliko nije
c
druga ije naglaeno.
c

Putevi i povezanost. Jedna od osnovnih operacija u grafu je prolazak

kroz niz cvorova povezanih granama. Uzmimo na primer graf kojim se

moe predstaviti neki veb sajt. U tom grafu cvorovi odgovaraju pojedina c
nim veb stranama i postoji grana izmedu cvora u i v ako u ima hiperlink na

v. U takvom grafu jedna operacija prolaska kroz cvorove odgovara na inu


c
na koji neki korisnik pregleda veb sajt prate i hiperlinkove.
c
Prethodna operacija se formalizuje pojmom puta u grafu. Put u neu
smerenom grafu G = (V , E) je niz P cvorova v1 , v2, . . ., vk1 , vk takvih da je

svaki susedan par cvorova v i , v i+1 u tom nizu spojen granom u G. Duina

puta P je broj grana na tom putu, odnosno k 1. Za put P se cesto kae

da je to put koji ide od cvora v1 do cvora vk , ili da je to v1 vk put. Na

slici 7.1, niz cvorova BG, CA, VA, BG, NS obrazuje put duine 4 od cvora

BG do cvora NS.

Put u grafu je prost ako su svi cvorovi na tom putu medusobno razli iti.
c

Ciklus je put v1 , v2 , . . ., vk1 , vk takav da je k > 2, prvih k 1 cvorova su


c
medusobno razli iti i v1 = vk . Drugim re ima, ciklus u grafu je zatvoren
c

prost put ne ra unaju i prvi i poslednji cvor. Graf koji nema nijedan ciklus
c
c
se naziva acikli ki graf.
c

7.1. Osnovni pojmovi i denicije

189

Sve ove denicije se prirodno prenose na usmerene grafove, uz jednu

izmenu: u putu ili ciklusu svi parovi susednih cvorova moraju biti povezani

usmerenim granama ciji se smer mora potovati izmedu susednih cvorova

u putu ili ciklusu. Na primer, niz cvorova a, d, a, c, b, b na slici 7.2 obrazuje

put duine 5 od cvora a do cvora b.


Za graf H = (V , E ) kaemo da je podgraf grafa G = (V , E) ukoliko je

c
V V i E E. Drugim re ima, graf H je podgraf grafa G ako su cvorovi

grafa H podskup cvorova grafa G, a grane grafa H su podskup grana grafa

G koje su incidentne cvorovima u H. Na slici 7.3 je prikazan primer grafa


i jedan od njegovih podgrafova.
1

S LIKA 7.3: Graf i jedan od njegovih podgrafova.

Neusmeren graf G je povezan ukoliko G ima samo jedan cvor (i nijednu

granu) ili za svaki par cvorova u i v u G postoji neki put od u do v. Primetimo da ovo ne zna i da u povezanom grafu postoji grana izmedu svaka dva
c

cvora, ve samo da postoji put (mogu e duga ak) izmedu njih. Primetimo i
c
c
c

da ako postoji u-v put u neusmerenom grafu, onda postoji i v-u put u tom

grafu koji se sastoji od obrnutog niza cvorova u-v puta. Graf na slici 7.1
je primer jednog povezanog grafa. Sa druge strane, graf na slici 7.4 nije
povezan graf, jer ne postoji nijedan put, recimo, izmedu cvorova 1 i 6.

G
1
6

S LIKA 7.4: Nepovezan graf.


Nepovezan graf na slici 7.4 se o igledno sastoji od dva povezana dela. Ti
c
delovi se nazivaju povezane komponente grafa (ili kra e samo komponente)
c

190

Grafovi

koje predstavljaju maksimalne povezane podgrafove.1 Primetimo da se u

neusmerenom grafu svaki cvor nalazi u ta no jednoj od njegovih povezanih


c
komponenti.
Denicija povezanosti usmerenih grafova nije tako prosta kao za neu

smerene grafove, jer je mogu e da postoji put od cvora u do cvora v, ali ne


c

i obrnut put od cvora v do cvora u. Zbog toga kaemo da je usmeren graf

jako povezan ukoliko za svaka dva cvora u i v postoji put od u do v i put


od v do u. Na primer, usmeren graf na slici 7.2 nije jako povezan, jer ne

postoji nijedan put, recimo, od cvora B do cvora A.

Slobodna stabla. Povezan graf koji nema nijedan ciklus naziva se slobodno stablo. Slobodna stabla se razlikuju od korenskih stabala o kojima
smo govorili u poglavlju 6 jedino po tome to su kod slobodnih stabala svi

cvorovi ravnopravni, odnosno slobodna stabla nemaju jedan poseban cvor


koji se zove koren.
Neko slobodno stablo se lako moe transformisati u korensko stablo

ukoliko se najpre izabere proizvoljni cvor za koren i zatim se poveu svi

cvorovi na drugom kraju svih grana koje idu od tog korena, zatim poveu

svi cvorovi svih grana koje idu od prethodnih cvorova (dece korena) i tako
dalje. Slikovitiji na in za razumevanje ovog postupka je da zamislimo da
c

grane u slobodnom stablu predstavljaju konce kojima su povezani cvorovi


i da se to stablo podigne da visi u vazduhu dre i ga za izabrani koren.
c
Tako, na primer, dva crtea na slici 7.5 predstavljaju zapravo isto stablo, tj.

isti parovi cvorova su spojeni granama, ali crte na levoj strani je slobodno
stablo i crte na desnoj strani je to stablo transformisano u korensko stablo

sa cvorom 1 kao korenom.


3
1
4

7
2

1
6

S LIKA 7.5: Transformacija slobodnog stabla u korensko stablo.


1 Komponenta grafa je maksimalna u smislu da nije pravi podgraf nijednog drugog
povezanog podgrafa datog grafa.

7.2. Predstavljanje grafova

191

U pravom smislu re i stabla su najprostija vrsta povezanih grafova,


c
jer uklanjanjem bilo koje grane iz stabla ono postaje nepovezano. Graf

koji se sastoji od vie stabala, ta nije graf cije sve povezane komponente
c
predstavljaju slobodna stabla sama za sebe, naziva se uma. Na slici 7.6 je
prikazan primer grafa G koji je uma.
G
1

10

S LIKA 7.6: uma.

7.2

Predstavljanje grafova

Da bi se grafovi mogli ekasno koristiti u ra unaru, moraju se predc

staviti u programima na na in koji obezbeduje lako manipulisanje cvoroc

vima i granama grafova. Najprostija struktura podataka koja se koristi za


predstavljanje grafova je matrica susedstva. Matrica susedstva je obi an
c

dvodimenzionalni niz ciji su brojevi redova i kolona jednaki broju cvorova


grafa. Obratite panju na to da za matricu susedstva grafa nisu bitne

oznake cvorova u grafu kojim su oni obeleeni, ve je bitan samo njihov


c
ukupan broj.

Matrica susedstva za usmeren graf G = (V , E) od n cvorova koji su


numerisani u proizvoljnom redosledu tako da je V = {v1 , . . ., vn } jeste dakle

n n matrica a takva da je a i, j = 1 ako postoji usmerena grana od cvora


vora v j , a u suprotnom slu aju je a i, j = 0. Na slici 7.7 je prikazan
c
v i do c
primer usmerenog grafa i njegova matrica susedstva.
Matrica susedstva za neusmeren graf se obrazuje na sli an na in tako
c
c

to se jedna neusmerena grana izmedu dva cvora predstavlja zapravo dve


ma usmerenim granama jednom usmerenom granom od prvog do drugog

cvora i drugom usmerenom granom od drugog do prvog cvora. To zna i da


c
je matrica susedstva neusmerenog grafa simetri na, odnosno a i, j = a j,i za
c
svako i i j. Pored toga, za matricu susedstva neusmerenog grafa vai da
je a i,i = 0 za svako i, jer neusmeren graf ne sadri grane-petlje od nekog

192

Grafovi

1
2
3
4
5

1
0
0
1
0
0

2
1
0
1
0
1

3
1
0
0
0
0

4
0
1
0
0
0

5
0
0
1
1
0

S LIKA 7.7: Usmeren graf i njegova matrica susedstva.

cvora do istog cvora. Na slici 7.8 je prikazan primer neusmerenog grafa i


njegova matrica susedstva.
1

1
2
3
4

1
0
1
1
0

2
1
0
1
1

3
1
1
0
1

4
0
1
1
0

S LIKA 7.8: Neusmeren graf i njegova matrica susedstva.


Ako se koristi reprezentacija grafa (usmerenog ili neusmerenog) pomo u matrice susedstva, vreme pristupa bilo kom elementu matrice je konc

stantno, odnosno to vreme ne zavisi od broja cvorova i grana grafa. Zbog


toga je ovakva reprezentacija pogodna u slu ajevima kada se u algoritmu
c

cesto proverava da li neka grana postoji ili ne u grafu.


Glavni nedostatak matrice susedstva za predstavljanje grafova je u

tome to matrica susedstva za graf od n cvorova zahteva veli inu memorijc


2
skog prostora (n ), cak i za grafove sa malim brojem grana. Zbog toga
vreme potrebno samo za formiranje cele matrice susedstva grafa iznosi

(n2 ), cime se automatski ne mogu dobiti algoritmi bri od (n2 ) za rad


sa retkim grafovima sa, recimo, n grana. Graf je redak ukoliko je njegov
broj grana mali deo od najve eg mogu eg broja grana. Nije teko proveriti
c
c

da najve i broj grana za usmeren graf sa n cvorova iznosi n2 , dok je taj broj
c
za neusmeren graf jednak n(n 1)/2.
Da bi se reio ovaj problem za retke grafove, koristi se alternativna
reprezentacija grafova pomo u listi susedstva. Ova reprezentacija ima nec
koliko varijacija, a u najprostijem obliku se graf predstavlja jednim nizom

povezanih listi susedstva za svaki cvor grafa. Lista susedstva za cvor v je

7.2. Predstavljanje grafova

193

lista svih cvorova koji su susedni cvoru v u grafu, u nekom redosledu.

Usmeren graf G = (V , E) sa skupom cvorova V = {v1 , . . ., vn } moe se

tako predstaviti pomo u jednog niza a veli ine n, pri cemu element a i
c
c

sadri pokaziva na listu susedstva cvora v i . Na slici 7.9 je ilustrovana


c
reprezentacija usmerenog grafa nizom listi susedstva.
a
1

2
3

S LIKA 7.9: Usmeren graf predstavljen listama susedstva.


Neusmeren graf se listama susedstva predstavlja na sli an na in tako
c
c
to se jedna neusmerena grana predstavlja dvema usmerenim granama.
Na slici 7.10 je ilustrovana reprezentacija neusmerenog grafa nizom listi
susedstva.
a

1
2

S LIKA 7.10: Neusmeren graf predstavljen listama susedstva.

Nije teko proveriti da je za predstavljanje grafa od n cvorova i m


grana nizom listi susedstva potreban memorijski prostor veli ine (n + m).
c

Naime, niz kojim se predstavljaju cvorovi grafa o igledno zauzima mec

morijski prostor veli ine (n). Duine listi susedstva zavise od cvora do
c

cvora i jednake su broju suseda (stepenu) pojedinih cvorova. Ali primetimo

da, ako je n u broj suseda cvora u, onda je uV n u = 2m. Naime, svaka


c
c
grana e = { u, v} se ra una ta no dvaput u ovom zbiru: jednom za n u i
jednom za n v . Poto je ovaj zbir jednak ukupnom broju puta koliko se

194

Grafovi

ra una svaka grana, taj zbir je 2m. Drugim re ima, ukupna duina svih
c
c
listi susedstva je 2m, odnosno memorijski prostor za sve liste susedstva je
veli ine (2m) = (m).
c
Veli ina memorijskog prostora (n + m) za niz listi susedstva je mnogo
c
c
manja od (n2 ) za matricu susedstva u slu aju retkih grafova. Sa druge
strane, treba imati u vidu da potencijalni nedostatak reprezentacije nizom
listi susedstva moe biti vreme od (n) koje je potrebno za proveravanje

da li postoji odredena grana izmedu dva cvora, jer moe biti (n) cvorova

u listi susedstva za bilo koji cvor.

7.3 Obilazak grafa

U poglavlju 6 smo upoznali tri na ina za obilazak binarnog stabla poc

mo u kojih se svi cvorovi nekog stabla mogu sistemati no posetiti kretac


c

njem du grana stabla od cvora do cvora. Kod grafova se sli an problem


c
tradicionalno naziva pretraga grafova i reava se primenom dva metoda
koji se nazivaju pretraga u irinu i pretraga u dubinu. Zna aj ovih postuc
paka pretrage grafova je u tome to se na njima zasnivaju mnogi algoritmi
za reavanje prakti nih problema koji se prirodno predstavljaju grafovima.
c
Jedan od takvih osnovnih algoritamskih problema za graf je pitanje

povezanosti dva cvora. Za graf G i dva njegova konkretna cvora s i t,


problem s-t povezanosti sastoji se u nalaenju ekasnog algoritma koji

daje odgovor na slede e pitanje: da li postoji put u grafu G od cvora s


c

do cvora t? Ovo prosto pitanje o tome da li postoji put izmedu dva cvora

moe se proiriti pitanjem da li postoji kratak put izmedu njih. Naime, u

mnogim primenama grafova potrebno je prona i put izmedu dva cvora koji
c

ima najmanje skokova. Kod transportnih ili komunikacionih mrea, na


primer, vrlo je vano znati najkra i put izmedu dve ta ke.
c
c

Zbog toga se uvodi pojam rastojanja izmedu dva cvora u grafu koje

se denie da bude duina najkra eg puta izmedu njih. (Ako ne postoji


c

nijedan put izmedu dva cvora, za njihovo rastojanje se obi no uzima da je


c

beskona no.) Primetimo da pojam rastojanja u grafovima ne mora odgoc

c
varati geografskom zna enju tog pojma dva cvora mogu biti na kratkom
rastojanju u grafu iako predstavljaju ta ke koje geografski mogu biti vrlo
c
udaljene.

7.3. Obilazak grafa

195

Pretraga u irinu
Moda najprostiji algoritam za odredivanje s-t povezanosti u grafu je

pretraga u irinu grafa (engl. breadth-rst search, BFS). Taj postupak je

dobio svoje ime po tome to se, polaze i od cvora s, ide to ire u grafu
c

pose ivanjem cvorova u svim mogu im pravcima u irinu.


c
c

Preciznije, za dati graf G = (V , E) i njegov cvor s, polazi se od cvora s i

u svakoj fazi pretrage u irinu cvorovi se otkrivaju u talasima. Prvi talas

se sastoji od svih cvorova koji su spojeni granom sa cvorom s. Drugi talas

se sastoji od svih novih cvorova koji su spojeni granom sa nekim cvorom

iz prvog talasa. Tre i talas se sastoji od svih novih cvorova koji su spojeni
c

granom sa nekim cvorom iz drugog talasa. Ovaj postupak se nastavlja na

o igledan na in sve dok se ne moe otkriti nijedan novi cvor. Na primer, na


c
c

slici 7.11 su prikazani talasi cvorova koji se otkrivaju pretragom u irinu

datog grafa ukoliko je po etni cvor 1.


c
G
Talas W0 : 1

1
3

2
5
8

6
9

11

Talas W1 : 2, 3, 4

4
7
10

Talas W2 : 5, 6
Talas W3 : 8, 9, 10, 7
Talas W4 : 11

S LIKA 7.11: Talasi pretrage u irinu grafa G od po etnog cvora 1.


c

Talasi cvorova W0 , W1 , W2 , . . . koji se redom dobijaju pretragom u irinu


mogu se preciznije denisati na slede i na in:
c
c

c
Talas W0 se sastoji od po etnog cvora s.

Talas Wi+1 za i 0 sastoji se od svih cvorava koji ne pripadaju nekom

prethodnom talasu i koji su povezani granom sa nekim cvorom u


talasu Wi .

Kako je rastojanje izmedu dva cvora najmanji broj grana na nekom

putu izmedu njih, primetimo da je talas W1 skup svih cvorova na rastojanju

1 od cvora s, da je talas W2 skup svih cvorova na rastojanju 2 od cvora s i

196

Grafovi

optije, da je talas Wi skup svih cvorova na rastojanju ta no i od cvora s.


c

Pored toga, neki cvor se ne nalazi ni u jednom talasu pretrage u irinu ako

i samo ako ne postoji put do njega od cvora s. Stoga se pretragom u irinu

grafa otkrivaju ne samo svi cvorovi koji su dostupni od cvora s u grafu,


nego se odreduju i najkra i putevi do njih. Stoga, pretragom u irinu se
c

lako reava problem s-t povezanosti u grafu dovoljno je tokom pretrage

od cvora s proveriti da li je neki otkriven cvor jednak t.

Na osnovu ovih cinjenica sledi i da pretraga u irinu neusmerenog

grafa G otkriva sve cvorove komponente grafa G koja sadri po etni cvor s.
c

Preciznije, unija svih talasa cvorova konstruisanih tokom pretrage u irinu

daje ta no cvorove komponente grafa G koja sadri cvor s.


c
Implementacija pretrage u irinu. Metod pretrage u irinu zasniva

se na ispitivanju suseda cvorova radi konstruisanja talasa otkrivenih cvorova. Zbog toga je za ekasnu algoritamsku realizaciju pretrage u irinu
idealna reprezentacija grafa nizom listi susedstva, jer ove liste upravo

sadre susede pojedinih cvorova. Za algoritam pretrage u irinu zato pret


postavljamo da je ulazni graf G sa n cvorova predstavljen globalnim nizom
listi susedstva.

Kada se konstruie naredni talas, pored ispitivanja suseda cvorova iz


prvog prethodnog talasa, potrebno je voditi ra una i o tome da neki od tih
c
suseda ne pripada ranijem talasu, odnosno da ti susedi nisu eventualno
ve otkriveni dosadanjom pretragom u irinu. Da bi se ovaj uslov mogao
c
lako proveriti u algoritmu, koristi se globalni logi ki niz p duine n. Svi
c
elementi ovog niza su po etno inicijalizovani vredno u neta no, a element
c
c
c

p[v] dobija vrednost ta no cim se pretragom otkrije (poseti) cvor v.


c
U algoritmu za pretragu u irinu datog grafa G pose uju se svi njegovi
c

cvorovi tako to se konstruiu talasi otkrivenih cvorova W0 , W1 , W2 , . . . na

na in koji je prethodno opisan. Ovi skupovi cvorova se predstavljaju gloc


balnim nizom listi W[0], W[1], W[2] i tako dalje.2 Radi lakeg razumevanja
algoritma, operacije za rad sa ovim listama u algoritmu nisu pisane onako
detaljno kako je to navedeno u odeljku 4.3. Nadamo se da to ne e izazvati
c

zabunu i da paljivi citaoci mogu lako prepoznati standardne operacije nad


listom o kojima je re .
c
// Ulaz: vor s u grafu G predstavljen listama susedstva
c
// Izlaz: pretraga u irinu grafa G od vora s
c
algorithm bfs(s)
2 Primetimo da je, radi jednostavnosti, niz W numerisan od 0, a ne od 1 kako smo navikli.

7.3. Obilazak grafa

W[0] = s;
p[s] = true;
i = 0;

197

// talas W0 poetno sadri cvor s


c
// polazni vor s je otkriven
c
// broja talasa vorova
c
c

while (W[i] != ) do
// prethodni talas Wi nije prazan
W[i+1] = ;
// naredni talas Wi+1 je poetno prazan
c
for (svaki vor u u talasu Wi ) do
c
// Ispitati susede vora u
c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
p[v] = true;
// vor v je novootkriven (poseen)
c
c
W[i+1] = W[i+1] + v;
// dodati v talasu Wi+1
i = i + 1;
return;

Analiza vremenske sloenosti algoritma bfs obuhva ena je slede om


c
c

cinjenicom:
L EMA Za graf G sa n cvorova i m grana koji je predstavljen nizom listi

susedstva, vreme izvravanja algoritma bfs je O(n + m). (To vreme je dakle
linearno u odnosu na veli inu ulaza algoritma.)
c
Dokaz: O evidno je da u vremenu izvravanja algoritma bfs dominira
c
c
vreme za koje se izvrava glavna while petlja. Medutim, ta an broj ite

c
racija ove while petlje nije lako odrediti, pa cemo postupiti na druga iji
na in i analizirati iteracije prve (spoljanje) for petlje tokom izvravanja
c
svih iteracija while petlje u algoritmu.
Pre toga, poto se u svakoj iteraciji while petlje na po etku konstruie
c
prazna lista za aktuelni talas i na kraju uve ava broja talasa, potrebno je
c
c
odrediti ukupno vreme potrebno za ta dva koraka. To je lako oceniti ukoliko

se primeti da su talasi disjunktni skupovi cvorova tako da ih najvie moe


biti n. To zna i da je u algoritmu potrebno konstruisati najvie n praznih
c
listi i izvriti najvie n operacija inkrementa broja a, pa je ukupno vreme
c
potrebno za to jednako O(n).
Da bismo sada ocenili vreme izvravanja spoljanje for petlje, prime
timo da se svaki cvor moe na i najvie jedanput u nekom talasu. Stoga se
c
tokom izvravanja svih iteracija while petlje u algoritmu, telo spoljanje

for petlje izvrava najvie jedanput za svaki cvor u grafa. Pored toga, ako
vora u, onda je broj iteracija unutranje
c
n u ozna ava broj suseda (stepen) c
for petlje jednak n u . Kako se dalje jedna iteracija te unutranje for petlje
o evidno izvrava za konstantno vreme, to je vreme izvravanja unutranje
c

198

Grafovi

for petlje za svaki cvor u jednako O(n u ). Ukoliko ovo vreme saberemo po

svim cvorovima grafa, dobijamo dakle ukupno vreme izvravanja spoljanje for petlje tokom izvravanja svih iteracija while petlje:

u V

O(n u ) = O

u V

n u = O(2m) = O(m) .

Najzad, ako ovom vremenu dodamo prethodno izra unato vreme za


c
konstruisanje listi i uve avanje broja a tokom izvravanja svih iteracija
c
c
while petlje, dobijamo traeno vreme izvravanja algoritma bfs: O(n) +
O(m) = O(n + m).
Stablo pretrage u irinu. Jedno vano svojstvo pretrage u irinu grafa
je da se na vrlo prirodan na in moe konstruisati stablo T sa korenom koji
c

je po etni cvor s i sa onim cvorovima iz grafa koji su dostupni od cvora s.


c
Stablo T se zove stablo pretrage u irinu i postupno se konstruie kako se

otkrivaju cvorovi grafa tokom pretrage u irinu na slede i na in:


c
c

Po etni cvor s je koren stabla T.


c
Pretpostavimo da smo konstruisali delimi no stablo T koje pokriva
c

cvorove u talasima W0 , W1 , . . ., Wi za i 0 i da su svi cvorovi iz Wi li


stovi tog stabla. Za svaki otkriven cvor v u talasu Wi+1 , posmatrajmo
trenutak njegovog otkrivanja tokom pretrage. To se dogada kada se

ispituje neki cvor u iz prethodnog talasa Wi i utvrdi se da je v njegov

sused koji nije prethodno otkriven. U tom trenutku se cvor v i grana


vor u postaje roditelj cvora

koja spaja u i v dodaju stablu T, odnosno c


v u stablu T.
Primetimo da je ovaj postupak konstruisanja stabla pretrage u irinu

dobro denisan, jer se u svakom koraku dodaju samo novi cvorovi iz narednog talasa, a uz to se dodaju i samo pojedine grane koje ih spajaju

sa cvorovima iz prethodnog talasa. Odatle sledi da su novododati cvorovi


listovi uve anog stabla i da novododate grane samo kompletiraju put do
c
njih ne formiraju i neki ciklus u stablu.
c
Prethodni algoritam bfs za pretragu u irinu grafa G moe se lako
proiriti kako bi se, usput, konstruisalo stablo pretrage u irinu T. Naredni
prilagodeni algoritam bfs sadri neophodne izmene napisane bez navo

denja detalja za operacije dodavanja cvorova i grana strukturi podataka

stabla.

7.3. Obilazak grafa

199

// Ulaz: vor s u grafu G predstavljen listama susedstva


c
// Izlaz: pretraga u irinu G od s i stablo pretrage u irinu T
algorithm bfs(s)
W[0] = s;
p[s] = true;
i = 0;
T = s;

//
//
//
//

talas W0 poetno sadri cvor s


c
polazni vor s je otkriven
c
broja talasa vorova
c
c
koren stabla T je vor s
c

while (W[i] != ) do
// prethodni talas Wi nije prazan
W[i+1] = ;
// naredni talas Wi+1 je poetno prazan
c
for (svaki vor u u talasu Wi ) do
c
// Ispitati susede vora u
c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
p[v] = true;
// vor v je novootkriven (poseen)
c
c
W[i+1] = W[i+1] + v;
// dodati v talasu Wi+1
T = T + v + {u,v};
// dodati v i granu { u, v} stablu T
i = i + 1;
return;

Na slici 7.12 je prikazano stablo pretrage u irinu T koje se dobija

ukoliko se pretragom u irinu datog grafa G otkrivaju cvorovi u talasima


istim redom kao na slici 7.11. Isprekidanim linijama u grafu G na slici 7.12

istaknute su grane koje ne dovode do otkrivanja novih cvorova tokom pretrage. U stablu T su grane stabla prikazane punim linijama, dok su isprekidanim linijama nazna ene grane grafa G koje ne pripadaju stablu T.
c
G

1
2

1
3

5
8

6
9

11

2
7

3
5

10

4
6

10

11

S LIKA 7.12: Stablo T koje se dobija pretragom u irinu datog grafa G od

cvora 1.

200

Grafovi

Na slici 7.12 moemo primetiti da sve grane grafa koje ne pripadaju

stablu pretrage u irinu (isprekidane linije) povezuju cvorove koji se nalaze


ili u istom talasu ili u susednim talasima. Ovo nije slu ajno i predstavlja
c
opte svojstvo stabla pretrage u irinu nekog grafa.

L EMA Neka je T stablo pretrage u irinu grafa G i neka su u i v cvorovi


u T koji pripadaju talasima Wi i W j , tim redom. Ako neka grana grafa G
spaja cvorove u i v, onda se i i j razlikuju najvie za jedan.

Dokaz: Dokaz izvodimo svodenjem na kontradikciju i zato pretpostavimo

da se i i j razlikuju za vie od jedan. Radi odredenosti, neka je Wi talas

ranije otkrivenih cvorova od W j i i < j 1. U proirenom algoritmu bfs

posmatrajmo trenutak kada se ispituju susedi cvora x koji pripada talasu

Wi . Poto je cvor y jedan od suseda cvora x u grafu G, y ce biti dodat talasu

Wi+1 ukoliko taj cvor nije ranije otkriven ili y pripada nekom prethodnom

talasu ukoliko je taj cvor ve otkriven. To zna i da mora biti j = i + 1 ili


c
c
c
c
j < i, to u oba slu aja protivre i pretpostavci da je i < j 1.

Pretraga u dubinu

Drugi sistemati an na in za obilazak svih cvorova grafa je pretraga


c
c
u dubinu grafa (engl. depth-rst search, DFS) koja je uoptenje postupka

obilaska cvorova stabla u preorder redosledu. Ime ovog metoda poti e od


c

toga to se ide sve dublje u grafu od po etnog cvora, du nekog puta sve dok
c

se taj put vie ne moe nastaviti, bilo zato to poslednji cvor nema grana
koje vode od njega ili zato to sve grane od njega vode do ve pose enih
c
c

cvorova.
Pretraga u dubinu grafa podse a na postupak koji se prirodno pric

menjuje kada se trai izlaz iz nekog lavirinta. Ukoliko cvorove i grane


grafa zamislimo kao lavirint medusobno povezanih prolaza kroz koje treba

prona i izlaz od po etnog cvora s, onda je prirodno probati prvu granu koja
c
c

vodi od s. Ako nas to vodi do nekog cvora v, onda bismo dalje sledili prvu

granu koja vodi od v. Ovaj postupak bismo zatim sli no nastavili od cvora
c

u koji smo doli od cvora v, sve dok moemo i ne dodemo u orsokak,


c

odnosno do cvora cije smo sve susede ve probali. Onda bismo se vratili
c

putem kojim smo doli do prvog cvora cije sve susede jo nismo probali i
zatim bismo odatle ponovili isti postupak.

Primetimo da se od svakog cvora ponavlja ista aktivnost: slediti prvu

granu koja vodi do nekog susednog cvora koji nije ve pose en. Zato se
c
c
pretraga u dubinu moe najlake opisati u rekurzivnom obliku u kojem

7.3. Obilazak grafa

201

ova aktivnost odgovara rekurzivnom pozivu, ali se evidenicja o tome koji

su cvorovi bili pose eni mora voditi na globalnom nivou.


c
Implementacija rekurzivnog algoritma za pretragu u dubinu grafa zasniva se na istim strukturama podataka koje se koriste i u algoritmu za

pretragu u irinu. Pretpostavljamo dakle da je ulazni graf G sa n cvorova


globalno predstavljen nizom listi susedstva. Pored toga, globalni logi ki niz
c

p duine n, ciji su svi elementi po etno inicijalizovani vredno u neta no,


c
c
c

slui za vodenje ra una o tome koji cvorovi su ve pose eni tokom pretrage.
c
c
c

// Ulaz: vor u u grafu G predstavljen listama susedstva


c
// Izlaz: pretraga u dubinu grafa G od vora u
c
algorithm dfs(u)
p[u] = true;

// vor u je poseen
c
c

// Ispitati susede vora u


c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
dfs(v);
// rekurzivna pretraga u dubinu od vora v
c
return;

Primetimo da za algoritam dfs, zbog njegove rekurzivne prirode, nije

bitan po etni cvor, ve ulazni cvor moe biti bilo koji cvor grafa. Na primer,
c
c
problem s-t povezanosti moe se jednostavno reiti pozivom dfs(s). Pored
toga, algoritam dfs ne proizvodi neki opipljiv rezultat, nego samo propi
suje odreden na in obilaska svih cvorova grafa. (Ovo zapaanje se odnosi
c

i na algoritam bfs iz prethodnog odeljka konstruisani talasi otkrivenih

cvorova su samo sredstvo za sistemati an obilazak svih cvorova grafa.) Nac

ravno, pravi rezultat zavisi od konkretnog problema cije se reenje zasniva


na optem algoritmu pretrage grafa.
c
Svaki poziv algoritma dfs odvija se samo za neki nepose en cvor. Tako,

za neki nepose en ulazni cvor u, u algoritmu se najpre registruje da je u


c

pose en, a zatim se ispituju svi susedi cvora u proveravanjem svake grane
c

koja ide od u. Ako se pronade neki jo uvek nepose en cvor v susedan


c

cvoru u, u algoritmu se odmah pose uje cvor v rekurzivnim pozivom istog


c

algoritma za cvor v. Poto se potpuno provere sve grane koje idu od cvora

u, poseta cvoru u se smatra zavrenom i algoritam zavrava rad.


Na slici 7.13 je ilustrovano izvravanje algoritma dfs na jednom primeru grafa tako to je uvla enjem nazna ena struktura rekurzivnih poc
c
ziva. Obratite panju na to da rezultat pretrage u dubinu nije jednozna an
c

202

Grafovi

i da zavisi od redosleda kojim se pose uju susedi nekog cvora u for petlji
c
algoritma dfs.

1
3

2
5
8

6
9

11

4
7
10

dfs(1)
dfs(2)
dfs(3)
dfs(6)
dfs(10)
dfs(7)
dfs(4)
dfs(9)
dfs(8)
dfs(5)
dfs(11)

S LIKA 7.13: Izvravanje algoritma dfs od cvora 1 datog grafa.


Pretraga u dubinu i pretraga u irinu grafa imaju neke sli nosti i neke
c
injenici da se na oba na ina na kraju
razlike. Jedna sli nost ogleda se u c
c
c

obide ta no ona povezana komponenta grafa koja sadri po etni cvor. Pored
c
c

toga, kao to cemo u nastavku pokazati, pretraga u dubinu ima sli ne


c
performanse kao pretraga u irinu i pretragom u dubinu se na prirodan

na in moe konstruisati stablo pose enih cvorova sli no kao kod pretrage
c
c
c
u irinu.
Sa druge strane, iako se primenom oba na ina naposletku obide isti
c

skup cvorova one komponente grafa koja sadri po etni cvor, pretragom
c

u dubinu se dobija potpuno druga iji redosled obilaska cvorova. Naime,


c
pretragom u dubinu se obi no probijaju vrlo duga ki putevi od po etnog
c
c
c

cvora, odnosno poziv algoritma dfs(u) generie lanac rekurzivnih poziva,


potencijalno vrlo duga ak, pre nego to se uradi bilo ta mnogo toga drugog.
c

Ovaj rekurzivni lanac poziva se prekida tek kad se od ulaznog cvora u

dode do cvora v odakle se lanac vie ne moe nastaviti, bilo zato to cvor v

nema grana koje vode od njega ili zato to sve grane od njega vode do ve
c

pose enih cvorova. U tom trenutku se rekurzija odmotava i vra a se na


c
c

prvi cvor od ta ke prekida odakle se mogu ispitati alternativni putevi.


c
Analiza pretrage u dubinu. Da bismo analizirali algoritam dfs, pret
postavimo da ulazni graf G = (V , E) ima n cvorova i m grana. Iako je dfs
rekurzivni algoritam, njegovo vreme izvravanja ne emo odrediti na uobic

cajen na in koji smo primenjivali kod analize rekurzivnih algoritama. Nije


c

7.3. Obilazak grafa

203

naime jasno kako to vreme moemo izraziti u obliku rekurentne jedna ine
c

cijim reavanjem moemo dobiti funkciju vremena izvravanja. Umesto


toga, postupi emo tako da saberemo vremena izvravanja svih poziva alc
c
c
goritma dfs, ne ra unaju i tu vreme za rekurzivne pozive pojedinih poziva.
c
Da bismo ocenili vreme izvravanja jednog poziva dfs(u), izuzimaju i

vreme za njegove rekurzivne pozive, primetimo da ono zavisi od broja cvo

rova koji su susedi cvora u. Ako je broj suseda (stepen) cvora u jednak
n u , onda se telo for petlje u algoritmu dfs izvrava n u puta. Poto se u
telu te petlje ne ra una vreme za izvravanje rekurzivnog poziva dfs(v),
c
moe se zaklju iti da se to telo izvrava za konstantno vreme. Prema
c
c
c
tome, ukupno vreme za izvravanje poziva dfs(u), ne ra unaju i njegove
rekurzivne pozive, jednako je O(1 + n u ). Ovde je jedinica dodata broju
c
suseda n u kako bi se u obzir uzeo slu aj kada je n u = 0, jer se onda poziv
dfs(u) ipak izvrava za neko konstantno vreme O(1).
Da bismo dalje ocenili ukupan broj poziva algoritma dfs, primetimo

da se svaki poziv tog algoritma izvrava najvie jedanput za svaki cvor u

grafu. Naime, cim se pozove dfs(u) za neki cvor u, odmah se taj cvor
c
obeleava da je pose en, a algoritam dfs se nikad ponovo ne poziva za ve
c

pose en cvor. Prema tome, ukupno vreme izvravanja za sve pozive algoc

c
c
ritma dfs od nekog po etnog cvora grafa G je ograni eno zbirom vremena

pojedina nih poziva za sve cvorove grafa G:


c

u V

O(1 + n u ) = O

u V

(1 + n u ) = O

u V

1+

u V

n u = O(n + 2m) = O(n + m) .

Drugima re ima, algoritam za pretragu u dubinu grafa G izvrava se za


c

vreme O(n + m), odnosno za linearno vreme u odnosu na zbir brojeva cvorova i grana grafa.
Stablo pretrage u dubinu. Svaka pretraga u dubinu grafa na prirodan
na in odreduje jedno povezuju e stablo komponente grafa koja sadri poc
c

cetni cvor pretrage s. Naime, pretragom u dubinu se svaki cvor te kompo


nente pose uje samo jednom, pa ti cvorovi i grane grafa kroz koje se prolazi
c
tokom pretrage u dubinu formiraju stablo T. Korensko stablo T se naziva

stablo pretrage u dubinu i postupno se konstruie kako se pose uju cvorovi


c
grafa tokom pretrage u dubinu na slede i na in:
c
c

Po etni cvor s je koren stabla T.


c
Pretpostavimo da se tokom pretrage u dubinu izvrava poziv dfs(u)

za neki cvor u. Ukoliko se za vreme tog izvravanja direktno rekur

zivno poziva dfs(v) za neki cvor v, onda se cvor v i grana koja spaja

204

Grafovi

u i v dodaju stablu T. Drugim re ima, cvor u postaje roditelj cvora


c

v u stablu T, jer je cvor u odgovoran za pose ivanje cvora v. Tako


c

se u stablu T cvorovi koji su deca cvora u nalaze, sleva na desno, u

redosledu po kojem se algoritam dfs direktno poziva za te cvorove


tokom izvravanja poziva dfs(u).

Sli no proirenom algoritmu za pretragu u irinu grafa, osnovni algoc


ritam dfs za pretragu u dubinu grafa G moe se lako proiriti kako bi se
usput konstruisalo stabla pretrage u dubinu. Ukoliko je to stablo po etno
c
prazno, ono se u narednom prilagodenom algoritmu dfs postupno proiruje

dodavanjem cvorova i grana.


// Ulaz: vor u u grafu G predstavljen listama susedstva
c
// Izlaz: pretraga u dubinu G od u i stablo pretrage u dubinu T
algorithm dfs(u)
p[u] = true;
T = T + u;

// vor u je poseen
c
c
// dodati vor u stablu T
c

// Ispitati susede vora u


c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
dfs(v);
// rekurzivna pretraga u dubinu od vora v
c
T = T + {u,v};
// dodati granu { u, v} stablu T
return;

Na slici 7.14 je prikazano stablo pretrage u dubinu koje se konstruie

pretragom u dubinu koja po inje od cvora 1 grafa G na slici 7.13. Predene


c

grane grafa su predstavljene punim linijama, dok su isprekidanim linijama


predstavljene grane grafa koje nisu kori ene tokom pretrage.
c
Grane grafa G se mogu klasikovati prema tome u kom odnosu stoje
sa granama stabla pretrage u dubinu T koje se konstruie tokom pretrage
u dubinu. Grana e = { u, v} u grafu G koja prouzrokuje to da se u pozivu
dfs(u) direktno rekurzivno poziva dfs(v) naziva se grana stabla. Pune
linije na slici 7.14 predstavljaju grane stabla.

Primetimo da isprekidane grane na slici 7.14 spajaju dva cvora koja


stoje u odnosu predak-potomak u stablu pretrage u dubinu. Isprekidana
grana je grana e = { u, v} u grafu G takva da ni dfs(u) ni dfs(v) ne pozivaju jedno drugo direktno, ve indirektno. Poto je isprekidana grana
c
pre ica za put nagore od potomka do pretka u stablu T, ona se naziva
c
povratna grana. Jedno korisno zapaanje u vezi sa ovim jeste da je ovo
potpuna klasikacija grana neusmerenog grafa.

7.3. Obilazak grafa

205
T

1
3

2
2

4
6

7
10

10
7

11
5

11

S LIKA 7.14: Stablo T dobijeno pretragom u dubinu datog grafa G.

L EMA Neka je T stablo pretrage u dubinu povezanog grafa G i neka su u i


v cvorovi u T. Ako je e = { u, v} grana grafa G koja nije grana stabla T, onda

je e povratna grana.

Dokaz: Primetimo najpre da za dati rekurzivni poziv dfs(u), svi cvorovi koji su pose eni izmedu po etka i zavretka ovog poziva predstavljaju
c
c

potomke cvora u u stablu T.


Pretpostavimo sada da je e = { u, v} grana grafa G koja nije grana stabla
T. Radi odredenosti, pretpostavimo jo da se pretragom u dubinu dolazi

do cvora u pre cvora v, odnosno da je cvor v je u trenutku poziva dfs(u)

bio nepose en. Kada se cvor v ispituje u pozivu dfs(u), grana e = { u, v}


c
se ne e dodati stablu T, jer e po pretpostavci nije grana stabla. Ali jedini
c
razlog zato grana e ne bi bila dodata stablu T je taj to je njen drugi

kraj v ranije ve pose en. Kako cvor v nije bio pose en pre po etka poziva
c
c
c
c

dfs(u), to zna i da je cvor v pose en izmedu po etka i kraja poziva dfs(u).


c
c
c

Na osnovu zapaanja na po etku dokaza onda sledi da je cvor v potomak


c

cvora u, odnosno da je e povratna grana.

Skup povezanih komponenti grafa


Do sada smo govorili o povezanoj komponenti grafa koja sadri odreden

vor s. Kako se u neusmerenom grafu svaki cvor nalazi u ta no jednoj od

c
c
njegovih povezanih komponenti, postavlja se pitanje u kom odnosu stoje
ove komponente? Taj odnos je izraen na slede i na in:
c
c

206

Grafovi

L EMA Povezane komponente bilo koja dva cvora s i t u grafu su ili identi ne

c
ili disjunktne.
Dokaz: Tvrdenje leme je inuitivno o igledno kada se graf nacrta, jer
c

se onda odmah prepoznaju povezani delovi od kojih se graf sastoji. To

nije teko i formalno pokazati, jer treba samo iskoristiti cinjenicu da su


komponente grafa njegovi povezani delovi, odnosno da postoji put izmedu

bilo koja dva cvora u jednoj komponenti.


Pre svega, ukoliko postoji put izmedu cvorova s i t u grafu, onda su

povezane komponente koje sadre s i t isti skup. Naime, svaki cvor v u

komponenti koja sadri s dostupan je i od cvora t put izmedu t i v sastoji

se od dve deonice: deonice izmedu t i s i deonice izmedu s i v. Poto ova

argumentacija vai i kada cvorovi s i t zamene uloge, neki cvor se nalazi u

komponenti koja sadri s ako i samo ako se taj cvor nalazi u komponenti
koja sadri t.
Sa druge strane, ukoliko ne postoji put izmedu cvorova s i t u grafu,

onda ne postoji nijedan cvor v koji se nalazi u povezanim komponentama

koje sadre s i t. To je zato to ukoliko bi takav cvor v postojao, onda bi


putevi od s do v i od v do t obrazovali i put izmedu s i t. Prema tome, ukoliko

ne postoji put izmedu cvorova s i t, onda su njihove povezane komponente



disjunktne.
Ovaj vrlo strukturirani medusobni odnos povezanih komponenti grafa

moe se iskoristiti za njihovo ekasno nalaenje. Prirodni algoritam je da

se najpre izabere proizvoljni cvor s i da se zatim pretragom u irinu ili

dubinu grafa od cvora s proizvede povezana komponenta koja sadri taj

po etni cvor. Isti postupak se zatim ponavlja od proizvoljnog cvora t koji


c

nije bio pose en prethodnom pretragom od cvora s, ukoliko se takav cvor


c
t uopte moe na i. Opravdanje za ovaj pristup lei u prethodnoj lemi:
c

povezane komponente cvorova s i t su medusobno disjunktne. Ako posle

zavretka druge pretrage od t jo uvek postoji neki cvor v koji nije bio

pose en prethodnim pretragama, isti postupak se ponavlja i od cvora v,


c

i tako dalje sve dok se ne posete svi cvorovi grafa.


Nije teko proveriti da je vreme izvravanja ovog algoritma za nalae
nje povezanih komponenti grafa od n cvorova i m grana jednako O(n + m).
U ovom obliku smo ranije izrazili vremena izvravanja algoritama za pretrage u irinu i dubinu grafa, ali to vreme je zapravo manje jer se u tim

algoritmima koriste samo cvorovi i grane povezane komponente koja sadri

po etni cvor pretrage. Mada se pretraga grafa u prethodnom algoritmu za


c
nalaenje svih povezanih komponenti grafa moe ponavljati vie puta, za

7.3. Obilazak grafa

207

svaku granu ili cvor obavlja se aktivnost konstantnog vremena ipak samo
u iteraciji u kojoj se konstruie povezana komponete kojoj oni pripadaju.
Zbog toga je vreme izvravanja prethodnog algoritma za nalaenje svih
povezanih komponenti grafa ukupno jednako O(n + m).

Primer: jedan problem velike TV mree


Mnogi prakti ni problemi koji se predstavljaju grafovima mogu se ec
kasno reiti prethodnim algoritmom za nalaenje svih povezanih komponenti grafa. Jedan primer takvog problema dobijamo ukoliko zamislimo da

je grafom opisana velika TV mrea neke kompanije. U tom grafu svaki cvor
predstavlja TV stanicu i svaka grana predstavlja dvosmerni komunikacioni kanal izmedu dve stanice kojim su one direktno zemaljski povezane

i mogu da medusobno primaju signal jedna od druge. Na slici 7.15 je

prikazan primer jedne TV mree u obliku neusmerenog grafa.

S LIKA 7.15: TV mrea predstavljena grafom TV stanica.


Ukoliko TV mrea uivo prenosi neki veliki svetski dogadaj (na primer,

svetsko fudbalsko prvenstvo), direktni prenosi se obavljaju preko satalita


jer je TV mrea geografski vrlo rasprostranjena. Satelit moe da prenosi
signal do bilo koje TV stanice, a kada neka TV stanica primi signal od
satelita, ona ga moe dalje zemaljski emitovati do susednih TV stanica.
Na primer, ako stanice a, b i c na slici 7.15 istovremeno dobijaju signal od

satelita i difuzno ga reemituju, sve ostale stanice u mrei ce dobiti signal


direktnog prenosa.
Zemaljsko emitovanje signala je mnogo jeftinije od satelitskog prenosa.
Zato je potrebno odrediti minimalan broj TV stanica koje moraju da dobiju

208

Grafovi

signal od satelita kako bi i sve ostale TV stanice u mrei mogle primiti


isti signal. Jasno je da se odgovor na pitanje koliki je ovaj minimalni broj
svodi na nalaenje broja povezanih komponenti grafa G koji predstavlja TV

mreu. Preciznije re eno, grafovski problem cije se ekasno reenje trai


c

je da se svakom cvoru grafa G pridrui broj takav da svi cvorovi u jednoj


povezanoj komponenti grafa G dobiju isti redni broj te komponente.
Reenje ovog problema je dato algoritmom connected-components u
nastavku i po strukturi je vrlo sli no osnovnom algoritmu za nalaenje
c

svih povezanih komponenti grafa G sa n cvorova i m grana. U algoritmu

connected-components se za brojeve pridruene cvorovima koristi glo


balni niz c veli ine n. Ovi brojevi komponenti se cvorovima dodeljuju na
c
osnovu globalnog broja a k kojim se prebrojavaju povezane komponente
c
grafa G. Rezultat algoritma su dakle elementi niza c takvi da za svaki

cvor v u grafu vrednost c v predstavlja redni broj komponente cvora v. Za


otkrivanje jedne komponente grafa se, radi odredenosti, koristi pretraga

u dubinu grafa. Ona je realizovana algoritmom dfs-cc koji je prilagoden

tako da se svakom pose enom cvoru pridruuje redni broj njegove kompoc
nente.
// Ulaz: graf G predstavljen listama susedstva
// Izlaz: niz c takav da je c v broj komponente vora v
c
algorithm connected-components(G)

// Svi cvorovi su poetno neposeeni


c
c
for (svaki vor v u nizu listi susedstva G ) do
c
p[v] = false;
c[v] = 0;
k = 0;

// broja povezanih komponenti grafa G


c

// Ispitati sve vorove grafa G


c
for (svaki vor v u nizu listi susedstva G ) do
c
if (p[v] == false) then
k = k + 1;
// vor v je u novoj komponenti grafa G
c
dfs-cc(v);
// nova pretraga u dubinu od vora v
c
return c;

// Ulaz: vor u u grafu G predstavljen listama susedstva


c
// Izlaz: broj c u dodeljen svim vorovima komponente vora u
c
c
algorithm dfs-cc(u)
p[u] = true;
c[u] = k;

// vor u je poseen
c
c
// vor u pripada aktuelnoj komponenti
c

7.4. Obilazak usmerenog grafa

209

// Ispitati susede vora u


c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
dfs-cc(v);
// rekurzivna pretraga od vora v
c
return;

Vreme izvravanja algoritma connected-components asimptotski je


o igledno jednako vremenu izvravanja osnovnog algoritma za nalaenje
c
broja povezanih komponenti grafa, odnosno to vreme je O(n + m).

7.4 Obilazak usmerenog grafa


Podsetimo se da su grane u usmerenim grafovima usmerene od jed

nog do drugog cvora: grana (u, v) ima smer od cvora u do cvora v. Ovaj
asimetri ni odnos izmedu cvorova proizvodi kvalitativno razli it efekat na
c
c

strukturu usmerenih grafova. Posmatrajmo na primer Internet iz grafov
ske perspektive kao jedan veliki, komplikovan graf ciji cvorovi predstavljaju pojedine veb strane, a grane predstavljaju medusobne hiperlinkove.

Pregledanje Interneta se onda svodi na pra enje niza grana u ovom usmec

renom grafu, pri cemu je smer grana od sutinske vanosti jer obi no nije
c
mogu e unazad pratiti hiperlinkove koji vode to date strane.
c
Vanost smera grana odraava se dakle na bitno druga iji pojam povec
zanosti u usmerenim grafovima nego u neusmerenim grafovima. U usme

renom grafu je mogu e da od cvora s postoji put do cvora t, ali ne i put


c
od t do s. To se onda prenosi na sloeniji pojam povezanih komponenti
usmerenog grafa i zato se posmatra svojstvo jake povezanosti usmerenih
grafova. Jaka povezanost usmerenih grafova otprilike odgovara obi noj
c
povezanosti neusmerenih grafova: usmeren graf je jako povezan ako za

svaka dva njegova cvora postoji put od jednog do drugog cvora, ali i obrnut

put od drugog do prvog cvora.


Skoro svi drugi osnovni pojmovi i algoritmi za neusmerene grafove ipak
se vrlo prirodno mogu prilagoditi za usmerene grafove. Ovo speci no vai
c
i za algoritme za pretragu u dubinu i irinu, koji se uz neznatne izmene
mogu primeniti za usmerene grafove.
Pretraga usmerenih grafova se konceptualno ne razlikuje od pretrage
neusmerenih grafova, jer se jedino menja interpretacija pojma susedni

cvor. Kod usmerenog grafa, cvor v je susedan cvoru u ako postoji usme

rena grana (u, v). Ali cvor u nije automatski susedan cvoru v, osim ako ne

210

Grafovi

postoji i grana (v, u). Ako se uzme u obzir ova promena interpretacije relacije susedstva, osnovni algoritmi bfs i dfs mogu se bez izmene primeniti i
za usmerene grafove. Pored toga, na identi an na in se moe pokazati da je
c
c

njihovo vreme izvravanja za usmeren graf sa n cvorova i m grana takode

jednako O(n + m).


U nastavku ovog poglavlja se zato usredsredujemo samo na pretragu u

dubinu usmerenog grafa pretraga u irinu se moe sli no analizirati. Na


c
primer, na slici 7.16 ilustrovano je izvravanje osnovnog algoritma dfs za
jedan usmeren graf.
G
1
3

2
5
8

6
9

11

4
7
10

dfs(1)
dfs(2)
dfs(4)
dfs(6)
dfs(9)
dfs(11)
dfs(8)
dfs(5)
dfs(3)
dfs(10)
dfs(7)

S LIKA 7.16: Izvravanje algoritma dfs od cvora 1 datog usmerenog grafa.


Na potpuno isti na in kao kod neusmerenih grafova moe se konstruic
sati stablo pretrage u dubinu za usmerene grafove: ako se tokom izvrava
nja dfs(u) direktno poziva dfs(v), stablu se dodaje cvor v i grana stabla

koja v povezuje sa u tako da cvor v bude dete cvora u u stablu. Drugim


re ima, stablo pretrage u dubinu T koje se indukuje pretragom u dubinu
c
grafa G zapravo je stablo rekurzivnih poziva algoritma dfs koje se dobija

od po etnog poziva tog algoritma za neki cvor grafa G. Na slici 7.17 je


c
prikazano stablo dobijeno pretragom u dubinu koja odgovara primeru na
slici 7.16.
Mada su algoritmi pretrage u dubinu usmerenih i neusmerenih grafova
konceptualno vrlo sli ni, njihovo izvravanje proizvodi prili no razli it efec
c
c

kat. Prvo, pretraga u dubinu moe proizvesti umu stabala cak i kada je
usmeren graf povezan. Na primer, da smo pretragu u dubinu na slici 7.16

po eli od cvora 7, dobili bismo umu od dva stabla ili vie njih. Drugo, u
c
slu aju neusmerenog grafa pokazali smo da grane grafa koje nisu grane
c

stabla pretrage u dubinu obavezno povezuju neki cvor sa jednim od njego-

7.4. Obilazak usmerenog grafa

211
T

2
5
8

4
6

4
6

10

11

10
8

11
5
3

S LIKA 7.17: Stablo T dobijeno pretragom u dubinu datog usmerenog


grafa G na slici 7.16.

vih predaka u stablu. Drugim re ima, grane neusmerenog grafa koje nisu
c
grane stabla uvek su povratne grane. Sa druge strane, grane usmerenog
grafa G u odnosu na njegovo stablo pretrage u dubinu T mogu biti jednog
od slede a tri tipa:
c
1. Direktna grana. To je usmerena grana (u, v) u G koja nije grana stabla

T takva da je cvor v pravi potomak cvora u, ali nije dete cvora u u T.


Na primer, na slici 7.17 grana (4, 7) je direktna grana.
2. Povratna grana. To je usmerena grana (u, v) u G koja nije grana stabla

T takva da je cvor v predak cvora u u T (u = v je dozvoljeno). Na primer,


na slici 7.17 grana (3, 6) je povratna grana. Obratite panju na to da se
petlje, koje su dozvoljene u usmerenih grafovima, smatraju povratnim
granama.
3. Popre na grana. To je usmerena grana (u, v) u G koja nije grana stabla
c

T takva da cvor v nije ni predak ni potomak cvora u u T. Druga ije


c
re eno, popre na grana je preostali tip usmerenih grana u G koje nisu
c
c
grane stabla T. Na primer, na slici 7.17 grana (7, 10) je popre na grana.
c
vorove razli itih stabala
Primetimo da popre ne grane mogu povezivati c
c
c
u umi. Zato u optem slu aju za odredenu popre nu granu (u, v) ne
c
c

mora biti ta no da cvorovi u i v imaju zajedni kog pretka.


c
c

212

Grafovi

Pored toga, na slici 7.17 se uo ava da popre na grana (7, 10) ima
c
c
smer zdesna na levo. To nije slu ajnost i vai u optem slu aju: svaka
c
c

popre na grana ima smer zdesna na levo, cak i u umi stabala pretrage
c
u dubinu.
Da bismo to pokazali, neka je (u, v) popre na grana i posmatrajmo
c

c
poziv dfs(u). O evidno je cvor v potomak cvora u u stablu pretrage u

dubinu ako i samo ako je cvor v dodat u stablo izmedu vremena po etka
c

izvravanja dfs(u) i vremena zavretka izvravanja dfs(u). U tom


vremenskom intervalu, do trenutka kada se tokom izvravanja dfs(u)

proverava grana (u, v), cvor v je morao biti ve pose en, jer (u, v) nije
c
c

grana stabla. Prema tome, cvor v je morao biti pose en ranije u toku
c
c
c
izvravanja dfs(u) ili pre poziva dfs(u). Ali prvi slu aj je nemogu ,

jer bi u suprotnom slu aju cvor v bio potomak cvora u. Dakle, v je bio
c

dodat u stablo pretrage u dubinu pre cvora u, a poto se cvorovi dodaju


u redosledu sleva na desno, v mora biti levo od u.

Usmereni aciklicki grafovi


Ako neusmeren graf nema nijedan ciklus, onda ima vrlo prostu strukturu ume: sve njegove povezane komponente su stabla. Ali za usmeren
graf je mogu e da nema nijedan (usmeren) ciklus i da ima sloenu strukc

turu. Na primer, usmeren graf bez ciklusa sa n cvorova moe imati veliki

broj grana reda (n2 ), dok stablo (neusmeren graf bez ciklusa) sa n cvorova
ima samo n 1 granu. Usmeren graf bez ciklusa se standardno naziva
usmeren acikli ki graf i jedan primer takvog grafa je prikazan na slici 7.18.
c
6

S LIKA 7.18: Usmeren acikli ki graf.


c

Usmeren acikli ki graf se u ra unarstvu cesto koristi za predstavljanje


c
c
uslovnog redosleda nekih zadataka po kojem se oni moraju zavravati.
Na primer, prilikom zidanja neke zgrade, prvi sprat se mora izgraditi pre
drugog sprata, ali elektri ni kablovi se mogu postaviti u isto vreme dok se
c

7.4. Obilazak usmerenog grafa

213

instaliraju prozori na jednom spratu. Drugi primer je program studiranja


na nekom fakultetu, gde su neki predmeti preduslovi za polaganje drugih
predmeta. Jo jedan primer je kolekcija paralelnih procesa od kojih se
sastoji neki ra unarski program tako da izlaz nekog procesa predstavlja
c
ulaz za neki drugi proces i zato se prvi proces mora zavriti pre po etka
c
drugog.
Prirodni model ovakvih struktura zavisnosti su usmereni acikli ki grac
fovi: usmerena grana od nekog zadatka a do drugog zadatka b predstavlja
uslov da se a mora zavriti pre nego to se moe po eti b. Na slici 7.19
c
je ilustrovana struktura zavisnosti pet zadataka. U tom primeru, recimo,
zadatak c se moe obaviti samo kada su zadaci a i b zavreni.
a

c
e

S LIKA 7.19: Usmeren acikli ki graf zavisnosti pet zadataka.


c
U optem slu aju, pretpostavimo da imamo skup zadataka {1, 2, . . ., n}
c
koje treba obaviti i da postoje zavisnosti medu njima takve da za izvesne

parove zadataka i i j imamo uslov da se i mora zavriti pre po etka j.


c
Ovakav skup medusobno zavisnih zadataka moe se predstaviti usmere

nim grafom G sa cvorovima koji predstavljaju pojedine zadatake i granama


(i, j) koje predstavljaju uslov da se i mora zavriti pre po etka j.
c
O igledno da bi ova relacija medusobne zavisnosti zadataka uopte
c

imala smisla, dobijeni usmeren graf G mora biti acikli ki, jer ukoliko G
c
sadri neki ciklus C, onda ne postoji na in da se uradi nijedan zadatak u
c
C. Naime, kako svaki zadatak u ciklusu C ima neki drugi zadatak koji
se prethodno mora zavriti, nijedan zadatak u C se ne moe obaviti jer se
nijedan zadatak ne moe zapo eti.
c
Ukoliko usmeren graf zavisnosti zadataka nema cikluse, prirodno je
onda traiti redosled tih zadataka po kojem se oni mogu obaviti tako da
sve medusobne zavisnosti zadataka budu potovane. Takav ispravan redo
sled zadataka se naziva topoloki redosled. Preciznije, topoloki redosled

usmerenog acikli kog grafa G sa n cvorova je neki linerani poredak njegoc


vorova u nizu v1 , v2 , . . ., vn tako da za svaku granu (v i , v j ) vai i < j.
vih c
Slikovito re eno, sve grane grafa G su usmerene sleva na desno ukoliko
c

se njegovi cvorovi nacrtaju du horizontalno linije u topolokom redosledu.

214

Grafovi

Na primer, topoloki redosled grafa na slici 7.19 je a, b, c, d, e, to je odmah


uo ljivo ukoliko se isti graf nacrta kao na slici 7.20. Obratite panju na to
c

da taj linearni poredak cvorova nije jedinstven drugi na in za topoloki


c
redosled istog grafa je b, d, a, c, e.

S LIKA 7.20: Topoloki redosled grafa na slici 7.19.


Topoloki redosled usmerenog grafa zavisnosti zadataka obezbeduje

dakle redosled po kojem se oni mogu bezbedno uraditi kada treba po eti
c
neki zadatak, svi zadaci koji su njegovi preduslovi sigurno su ve zavreni.
c
U stvari, posmatrano iz apstraktnijeg ugla, topoloki redosled usmerenog
grafa predstavlja dokaz da je graf acikli ki.
c
L EMA Ako usmeren graf G ima topoloki redosled, onda G nema nijedan
ciklus.
Dokaz: Pretpostavimo, radi kontradikcije, da G ima jedan topoloki re
dosled svojih cvorova v1 , v2 , . . ., vn i da u G postoji ciklus C. Neka je v j

cvor u C sa najmanjim indeksom i neka je v i cvor u C koji neposredno

c
prethodi cvoru v j . To zna i da je (v i , v j ) jedna od grana u G. Ali to dovodi do
protivre nosti, jer onda mora biti ta no da je i < j zato to svaka grana za
c
c

topoloki redosled cvorova ide od cvora sa manjim indeksom prema cvoru

sa ve im indeksom, kao i da je j < i zato to su v j i v i cvorovi u C i v j je


c

cvor u C sa najmanjim indeksom.


Prema tome, postojanje topolokog redosleda usmerenog grafa je dovoljan uslov da taj graf nema cikluse. Taj kriterijum moe ponekad biti vrlo
koristan, jer se vizuelno moe lako pokazati da je graf acikli ki. Na primer,
c
nije odmah jasno to da graf na slici 7.18 nema cikluse, ali ako se isti graf
prikae u topolokom redosledu kao na slici 7.21, onda je to o igledno poto
c
sve grane idu sleva na desno.
Nalaenje topolokog redosleda. Tee pitanje za usmeren acikli ki
c
graf je obrnuto od onog na koje odgovor daje poslednja lema: da li svaki
usmeren acikli ki graf ima topoloki redosled? Ako je to slu aj, dodatno
c
c
bi bilo vrlo korisno imati ekasan algoritam za nalaenje jednog topolokog redosleda datog usmerenog acikli kog grafa, jer onda bi se za svaku
c
relaciju zavisnosti nad skupom zadataka bez ciklusa mogao ekasno na i
c

7.4. Obilazak usmerenog grafa

215

S LIKA 7.21: Topoloki redosled grafa na slici 7.18.

redosled po kojem se ti zadaci mogu bezbedno obaviti. Odgovor na pret


hodno pitanje je potvrdan i, u stvari, to cemo pokazati na konstruktivan
na in. Drugim re ima, pokaza emo jedan ekasan algoritam kojim se za
c
c
c
dati usmeren acikli ki graf pronalazi njegov topoloki redosled.
c
Algoritam za nalaenje topolokog redosleda usmerenog acikli kog grac
fa G sli an je algoritmu za nalaenje povezanih komponenti neusmerenog
c
grafa, osim to nije svejedno koja pretraga grafa se koristi nego se mora
koristiti pretraga u dubinu. Opti pristup je dakle da se najpre izabere

proizvoljni cvor s u G i da se zatim pretragom u dubinu od cvora s posete

svi cvorovi u G koji su dostupni od tog po etnog cvora. Isti postupak se


c

zatim ponavlja od proizvoljnog cvora t koji nije bio pose en prethodnom


c

pretragom od cvora s, ukoliko se takav cvor t uopte moe na i. Ako posle


c

zavretka druge pretrage od t jo uvek postoji neki cvor v koji nije bio

pose en prethodnim pretragama, isti postupak se ponavlja i od cvora v, i


c

tako dalje sve dok se ne posete svi cvorovi grafa. Na ovaj na in se indukuje
c
uma stabala pretrage u dubinu sa korenima s, t i tako dalje.

Za razumevanje ovog algoritma je najvanija cinjenica to da jedno stablo pretrage u dubinu u sutini predstavlja stablo rekurzivnih poziva al
c
goritma dfs od po etnog poziva tog algoritma za neki cvor. Kako se za

svaki cvor v po etak i zavretak poziva dfs(v) odigravaju u diskretnim


c
vremenskim trenucima, to se na vremenskoj osi moe pratiti izvravanje
celokupnog prethodno opisanog postupka za nalaenje topolokog redosleda. Na primer, na slici 7.22 su na vremenskoj osi prikazani intervali
trajanja svih poziva algoritma dfs tokom viestruke pretrage u dubinu

grafa na slici 7.19 od cvora b i od cvora a. Pravougaoni oblik cvorova na toj


slici ukazuje na interval izmedu po etka i zavretka poziva algoritma dfs
c

za odgovaraju i cvor.
c
Podsetimo se da se tokom (viestruke) pretrage u dubinu grafa algo
c
ritam dfs poziva ta no jedanput za svaki cvor grafa. Zbog toga je vreme

zavretka poziva dfs(v) za svaki cvor v nedvosmisleno odredeno. Pretpo

216

Grafovi

e
1

9 10

S LIKA 7.22: Intervali trajanja poziva algoritma dfs na vremenskoj osi


tokom viestruke pretrage u dubinu grafa na slici 7.19.

stavimo da je tokom (viestruke) pretrage u dubinu grafa G dobijen niz

cvorova v1 , v2 , . . ., vn u redosledu koji je odreden po vremenu zavretka

c
poziva algoritma dfs za sve cvorove. To zna i da se tokom pretrage u
dubinu grafa G prvi zavrio poziv dfs(v1 ), zatim se zavrio poziv dfs(v2 )
i tako dalje, poslednji se zavrio poziv dfs(vn ). Recimo, u primeru na

slici 7.22 dobija se redosled cvorova e, c, d, b, a. Klju no zapaanje je da


c
je ovaj redosled zapravo obrnut topoloki redosled usmerenog acikli kog
c
grafa.
c
L EMA Neka je tokom (viestruke) pretrage u dubinu usmerenog acikli kog
grafa G dobijen niz cvorova v1 , v2 , . . ., vn u redosledu koji je odreden po

vremenu zavretka poziva algoritma dfs za sve cvorove. Ako je (v i , v j ) grana

grafa G, onda je i > j.


Dokaz: Neka je (v i , v j ) grana usmerenog acikli kog grafa G. Budu i da
c
c
(viestruka) pretraga u dubinu grafa G indukuje umu stabala pretrage u
dubinu, grana (v i , v j ) u G se moe klasikovati prema svom tipu kao grana
nekog stabla, direktna grana, povratna grana ili popre na grana. U stvari,
c
poto je G acikli ki graf, (v i , v j ) ne moe biti povratna grana, jer bi se njome
c
o evidno zatvorio jedan put u grafu G koji bi formirao usmeren ciklus.
c
U slu aju kada je (v i , v j ) grana stabla ili direktna grana, nije se teko
c

c
uveriti da je i > j. Naime, u tom slu aju je cvor v j potomak cvora v i , pa se
poziv dfs(v i ) svakako zavrava posle poziva dfs(v j ).
c
Najzad, ako je (v i , v j ) popre na grana, onda se mogu razlikovati dva

slu aja zavisno od toga da li cvorovi v i i v j pripadaju istom stablu ili razlic

citim stablima u umi pretrage u dubinu. Ipak, u oba slu aja smer grane
c

7.4. Obilazak usmerenog grafa

217

(v i , v j ) zdesna na levo ukazuje da je poziv dfs(v i ) zapo et posle zavretka


c
poziva dfs(v j ), pa se svakako poziv dfs(v i ) i zavrava posle zavretka
c
poziva dfs(v j ). A to upravo zna i da je i > j, to je trebalo pokazati.
Da bi se odredio topoloki redosled usmerenog acikli kog grafa G, doc
voljno je dakle modikovati osnovni algoritam dfs tako da se neporedno

pre njegovog zavretka cvor koji je njegov parametar dodaje na kraj jedne

povezane liste. Na taj na in se obrazuje lista cvorova v1 , v2 , . . ., vn u obrnuc


tom topolokom redosledu grafa G. Naravno, na kraju postupka nalaenja
topolokog redosleda treba jo samo obrnuti dobijenu listu. Drugi ekvivalentni pristup, koji smo zapravo primenili u modikovanom algoritmu dfs,
sastoji se u tome da se neporedno pre zavretka tog algoritma odgovaraju i
c

cvor dodaje na po etak povezane liste.


c
// Ulaz: usmeren acikliki graf G predstavljen listama susedstva
c
// Izlaz: lista vorova l u topolokom redosledu grafa G
c
algorithm topological-ordering(G)

// Svi cvorovi su poetno neposeeni


c
c
for (svaki vor v u nizu listi susedstva G ) do
c
p[v] = false;
list-make(l);

// l je poetno prazna lista


c

// Ispitati sve vorove grafa G


c
for (svaki vor v u nizu listi susedstva G ) do
c
if (p[v] == false) then
dfs-to(v);
// nova pretraga u dubinu od vora v
c
return l;

// Ulaz: vor u u grafu G predstavljen listama susedstva


c
// Izlaz: vor u dodat na poetak liste l na kraju pretrage u dubinu
c
c
algorithm dfs-to(u)
p[u] = true;

// vor u je poseen
c
c

// Ispitati susede vora u


c
for (svaki vor v u listi susedstva G za vor u) do
c
c
if (p[v] == false) then
dfs-to(v);
// rekurzivna pretraga od vora v
c
list-insert(u,null,l);
return;

// dodati vor u na poetak liste l


c
c

218

Grafovi

Vreme izvravanja algoritma topological-ordering za topoloki re


dosled usmerenog acikli kog grafa G sa n cvorova i m grana asimptotski je
c
o igledno jednako O(n + m).
c

Zadaci
1. Za usmeren graf G na slici 7.23 odgovorite na slede a pitanja.
c

a) Koliko cvorova i grana ima graf G?


b) Navedite sve proste puteve od a do b u G.

c) Navedite sve susede cvora b u G.

d) Navedite sve cikluse od cvora b u G.


G
b
a

c
f

e
d

S LIKA 7.23.

2. Odgovorite na ista pitanja iz prethodnog zadatka za neusmerenu verziju


grafa na slici 7.23. Neusmerena verzija se dobija zamenom svih usmerenih grana odgovaraju im neusmerenim granama tako to se strelice
c
samo zamene linijama.

3. Dokaite da ako se granom spoje bilo koja dva cvora u slobodnom stablu
T izmedu kojih ne postoji grana, onda se formira ta no jedan ciklus.
c

4. Dokaite da povezan neusmeren graf G sa n cvorova predstavlja slobodno stablo ako i samo ako G ima n 1 granu.

7.4. Obilazak usmerenog grafa

219

5. Predstavite graf G na slici 7.23 pomo u matrice susedstva i niza listi


c
susedstva.
6. Predstavite neusmerenu verziju grafa G na slici 7.23 pomo u matrice
c
susedstva i niza listi susedstva.

7. Za usmeren graf G predstavljen nizom listi susedstva svojih cvorova

potrebno je ponekad za svaki cvor imati i povezanu listu njegovih pret


hodnika, a ne samo njegovih sledbenika. Preciznije, za svaki cvor v

u G treba obrazovati povezanu listu svih cvorova u takvih da je (u, v)


usmerena grana u G. Napiite i analizirajte ekasan algoritam kojim
se obavlja ovaj zadatak konvertovanja reprezentacije grafa G.

8. Cvor s usmerenog grafa G sa n cvorova naziva se ponor ukoliko je ulazni

stepen cvora s jednak n 1 i njegov izlazni stepen jednak 0. Drugim

re ima, za svaki cvor v u G razli it od s postoji grana (v, s) i ne postoji


c
c
grana (s, v). Napiite algoritam vremenske sloenosti O(n) koji odreduje

vor koji
da li usmeren graf predstavljen matricom susedstva ima jedan c
je ponor.
9. Za usmeren graf G na slici 7.24 odgovorite na slede a pitanja.
c

a) Odredite talase cvorova W0 , W1 , W2 , . . . koji se dobijaju pretragom u

irinu grafa G od po etnog cvora e.


c
b) Konstruiite odgovaraju e stablo pretrage u irinu.
c

10. Odgovorite na ista pitanja iz prethodnog zadatka za neusmerenu verziju


grafa G na slici 7.24.
11. Napiite i analizirajte algoritam bfs za pretragu u irinu grafa koji

koristi jedan red za cekanje umesto vie posebnih listi W[i] za svaki

talas Wi . (Savet: U algoritmu se ispituju svi susedi onog cvora koji je

prvi u redu za cekanje, a cim se neki cvor otkrije prilikom ispitivanja,

dodaje se na kraj reda za cekanje.)

12. Neusmeren graf G = (V , E) je bipartitan ukoliko se njegovi cvorovi mogu


podeliti u dva disjunktna skupa takva da je svaka grana u G incidentna

220

Grafovi

G
b
a

c
h
e
g
d
f

S LIKA 7.24.

cvorovima iz ovih skupova. Formalno, V = X Y , X Y = i { u, v}


E u X i v Y . Na slici 7.25 je prikazan primer bipartitnog grafa.

S LIKA 7.25.
a) Pokaite da je svako slobodno stablo jedan bipartitan graf.
b) Napiite ekasan algoritam kojim se proverava da li je dati neusmeren graf bipartitan. (Savet: Koristite pretragu u irinu.)
13. Za usmeren graf G na slici 7.24, kao i za njegovu neusmerenu verziju,
odgovorite na slede a pitanja.
c
a) Navedite sve rekurzivne pozive algoritma dfs za graf G koji se
c
c
dobijaju za po etni poziv dfs(a) i uvla enjem nazna ite njihov
c

odnos. Pretpostavite da ako treba izabrati neki cvor izmedu vie

njih, onda se od mogu ih bira prvi cvor po abecednom redosledu.


c
b) Konstruiite odgovaraju e stablo (umu) pretrage u dubinu.
c
c) Klasikujte sve grane grafa G u odnosu na konstruisano stablo
prema tome da li predstavljaju grane stabla, direktne grane, povratne grane ili popre ne grane.
c

7.4. Obilazak usmerenog grafa

221

14. Napiite i analizirajte iterativnu (nerekurzivnu) verziju algoritma dfs

za pretragu u dubinu grafa od po etnog cvora s. (Savet: Rekurzivnu


c

strukturu pretrage u dubinu simulirajte stekom na koji se cvorovi sme


taju kako se pose uju, a sa vrha steka se uklanja cvor kada treba
c
ispitati sve njegove susede.)

15. Dokaite da u povezanom neusmerenom grafu G postoji cvor od koga su


njegova stabla pretrage u dubinu i irinu jednaka ako i samo ako je G
slobodno stablo. (Savet: Ova stabla su jednaka ako imaju jednake skupove grana, odnosno redosled u kojem se grane koriste tokom pretrage
u dubinu i irinu nije vaan.)
16. Napiite algoritam connected-components na strani 208 tako da se
za otkrivanje jedne komponente grafa koristi pretraga u irinu umesto
pretrage u dubinu grafa.

17. Navedite primer usmerenog grafa bez ciklusa sa n cvorova koji ima
(n2 ) grana. (Savet: Uo ite graf G = (V , E) kod koga je V = {1, 2, . . ., n} i
c
E = {(i, j) : i < j za i, j V }.)
18. Ako d(u, v) ozna ava duina najkra eg puta (rastojanje) izmedu cvorova
c
c

vora u je:
c
u i v u grafu G = (V , E), ekscentri nost c
max d(u, v).
v V

Ekscentri nost cvora u je dakle duina najdueg najkra eg puta koji


c
c
polazi od u. Napiite ekasan algoritam kojim se izra unava ekcentri c
c

nost svih cvorova usmerenog grafa. (Savet: Koristite pretragu u irinu.)


19. Neka je G usmeren graf i T jedno njegovo stablo u dubinu.
a) Dokaite da G ima usmeren ciklus ako i samo ako G ima povratnu
granu u odnosu na T.
b) Napiite ekasan algoritam kojim se proverava da li je G acikli ki
c
graf.
20. Neka je G usmeren acikli ki graf.
c

a) Dokaite da G sadri cvor bez ulaznih grana.

222

Grafovi

b) Dokaite indukcijom po broju cvorova grafa da G ima topoloki


redosled. (Savet: U dokazu indukcijskog koraka uo ite graf G {v}
c

dobijen uklanjanjem cvora v bez ulaznih grana.)


c) Koriste i indukcijski dokaz napiite drugi algoritam za nalaenje
c
topolokog redosleda grafa G.

21. Prost put u grafu je Hamiltonov ako prolazi kroz sve cvorove grafa. Napiite ekasan algoritam kojim se odreduje da li dati usmeren acikli ki
c

graf sadri Hamiltonov put. (Savet: Posmatrajte topoloki redosled


datog grafa.)

G LAVA

8
Teinski grafovi

U prethodnom poglavlju smo pokazali da se za nalaenje najkra eg


c

puta (rastojanja) izmedu dva cvora u povezanom grafu moe koristiti pre

traga u irinu. Naime, podsetimo se da i-ti talas otkrivenih cvorova tokom

pretrage u irinu sadri cvorove grafa koji se nalaze ta no na rastojanju


c

i od po etnog cvora. Pojam rastojanja u ovom slu aju podrazumeva da su


c
c
sve grane ravnopravne, odnosno da sve imaju istu teinu u izra unavanju
c
duine puteva u grafu. Medutim, u mnogim primenama ovaj pristup nije

odgovaraju i.
c
Graf moe predstavljati, na primer, neku ra unarsku mreu (kao to je
c

Internet) sa ra unarima kao cvorovima tog grafa i komunikacionim linkoc


vima izmedu pojedinih ra unara kao granama tog grafa. Ako je cilj na i
c
c

najbri na in za usmeravanje paketa podataka izmedu neka dva ra unara


c
c

u mrei, onda se to svodi na nalaenja najkra eg puta izmedu dva cvora


c

koji ozna avaju date ra unare u grafu. Ali u ovom slu aju nije prirodno
c
c
c
da sve grane grafa budu ravnopravne poto su neke veze u mrei ra uc
nara obi no mnogo bre od drugih neke grane mogu predstavljati spore
c
telefonske linije, dok druge predstavljaju brze opti ke veze.
c
Da bismo sli ne probleme modelirali grafovima, u ovom poglavlju proc
irujemo pojam grafa i posmatramo (usmerene ili neusmerene) grafove

cije grane imaju pridruenu numeri ku vrednost. Ove vrednosti dodeljene


c
granama nazivaju se teine grana, a odgovaraju i grafovi teinski grafovi.
c

224

Teinski grafovi

8.1

Osnovni pojmovi

Teinski graf je obi an (usmeren ili neusmeren) graf cije sve grane
c
imaju teinu u obliku numeri ke vrednosti. Primetimo da su teine grana
c
neutralni naziv za brojeve koji su pridrueni granama, ali u prakti nim
c
primenama ti brojevi mogu predstavljati razne druge zi ke veli ine kao
c
c

to su duina, vreme, cena, brzina ili neka druga mera odnosa dva cvora.
Primer jednog teinskog grafa je prikazan na slici 8.1.
a

100

200
120
350

300

S LIKA 8.1: Teinski graf.


Koncepti u vazi sa teinskim grafovima se bez izmena odnose kako
na neusmerene tako i na usmerene grafove. Zbog toga u ovom poglavlju
govorimo samo o neusmerenim teinskim grafovima, a zainteresovanim

citaocima ostavljamo da izloene probleme i reenja prilagode usmerenim


teinskim grafovima.
Teinski graf je formalno dakle graf G = (V , E) takav da svaka grana e u

E ima dodeljen broj w(e) koji odreduje njenu teinu. S obzirom na cinjenicu

da obi an graf moemo smatrati teinskim grafom cije su sve teine grana
c
jednake (na primer, moemo uzeti da su sve teine jednake 1), jasno je da
svi osnovni pojmovi za obi ne grafove imaju smisla i za teinske grafove.
c

Cak se i dve reprezentacije obi nih grafova u ra unarima, matrica suc


c
sedstva i niz listi susedstva, mogu lako prilagoditi za predstavljanje teinskih grafova. Podsetimo se da elementi matrice susedstva za obi an graf
c

mogu biti brojevi 1 ili 0 cime se odreduje da li grana izmedu neka dva cvora

postoji ili ne. U slu aju teinskih grafova, postojanje neke grane e i njena
c
teina w(e) zajedno se predstavljaju odgovaraju im elementom matrice suc
sedstva koji je jednak w(e). Ali zato ako neka grana ne postoji u grafu,
odgovaraju i element matrice susedstva mora biti neka vrednost koja nije
c
mogu a za teinu grane. Na slici 8.2 je prikazana matrica susedstva u kojoj
c
se za predstavljanje nepostoje e grane u teinskom grafu na slici 8.1 koristi
c
specijalni simbol .


8.2. Minimalno povezujuce stablo

a
b
c
d

200

b
100

80

225
c
120

d
350

300

S LIKA 8.2: Matrica susedstva za teinski graf na slici 8.1.

Niz listi susedstva za predstavljajnje obi nog grafa moe se lako pric
lagoditi za predstavljajnje teinskog grafa ukoliko se teina neke grane
e priklju i elementu povezane liste koji odreduje drugi kraj grane e. Na
c

slici 8.3 je prikazana reprezentacija teinskog grafa na slici 8.1 pomo u


c
niza listi susedstva.
a

b 100

c 120

80

d 300

d 350

b
c

a 200

S LIKA 8.3: Niz listi susedstva za teinski graf na slici 8.1.

8.2 Minimalno povezujuce stablo


Da bismo uveli pojam minimalnog povezuju eg stabla nekog teinskog
c
grafa, razmotrimo najpre jedan prakti an primer. Pretpostavimo da neka
c
kompanije ima vie predstavnitva u razli itim gradovima koje treba da
c
povee u jedinstvenu mreu. Da bi povezala sva svoja predstavnitva u
integrisanu mreu, za kompaniju je vano da odredi najmanju cenu iznajmljivanja telekomunikacionih linija izmedu svojih predstavnitava.

Ovaj problem se moe predstaviti teinskim grafom sa cvorovima koji


ozna avaju predstavnitva kompanije i granama sa numeri kim vrednoc
c
stima koje odgovaraju cenama zakupljenih prenosnih veza izmedu pojedi
nih predstavnitava. Na slici 8.4(a) je prikazan hipoteti ki graf koji predc
stavlja sve mogu e zakupljene linije izmedu odgovaraju ih predstavnitava
c
c

i njihove cene.

226

Teinski grafovi

20

10

20

10

2
5

3
6

d
(a)

3
6

d
(b)

S LIKA 8.4: Teinski graf predstavnitava hipoteti ke kompanije.


c

Nije teko do i do zaklju ka da najekonomi nije reenje za ovaj problem


c
c
c
treba da obuhvati podskup grana T datog grafa koji ispunjava ove uslove:

1. Grane u T moraju povezivati sve cvorove, jer je neophodno da bilo


koja dva predstavnitva kompanije mogu da medusobno komunici
raju, makar indirektno preko drugih predstavnitava.
2. Zbir cena grana u T mora biti najmanji, odnosno ne sme biti striktno
ve i od zbira cena bilo kog drugog podskupa grana datog grafa koje
c
ispunjavaju prvi uslov.
Primetimo odmah da najekonomi nije reenje T ne sadri ciklus, jer bi
c
u suprotnom mogla da se smanji njegova cena uklanjanjem bilo koje grane

u ciklusu. Pri tome povezanost izmedu bilo koje dva cvora datog grafa ne bi

bila ugroena. Jedno optimalno reenje T za graf na slici 8.4(a) prikazano


je pod (b) na istoj slici tako to su grane u T istaknute u grafu.
U optem slu aju, pretpostavimo da je dati teinski graf G = (V , E)
c
povezan i da su sve teine grana pozitivne. Problem o kome je re u primeru
c
kompanije sa vie predstavnitava je na i podskup grana T E takav da
c
podgraf (V , T) bude povezan i da ukupna teina eT w(e) grana u T bude
minimalna. Osnovno zapaanje u vezi sa ovim problemom je da svako
njegovo reenje (V , T) mora biti slobodno stablo, odnosno povezan graf bez
ciklusa.

L EMA Ako je (V , T) povezan podgraf teinskog grafa G = (V , E) cija je


ukupna teina grana najmanja, onda je (V , T) slobodno stablo.
Dokaz: Poto je (V , T) po deniciji povezan graf, treba se jo samo uveriti
u to da graf (V , T) ne sadri nijedan ciklus. Ali ako bi graf (V , T) sadrao
neki ciklus C, radi kontradikcije uo imo bilo koju granu e tog ciklusa C.
c


8.2. Minimalno povezujuce stablo

227

Onda bi graf (V , T e) i dalje bio povezan, jer svaki put u (V , T) izmedu

dva cvora koji koristi e moe i i zaobilazno u (V , T e) preko cvorova u


c
ostatku ciklusa C. Stoga je i graf (V , T e) jedno reenje za prethodni
problem. Uz to je reenje (V , T e) jeftinije od reenja (V , T), jer je
ukupna teina grana u grafu (V , T e) striktno manja za teinu grane
e. Ovo pritivre i pretpostavci da je (V , T) najjeftinije reenje navedenog
c
problema, to pokazuje da graf (V , T) ne moe imati nijedan ciklus.
Podgraf (V , T) obi nog (neteinskog) grafa G = (V , E) naziva se povezuc

ju e stablo grafa G ukoliko je (V , T) slobodno stablo. Cesto se radi jedc


c
nostavnosti sam podskup grana T E naziva povezuju e stablo, jer se

podrazumeva da ono sadri skup svih cvorova V datog grafa G. Nije teko
proveriti da povezuju e stablo grafa G postoji ako i samo ako je G povezan
c
graf.
U slu aju povezanog teinskog grafa G, zbir teina grana u nekom poc
vezuju em stablu T tog grafa nazivamo cenom stabla T. Problem nalaenja
c
povezuju eg stabla grafa G koje ima najmanju cenu, prema prethodnoj
c
lemi, zapravo je drugim re ima formulisan opti problem koji smo ilustroc
vali primerom kompanije sa vie predstavnitava: za dati teinski graf
c
G = (V , E) na i podskup grana T E tako da podgraf (V , T) bude povezan
i da ukupna teina grana u T bude minimalna. Zbog toga se reenje
T ovog problema naziva minimalno povezuju e stablo (engl. minimum
c
spanning tree) grafa G. Dakle, minimalno povezuju e stablo je stablo jer je
c

acikli ki graf; ono je povezuju e jer povezuje sve cvorove datog grafa; i ono
c
c
je minimalno jer ima najmanju cenu medu svim povezuju im stablima.
c

Sem ukoliko G nije vrlo prost graf, G moe imati ogroman broj po
vezuju ih stabala cija je struktura potpuno razli ita. Zbog toga na prvi
c
c
pogled nije uopte lako na i povezuju e stablo sa najmanjom cenom medu
c
c

svim mogu im kandidatima. Ipak, otkriveni su mnogi ekasni algoritmi


c
za nalaenje minimalnog povezuju eg stabla datog teinskog grafa. Intec

resantno je da se svi oni zasnivaju na relativno jednostavnoj cinjenici koju


zovemo svojstvo podele grafa.
L EMA ( SVOJSTVO PODELE GRAFA ) Neka je G = (V , E) povezan teinski
graf i neka su V1 i V2 dva neprazna disjunktna podskupa njegovog skupa
cvorova V takva da je V = V1 V2 . Ako je e jedinstvena grana najmanje

teine u E takva da joj je jedan kraj u V1 i drugi kraj u V2 , onda svako


minimalno povezuju e stablo grafa G sadri granu e.
c
Dokaz: Pretpostavimo da je e = {v1 , v2 } jedinstvena grana najmanje teine
od onih kod kojih je jedan kraj u V1 i drugi kraj u V2 . Neka je T bilo koje

228

Teinski grafovi

minimalno povezuju e stablo grafa G. (Primetimo da poto je G povezan


c
graf, G ima povezuju e stablo, pa zato ima i bar jedno minimalno povec
zuju e stablo.). Radi kontradikcije pretpostavimo da T ne sadri granu
c
e. Ako granu e ipak dodamo stablu T, formira e se ta no jedan ciklus C
c
c
u stablu T. (Podsetimo se da je ovo jedna od osobina slobodnog stabla).

U ovom ciklusu C koji sadri granu e kao most izmedu skupa cvorova

V1 i V2 mora postojati jo jedna grana e = {v1 , v2 } u T takva da v1 V1 i


v2 V2 . U suprotnom, ciklus C se ne moe zatvoriti u T, odnosno ne postoji

na in da idu i du ciklusa C dodemo, recimo, od cvora v1 nazad u cvor v1


c
c

bez ponovnog prelaenja preko grane e. Ovaj argument je ilustrovan na


slici 8.5.
V1

V2

v1

v1

v2

v2

S LIKA 8.5: Formiranje ciklusa u minimalnom povezuju em stablu


c
dodavanjem grane e.

Ako se sada ukloni grana e iz stabla T, prekida se jedini ciklus u T i

dobija se novo stablo T = T e koje povezuje sve cvorove grafa G. Naime,


svaki put u T koji je koristio granu e moe se zameniti drugim putem u T
koji ide zaobilazno izmedu cvorova v1 i v2 du ciklusa C.

Kako je grana e jedna od onih koje imaju jedan kraj u V1 i drugi kraj
u V2 , to je po pretpostavci teina grane e striktno manja od teine grane
e . Stoga je i cena stabla T striktno manja od cene stabla T. Ali to je
nemogu e, jer je T minimalno povezuju e stablo grafa G.
c
c
Prakti no svi algoritmi za konstruisanje minimalnog povezuju eg stac
c
bla teinskog grafa koriste na neki na in ovo svojstvo podele grafa radi
c
postupnog izbora njegovih grana koje pripadaju minimalnom povezuju em
c
stablu. Kruskalov i Primov algoritam su klasi ni predstavnici ovog pric
stupa.


8.2. Minimalno povezujuce stablo

229

Kruskalov algoritam
Radi konstruisanja minimalnog povezuju eg stabla teinskog grafa G =
c
(V , E), u Kruskalovom algoritmu se polazi od ume (V , ) koja se sastoji od

svih cvorova grafa G i nema nijednu granu. Drugim re ima, po etna uma
c
c

se sastoji od stabala koja cine pojedina ni cvorovi sami za sebe.


c
U algoritmu se zatim redom ispituju grane grafa u rastu em redosledu
c
njihovih teina. U svakom koraku kako se dolazi do neke grane e u ovom
redosledu, proverava se da li e proizvodi ciklus ukoliko se doda granama
koje su do tada izabrane za minimalno povezuju e stablo. Ta nije, ako
c
c

grana e povezuje dva cvora iz dva razli ita stabla do tada konstruisane
c
ume, onda se e dodaje skupu izabranih grana i ta dva stabla se objedinjuju

u jedno stablo. U suprotnom, ako e povezuje dva cvora iz istog stabla do


tada konstruisane ume, onda se e odbacuje jer bi proizvela ciklus. Na
slici 8.6 je prikazano postupno izvravanje Kruskalovog algoritma za graf
na slici 8.4(a).
(0)

(1)

(2)

f
2

b
1

(3)

(4)

(5)

b
1

b
1

S LIKA 8.6: Izvravanje Kruskalovog algoritma za graf na slici 8.4(a).

Ispravnost Kruskalovog algoritma je neposredna posledica svojstva podele grafa.

230

Teinski grafovi

L EMA Kruskalov algoritam konstruie minimalno povezuju e stablo povec


zanog teinskog grafa G.
Dokaz: Pretpostavimo privremeno da su sve teine grana u grafu G =

(V , E) medusobno razli ite, a na kraju cemo pokazati kako moemo elimic

nisati ovu pretpostavku.


Razmotrimo bilo koju granu e = { u, v} koja je u Kruskalovom algoritmu

dodata umi (stablu) T u k-tom koraku. Neka je A skup svih cvorova

povezanih putem sa cvorom u u T i B skup svih cvorova povezanih putem

sa cvorom v u T u trenutku neposredno pre dodavanja grane e. O igledno


c
su A i B disjunktni skupovi, jer bi se u suprotnom slu aju dodavanjem
c
grane e obrazovao ciklus u T.
c
Neka je V1 = A i V2 = V A, pa je u V1 i v V2 . Drugim re ima, V1 i V2

su neprazni disjunktni podskupovi cvorova takvi da je V = V1 V2 . Pored


toga, nijedna druga grana pre k-tog koraka nije imala jedan kraj u V1 i
c
drugi kraj u V2 , jer bi u suprotnom takva grana bila ve dodata poto ne
obrazuje ciklus u T. Zato je e grana najmanje teine izmedu V1 i V2 u grafu

G, a uz to je i jedinstvena s tom osobinom jer su sve teine grana razli ite.


c
Prema svojstvu podele grafa dakle, grana e pripada svakom povezuju em
c
stablu grafa G.
Stoga ukoliko jo pokaemo da je zavrna uma T koja je rezultat Kru
skalovog algoritma zapravo povezuju e stablo grafa G, onda ce to autoc
matski zna iti da je T ujedno i minimalno povezuju e stablo. O igledno je
c
c
c
da T ne sadri nijedan ciklus, jer se u Kruskalovom algoritmu eksplicitno
odbacuju grane koje obrazuju neki ciklus. Isto tako, zavrna uma T ne
moe se sastojati od dva nepovezana disjunktna stabla T i T (ili vie
njih), jer je graf G povezan i postoji bar jedna grana izmedu T i T , pa

ce se u algoritmu od tih grana dodati u T ona prva na koju se naide u

rastu em redosledu teina.


c
Ostalo je jo da pokaemo optimalnost Kruskalovog algoritma u slu aju
c
kada neke grane grafa G imaju jednake teine. U tom slu aju zamislimo da
c
smo od grafa G obrazovali novi teinksi graf G tako to smo teinama svih
grana sa jednakim teinama u G dodali razli ite ekstremno male vrednosti
c
kako bi njihove nove teine bile medusobno razli ite. Takve vrednosti uvek
c

moemo izabrati tako da se ne promeni relativni redosled cena originalnih


povezuju ih stabala grafa G.
c
Nije se teko uveriti da je svako minimalno povezuju e stablo T noc
c
vog grafa G ujedno i minimalno povezuju e stablo originalnog grafa G.
(Obrnuto, naravno, ne mora biti ta no.) Naime, poto G i G imaju istu
c


8.2. Minimalno povezujuce stablo

231

strukturu, ti grafovi imaju ista povezuju a stabla. Ali ako bi stara cena
c
stabla T bila ve a od stare cene nekog drugog povezuju eg stabla grafa G,
c
c
onda za dovoljno male promene teina grana ne bi cena tog drugog stabla
mogla da se uve a toliko da stablo T bude bolje sa novim teinama u G . To
c
pokazuje da je T minimalno povezuju e stablo i za graf G. Kako su teine
c

c
grana novog grafa G medusobno razli ite, Kruskalov algoritam ce prema

prethodnom delu dokaza konstruisati njegovo minimalno povezuju e stac


blo T koje je optimalno i za originalni graf G.
Implementacija Kruskalovog algoritma. U Kruskalovom algoritmu

se polazi od ume stabala koja se sastoje samo od pojedina nih cvorova


c
grafa bez ijedne grane. Ova po etna trivijalna stabla u umi se zatim
c
proiruju dodavanjem grana koje nikad ne proizvode ciklus.
U realizaciji Kruskalovog algoritma potrebno je zato voditi priciznu evi
deniciju o tome koji disjunktni podskupovi cvorova grafa pripadaju kojim
stablima u umi koja se postupno transformie u minimalno povezuju e
c
stablo. Pored toga, kako se neka grana e = { u, v} ispituje u svakom koraku,
potrebno je ekasno odrediti kojim stablima u umi pripadaju njeni krajevi
u i v. Ako su ova stabla razli ita, onda se grana e dodaje jer ne proizvodi
c

ciklus i dva odgovaraju a skupa cvorova se objedinjuju u jedan skup koji


c
odgovara novom stablu u umi. Ako krajevi u i v grane e pripadaju istom
stablu, onda se grana e preska e jer bi proizvela ciklus u tom stablu.
c
Za ekasnu realizaciju Kruskalovog algoritma potrebno je dakle ta no
c
ono to obezbeduje struktura podataka disjunktnih skupova o kojoj smo

govorili u odeljku 6.5 na strani 177. Citaoci se mogu podsetiti da se tom


strukturom podataka predstavljaju disjunktni skupovi nekih elemenata.

U slu aju Kruskalovog algoritma elementi skupova su cvorovi grafa. Za


c

dati cvor u, operacija ds-find(u) kao rezultat daje ime skupa cvorova koji

sadri u. Ova operacija se onda moe iskoristiti za utvrdivanje da li cvorovi

u i v pripadaju istom skupu tako to se prosto proveri da li je ds-find(u)


jednako ds-find(v). Isto tako, struktura podataka disjunktnih skupova
sadri operaciju ds-union(u,v) kojom se disjunktni skupovi koji sadre u
i v objedinjuju u jedan skup.
Koriste i ova zapaanja, Kruskalov algoritam na pseudo jeziku za nac
laenje minimalnog povezuju eg stabla povezanog teinskog grafa G sa n
c

cvorova i m grana je:


// Ulaz: povezan teinski graf G
// Izlaz: minimalno povezujue stabla T grafa G
c
algorithm mst-kruskal(G)

232

Teinski grafovi

Obrazovati obian niz od grana grafa G sa pridruenim teinama;


c
Preurediti taj niz u rastuem redosledu teina grana.
c
Neka je e 1 , e 2 ,... , e m dobijeni niz sortiranih grana;
T =
// uma T je poetno bez grana
c
// ... ali svi vorovi su njena stabla
c
for (svaki vor v u grafu G ) do
c
ds-make(v);
for i = 1 to m do
Neka je e i = { u, v};
a = ds-find(u);
b = ds-find(v);
if (a != b) then
T = T + ei;
ds-union(a,b);

//
//
//
//
//

ime skupa kome pripada u


ime skupa kome pripada v
skupovi koji sadre u i v nisu isti
dodati granu e i umi T
objediniti skupove koji sadre u i v

return T;

Vreme izvravanja algoritma mst-kruskal moe se odrediti ukoliko se


saberu vremena izvravanja njegovih glavnijih delova:
Ako je graf G predstavljen matricom susedstva ili nizom listi susedstva, nije se teko uveriti da se obi an niz njegovih grana sa pridruc
enim teinama moe lako obrazovati za vreme O(m).
Za sortiranje tog niza u rastu em redosledu po teinama grana moe
c
se iskoristiti neki ekasan algoritam za sortiranje tako da vreme
potrebno za preuredivanje niza grana iznosi O(m log m).

Vreme izvravanja prve for petlje u kojoj se inicijalizuje n disjunktnih skupova iznosi O(n), jer za inicijalizaciju jednog skupa treba
konstantno vreme.
Telo druge for petlje se izvrava m puta, a svaka iteracija se izvrava
za vreme O(log n) ukoliko su operacije sa disjunktnim skupovima
realizovane onako kako smo to opisali na strani 177. Prema tome,
ukupno vreme izvravanja druge for petlje je O(m log n).
Kako za povezan graf vai da je m n 1, to je n = O(m). Takode,

c
poto uvek vai m n2 , to je log m = O(log n). Uzimaju i sve u obzir dakle,
ukupno vreme izvravanja algoritma mst-kruskal je:
O(m) + O(m log m) + O(n) + O(m log n) =
O(m) + O(m log n) + O(m) + O(m log n) = O(m log n) .


8.2. Minimalno povezujuce stablo

233

Primov algoritam
U Kruskalovom algoritmu se pohlepno biraju grane najmanje teine
bez mnogo obzira na to u kakvom odnosu stoje sa prethodno izabranim
granama, osim to se pazi da se ne formira ciklus. Na ovaj na in se doc
bija uma stabala koja se ire prili no nasumi no dok se ne stope u jedno
c
c
zavrno stablo.
Nasuprot tome, u Primovom algoritmu se dobija minimalno povezuju e
c
stablo tako to se po etno najprostije stablo postupno proiruje. To po etno
c
c

stablo je neki proizvoljno izabran cvor s, a u svakom koraku se delimi no


c

konstruisanom stablu dodaje novi cvor na drugom kraju grane najmanje


teine koja izlazi iz tog stabla. Preciznije, u svakom koraku se obrazuje

c
c
podskup cvorova S V nad kojim je delimi no konstruisano povezuju e

c
stablo. Po etno je S = { s} i zatim se S postupno uve ava za jedan cvor v
c
kojim se minimizuje cena uve anja skupa S:
c
min w(e).

e={u,v}
uS,vS

U svakom iteraciji Primovog algoritma se dakle grana e = { u, v} za koju se

postie ovaj minimum i cvor v dodaju povezuju em stablu grafa G koje se


c
konstruie. Na slici 8.7 je ilustrovana jedna iteracija Primovog algoritma
u kojoj je grana e = { u, v} izabrana kao grana minimalne teine od onih kod
kojih je jedan kraj u S i drugi kraj je izvan S.
G

S
v

S LIKA 8.7: Jedna iteracija Primovog algoritma.


Na slici 8.8 je prikazano postupno izvravanje Primovog algoritma za

graf na slici 8.4(a) ukoliko je po etni cvor izabran da bude cvor a.


c

234

Teinski grafovi

(0)

(1)

(2)

a
f

a
f

(3)

(4)

(5)

a
f

a
f

8
2

b
1

S LIKA 8.8: Izvravanje Primovog algoritma za graf na slici 8.4(a) od

po etnog cvora a.
c

Ispravnost Primovog algoritma je takode neposredna posledica svojstva

podele grafa.
c
L EMA Primov algoritam konstruie minimalno povezuju e stablo povezanog teinskog grafa G.
Dokaz: Ispravnost Primovog algoritma se dokazuje vrlo sli no Kruskaloc

vom algoritmu. Zbog toga cemo pokazati samo da se i u Primovom algoritmu u svakom koraku dodaje grana koja pripada svakom minimalnom
povezuju em stablu grafa G.
c
Ali to je u Primovom algoritmu jo o iglednije, jer u svakom koraku
c

postoji podskup cvorova S nad kojim je delimi no konstruisano povezuju e


c
c
stablo. Pri tome se bira grana minimalne teine e sa jednim krajem u

S i drugim krajem v u V S, pa se grana e i cvor v dodaju stablu koje


se konstruie. Stoga na osnovu svojstva podele grafa neposredno sledi da
grana e pripada svakom minimalnom povezuju em stablu grafa G.
c


8.2. Minimalno povezujuce stablo

235

Implementacija Primovog algoritma. Da bi se ekasno realizovao

Primov algoritam, mora se paljivo voditi evidencija o skupu cvorova S i


skupu grana T koji pripadaju delimi no konstruisanom povezuju em stac
c

blu grafa G. Pored toga, grane ciji je samo jedan kraj u skupu S moraju se
organizovati na na in koji omogu ava da se moe brzo izabrati takva grana
c
c
minimalne teine. Zbog toga se u ralizaciji Primovog algoritma koriste ove
strukture podataka:
Za skup grana T delimi nog stabla koristi se reprezentacija u obliku
c
povezane liste kako bi dodavanje grane u T moglo da se izvri za
konstantno vreme.

Za skup cvorova S delimi nog stabla potrebna je reprezentacija koja


c

omogu ava da operacije provere clanstva i dodavanja novog elementa


c
skupu mogu da se izvre za konstantno vreme. Obi na reprezentacija
c
pomo u karakteristi nog niza skupa S zadovoljava ovaj uslov. Duina
c
c

ovog niza jednaka je broju cvorova grafa G i elementi niza su indek vorovima. Pored toga, svaki element niza ima vrednost
sirani tim c
ta no ili neta no prema tome da li odgovaraju i cvor pripada skupu
c
c
c
S.
Da bi se brzo odredila slede a grana koju treba dodati delimi nom
c
c

stablu, koristi se red sa prioritetima ciji su elementi grane grafa


G. Preciznije, svaki element tog reda ima dva polja: jedno polje
c
sadri granu e = { u, v} i drugo polje sadri njenu teinu w(e). Za klju
(prioritet) odgovaraju eg elementa u redu uzima se teina grane u
c
drugom polju.
Imaju i ove napomene u vidu i pretpostavljaju i reprezentaciju grafa
c
c
G pomo u niza listi susedstva, Primov algoritam za nalaenje minimalnog
c
povezuju eg stabla grafa G moe se preciznije izraziti na pseudo jeziku na
c
slede i na in:
c
c
// Ulaz: povezan teinski graf G
// Izlaz: minimalno povezujue stabla T grafa G
c
algorithm mst-prim(G)

Proizvoljno izabrati cvor s u G ;


S = { s }; T =
// inicijalizovati delimino stablo
c
Q = ;
// konstruisati prazan red sa prioritetima
for (svaka grana e = { s, x} u grafu G ) do
pq-insert(Q,(w(e), e ));
while (Q !=

) do

236

Teinski grafovi

e = pq-deletemin(Q);
Neka je e = { u, v};
T = T + e ; // granu e dodati granama deliminog stabla
c
S = S + v; // drugi kraj v grane e dodati vorovima
c
// deliminog stabla
c
for (svaka grana e = {v, x} za koju x S ) do
pq-insert(Q,(w(e), e ));
return T;

U vremenu izvravanja algoritma mst-prim dominiraju dve petlje: u


prvoj for petlji se inicijalizuje red sa prioritetima Q, dok se u drugoj while

petlji konstruie minimalno povezuju e stablo. Za graf G sa n cvorova i m


c
grana vreme izvravanja for petlje je O(n log n), poto se u njoj izvrava
najvie n operacija dodavanja elementa u red sa prioritetima veli ine najc
vie n. Sli no, u while petlji se izvrava najvie m operacija dodavanja
c
i uklanjanja za red elemenata sa prioritetima duine najvie m. Poto
se dodatne operacije u svakoj iteraciji te petlje izvravaju za konstantno
vreme, vreme izvravanja while petlje iznosi O(m log m). Ukupno vreme
izvravanja algoritma mst-prim je dakle:
O(n log n) + O(m log m) = O(m log n) .

Kao zaklju ak se prema tome moe izvesti cinjenica da Primov i Kruc


skalov algoritam za nalaenje minimalnog povezuju eg stabla grafa imaju
c
asimptotski jednako vreme izvravanja.

8.3 Najkraci putevi od jednog cvora

Grafovi se cesto koriste za modeliranje mrea u kojima se prelazi neki


put od jedne ta ke do druge na primer, od jednog grada do drugog preko
c
puteva kojima su gradovi povezani ili od jednog ra unara do drugog preko
c
komunikacionih linkova kojima su ra unari povezani. Zbog toga je jedan
c
od osnovnih algoritamskih problema za grafove nalaenje najkra ih puteva
c
izmedu cvorova u grafu.

Neka je dat povezan teinski graf G = (V , E). U vezi sa problemom
nalaenja najkra ih puteva u grafu G prirodnije je podrazumevati da nuc
meri ke vrednosti pridruene granama grafa predstavljaju njihovu duinu,
c
a ne teinu. (Naravno, duina ili teina mogu stvarno predstavljati neto

sasvim tre e, recimo, vreme ili cenu.) Tome cemo se prilagoditi u izlaganju
c

8.3. Najkraci putevi od jednog cvora

237

do kraja ovog poglavlja i govoriti da svaka grana e = { u, v} u teinskom


grafu G ima pridruenu duinu (e) 0 koja predstavlja meru prelaska u

jednom koraku od cvora u do cvora v.


Za neki put P u grafu G, duina tog puta (P) je prosto zbir duina svih

grana na putu P. Formalno, ako se put P sastoji od cvorova v1 , v2 , . . ., vk i


grana e i = {v i , v i+1 } izmedu njih, onda je:

(P) =

k 1

(e i ) .
i =1

Problem najkra ih puteva od jednog cvora sastoji se u tome da se za


c

dati cvor s u teinskom grafu G odrede najkra i putavi od tog cvora s do


c

svih ostalih cvorova u grafu G. (Interesantno je da naizgled jednostavniji

problem nalaenja najkra eg puta od jednog datog cvora do drugog datog


c

cvora ima istu sloenost u optem slu aju kao problem najkra ih puteva
c
c

od jednog datog cvora do svih ostalih cvorova.) Jedno ekasno reenje za


ovaj problem prvi je predloio Edsger Dijkstra i po njemu se ono naziva
Dijkstrin algoritam.

Dijkstrin algoritam

Podsetimo se da se problem nalaenja najkra ih puteva od jednog cvora


c
u specijalnom slu aju obi nog grafa, kod koga su sve grane jednake duine,
c
c
moe reiti pretragom u irinu. U Dijkstrinom algoritmu se ovaj pristup
generalizuje za teinski graf tako to se na odreden na in primenjuje ponc

derisana pretraga u irinu od datog cvora. Radi jednostavnijeg izlaganja

Dijkstrinog algoritma, najpre cemo pojednostaviti problem i pretpostaviti

da se trae samo duine najkra ih puteva od cvora s do svih ostalih cvorova


c
u grafu same najkra e puteve je u algoritmu lako rekonstruisati.
c
Sutinska odlika Dijkstrinog algoritma je da se najkra i putevi od dac

tog cvora s do ostalih cvorova otkrivaju u rastu em redosledu duina najc

kra ih puteva. U algoritmu se postupno konstruie skup cvorova S takav


c

da je za svaki cvor u u S odredena duina najkra eg puta d(u) od cvora s.


c

To se skup reenih cvorova grafa G. Na po etku je S = { s} i d(s) = 0.


c

Da bi se u narednoj iteraciji skup reenih cvorova S proirio za jedan

c
cvor, za svaki nereen cvor v u V S se odreduje duina najkra eg speci

jalnog puta od s do v. Specijalni put do cvora v je neki put koji po inje


c
vora s, zatim prolazi samo kroz reene cvorove i, na samom kraju,

od c

dolazi do nekog cvora u S i zavrava se jednom granom u cvoru v. Jedan

specijalni put do cvora v je ilustrovan na slici 8.9.

238

Teinski grafovi
G
S
reeni

cvorovi
s

specijalni
put

S LIKA 8.9: Specijalni put od s do v u Dijkstrinom algoritmu.

Drugim re ima, za svaki nereen cvor v izvan skupa S odreduje se


c

veli ina
c
(v) = min d(u) + (e).
e={u,v}
u S

Nakon toga, radi proirenja skupa S, bira se cvor x za koji se ova veli ina
c

minimizuje, odnosno bira se cvor x takav da je (x) = minvV S (v). Taj

cvor se dodaje skupu S i za njegovu duinu najkra eg puta d(x) uzima se


c

(x). Skup S se proiruje na ovaj na in za jedan cvor sve dok se ne obuhvate


c

svi cvorovi iz skupa V grafa G.


Verovatno nije odmah jasno zato je ovaj postupak ispravan. Zato da
bismo ga bolje razumeli, posmatrajmo jedno mogu e stanje izvravanja
c
Dijkstrinog algoritma koje je prikazano na slici 8.10.

1
4

x
2

2
3

S LIKA 8.10: Primer izvravanja Dijkstrinog algoritma.

8.3. Najkraci putevi od jednog cvora

239

U trenutku izvravanja Dijkstrinog algoritma na slici 8.10 zavrene su

dve iteracije: skup S je u prvoj iteraciji bio proiren za cvor u i u drugoj

za cvor v. U tre oj iteraciji bi se dodao cvor x, jer se za taj cvor postie


c
najmanja vrednost (x). Naime, (x) = min{1 + 1, 0 + 4, 2 + 2} = 2, (y) =

1 + 3 = 4 i (z) = 2 + 3 = 5. Obratite panju na to da bi dodavanje cvora y ili

z skupu S u ovom trenutku bilo pogreno; oni ce se ipak ispravno dodati u

narednim iteracijama zbog grana koje ih povezuju sa cvorom x.


Primetimo da se u svakoj iteraciji Dijkstrinog algoritma trai najkra i
c

specijalni put od cvora s i da se skupu S dodaje cvor x koji se nalazi na


kraju tog puta. Takode, taj najkra i specijalni put P x od s do x proglaava
c

se za globalno najkra i put od s do x, odnosno vrednost d(x) izjedna ava se


c
c
c
sa (x). Zato je ovaj pristup ispravan? Klju ni razlog je to to su duine
svih grana u grafu nenegativne u stvari, ukoliko je duina neke grane
negativna, rezultat Dijkstrinog algoritma moe biti pogrean.
Da bismo pokazali da ne postoji kra i put od s do x u grafu G, posmac
trajmo bilo koji drugi put P od s do x. Ovaj put mora negde iza i iz skupa
c

S, jer je cvor x izvan S. Neka je y prvi cvor na putu P koji nije u S i neka
je P y deonica puta P od s do y. Kao to je prikazano na slici 8.11, put P iza

cvora y moe krivudati unutar i izvan skupa S nekoliko puta dok se najzad

ne zavri u cvoru x.
G
S
Px

x
u

s
v

S LIKA 8.11: Najkra i specijalni put P x i proizvoljni put P od cvora s do


c
vora x ciji je prvi deo do cvora y specijalan.

c
Kako je P y jedan od specijalnih puteva od cvora s i P x je najkra i takav
specijalni put, to je (P y ) (P x ). Sa druge strane, (P) (P y ) jer su
duine grana nenegativne. Ove dve nejednakosti zajedno daju (P) (P x ),
to pokazuje da duina svakog puta P od s do x nije kra a od duine
c

240

Teinski grafovi

puta P x . Preciznije tvrdenje o ispravnosti Dijkstrinog algoritma moe se

formulisati na slede i na in:


c
c

L EMA Skup S u toku izvravanja Dijkstrinog algoritma sadri cvorove x

takve da je d(x) duina najkra eg puta P x od cvora s do cvora x.


c

Dokaz: Dokaz tvrdenja izvodimo indukcijom po broju cvorova u S. U ba


c
znom slu aju za S = { s} tvrdenje je o igledno, jer je d(s) = 0. Pretpostavimo
c

da je tvrdenje ta no kada S ima k 1 cvorova i pokaimo da ono vai i za


c

skup S uve an za jedan cvor x u Dijkstrinom algoritmu.


c
Neka je grana { u, x} poslednja grana na specijalnom putu P x . Kako je

u neki cvor u S, po indukcijskoj pretpostavci je d(u) duina najkra eg puta


c

P u od cvora s do cvora u. Neka je P bilo koji drugi put u grafu od s do x;


na cilj je da pokaemo da njegova duina nije manja od duine puta P x .

Put P mora negde iza i iz skupa S, jer je cvor x izvan S. Neka je y prvi
c

cvor na putu P koji nije u S i neka je cvor v u S odmah ispred cvora y na


putu P (slika 8.11).

Neka je P deonica puta P od s do v. Kako je cvor v u S, po indukcijskoj


c
pretpostavci duina puta P nije manja od duine najkra eg puta od s do
v, odnosno (P ) d(v). Stoga deonica puta P od s do y ima duinu (P ) +

(v, y) d(v)+ (v, y) (y). Poto je u Dijkstrinom algoritmu cvor x izabran


c
da bude dodat skupu S, to je (y) (x) = d(x) = (P x ). Uzimaju i sve ovo

u obzir, kao i cinjenicu da duina deonice puta P od s do y nije manja od


duine celog puta P jer su grane nenegativne, najzad dobijamo traenu
nejednakost (P) (P ) + (v, y) (y) (x) = d(x) = (P x ).

Implementacija Dijkstrinog algoritma. Za teinski graf G sa n cvorova i m grana, u Dijkstrinom algoritmu se izvrava n 1 iteracija doda
vanja novog cvora x skupu S. Na prvi pogled, u svakoj iteraciji se zahteva

ispitivanje svakog cvora v u V S i svih grana izmedu cvorova u S i cvora


v radi izra unavanja najpre minimuma (v) i zatim izbora cvora x za koji
c
se postie najmanji od ovih minumuma. U najgorem slu aju dakle vreme
c
izvravanja svake iteracije moe biti O(m), pa bi ukupno vreme izvravanja
Dijkstrinog algoritma bilo O(mn).
Da bi se ekasnost Dijkstrinog algoritma znatno unapredila, moraju
se koristiti prave strukture podataka. Pre svega, da se ne bi nepotrebno
u svakoj iteraciji ponovo izra unavale duine najkra ih specijalnih puteva
c
c
vorova u V S, one se cuvaju u nizu d duine n koji je indeksiran

do c

cvorovima grafa G. Ta nije, za svaki reen cvor v u S, element d(v) jednak


c

je duini globalno najkra eg puta od s do v, dok za svaki nereen cvor v u


c

8.3. Najkraci putevi od jednog cvora

241

V S, element d(v) jednak je duini najkra eg specijalnog puta od s do v.


c
Po etno je dakle d(s) = 0 i d(v) = (s, v) ukoliko u grafu G postoji grana od
c
s do v ili po konvenciji d(v) = ukoliko takva grana ne postoji.
Dodatno poboljanje moe se obezbediti u svakoj iteraciji kada se bira

nereen cvor x koji ima najmanju vrednost d(x) od svih nereenih cvorova.
Radi ekasne realizacije tog postupka moe se postupiti na sli an na in
c
c
kao kod Primovog algoritma i koristiti struktura podataka reda sa priori
tetima za sve nereene cvorove u V S. Ako jedan element takvog reda

predstavlja cvor v u V S sa prioritetom jednakim elementu d(v) u nizu d,


onda se moe ekasno odrediti element tog reda sa najmanjim prioritetom,

odnosno nereen cvor x koji ima najkra u duinu d(x) specijalnog puta od
c

cvora s.

Nakon dodavanja izabranog cvora x skupu S, mora se uzeti u obzir da je

cvor x reen i da moda postoje kra i specijalni putevi koji vode do njegovih
c

suseda. Zbog toga se mora proveriti vrednost d(v) za svaki nereen cvor v

koji je susedan cvoru x. Naime, za svaki takav cvor v, novi specijalni put
do v prati put od s do x u novom S i zavrava se granom { x, v}. Taj novi

c
specijalni put do cvora v ima duinu d(x) + (x, v), pa ako je taj put kra i od
postoje eg najkra eg specijalnog puta do v duine d(v), ta stara vrednost
c
c
c
d(v) mora se aurirati vredno u d(x) + (x, v). Jedan primer ovog slu aja
c
prikazan je na slici 8.12.
d(x) = 11

d(x) = 11

v
s
d(s) = 0

d(v) = 20

d(v) = 17

s
d(s) = 0

S LIKA 8.12: Podeavanje nereenog cvora v.


U slu aju kada vrednost d(x) + (x, v) nije manja od stare vrednosti d(v)
c

nereenog cvora v, novi specijalni put do v nije kra i od postoje eg, pa stara
c
c
vrednost d(v) treba da ostane nepromenjena. Oba slu aja podeavanja
c

vrednosti d(v) nereenog cvora v koji je susedan novododatom cvoru x


mogu se kra e zapisati u obliku d(v) = min d(v), d(x) + (x, v) . Ova opec

racija podeavanja duine najkra eg specijalnog puta do nereenog cvora


c
naziva se poputanje. Metafora za ovaj termin je stanje opruge koja se
najpre napinje i zatim oputa do svog normalnog oblika u stanju mirovanja.
Precizniji zapis Dijkstrinog algoritma na pseudo jeziku kojim su obu-

242

Teinski grafovi

hva ene prethodne napomene je:


c

// Ulaz: teinski graf G , cvor s u G


// Izlaz: niz d duina najkaih puteva od s do svih vorova
c
c
algorithm dijkstra(G,s)
S = {s};
d[s] = 0;
for (svaki vor v = s u G ) do
c
if ({s,v} grana u G ) then
d[v] = (s, v);
else
d[v] = ;
while (S = V ) do
Odrediti vor x V S za koji je d[x] najmanje;
c
S = S + x;
for (svaki vor v V S koji je spojen granom sa x) do
c
d[v] = min{d[v], d[x] + (x, v)} // poputanje
return d;

Na slici 8.13 je ilustrovano izvravanje algoritma dijkstra za jedan

dati graf i cvor u tom grafu.


1

20

10

7
5

3
2
4

4
6

iteracija

d(1)

d(2)

d(3)

d(4)

d(5)

d(6)

{1}

20

10

{1, 6}

20

10

12

11

{1, 3, 6}

17

10

12

11

{1, 3, 5, 6}

17

10

12

11

{1, 3, 4, 5, 6}

13

10

12

11

{1, 2, 3, 4, 5, 6}

13

10

12

11

S LIKA 8.13: Izvravanje Dijkstrinog algoritma za graf G i s = 1.

8.4. Najkraci putevi izmedu svih cvorova

243

Radi analize Dijkstrinog algoritma, pretpostavimo da je ulazni graf G


predstavljen nizom listi susedstva i da se za realizaciju reda sa prioritetima
koristi binarni min-hip. Onda se inicijalizacija hipa izvrava za vreme

O(n). Izbor cvora x S koji minimizuje rastojanja d sastoji se od uklanjanja

korena iz hipa, to se izvrava za vreme O(log n). Dodavanje cvora x skupu


S izvrava se za konstantno vreme ukoliko je skup S predstavljen, recimo,
povezanom listom. Postupak poputanja se sastoji od ispitivanja svake

grane koja povezuje cvor x i nekog njegovog suseda v koji se nalazi izvan
c
novog S radi provere da li je d(x) + (x, v) < d(v). Ako je to slu aj, mora se

promeniti vrednost d(v) i cvor v s tim promenjenim prioritetom pogurati


uz hip, to se opet izvrava za vreme O(log n). Primetimo da se ovo radi
najvie jedanput po svakoj grani grafa.
Prema tome, u algoritmu dijkstra se obavlja n 1 operacija ukla
njanja korena iz hipa i najvie m operacija pomeranja cvora na njegovo
pravo mesto u hipu. Ukupno vreme za izvravanja tih operacija je dakle
O((n + m) log n). Ako je dati graf povezan, onda je m n 1, pa se u
tom slu aju vreme izvravanja Dijkstrinog algoritma moe kra e izraziti
c
c
u obliku O(m log n).

8.4 Najkraci putevi izmedu svih cvorova

Problem najkra ih puteva izmedu svih cvorova sastoji se u nalaenju


c

najkra ih puteva izmedu svaka dva cvora u teinskom grafu G. Ako u


c

grafu nema negativnih grana, onda se ovaj problem moe reiti viestru
kim izvravanjem Dijkstrinog algoritma od svakog cvora grafa. Ukoliko

G ima n cvorova i m grana, vreme potrebno za ovo reenje je O(nm log n),
pod pretpostavkom da je graf G povezan i predstavljen nizom listi susedstva. U najgorem slu aju kada je ulazni graf gust, odnosno m = (n2 ), ovo
c
c
vreme iznosi O(n3 log n). U najboljem slu aju kada je graf redak, odnosno
2
m = (n), ovo vreme iznosi O(n log n).

U ovom odeljku cemo pokazati drugi na in za reavanje problema nac

laenja najkra ih puteva izmedu svih cvorova koji se moe primeniti cak
c

i u slu aju kada graf sadri grane negativne duine (ali ne i cikluse nec
gativne duine). Taj na in se po svom autoru naziva Flojdov algoritam
c
i pripada kategoriji algortama dinami kog programiranja. U ovom algoc
ritmu se pretpostavlja da je ulazni graf predstavljen matricom susedstva i
njegovo vreme izvravanja je O(n3 ).

244

Teinski grafovi

Flojdov algoritam. Flojdov algoritam za reenje problema nalaenja

najkra ih puteva izmedu svih cvorova je konceptualno jednostavniji od


c

Dijkstrinog algoritma, mada reava o igledno tei problem.


c

Neka je G = (V , E) teinski graf i neka su svi cvorovi grafa G proizvoljno


numerisani tako da je V = {v1 , v2 , . . ., vn }. Flojdov algoritam se zasniva na

ideji da se nalaenje najkra eg puta izmedu bilo koja dva cvora v i i v j podeli
c

na nalaenje dva najkra a puta: jednog puta od v i do nekog posrednog


c

c
c
cvora i drugog puta od tog posrednog cvora do v j . Ta nije, najkra i put od

c
v i do v j odreduje se koriste i na tom putu samo posredne cvorove iz skupa

prvih k cvorova Vk = {v1 , v2 , . . ., vk }. Ali taj postupak se ponavlja redom za


svako k = 1, 2, . . ., n, odnosno za niz skupova V1 , V2 , . . ., Vn , tako da se na
c
kraju za Vn = V dobija globalno najkra i put izmedu v i i v j .

Da bismo pojednostavili opis Flojdovog algoritma, pretpostavimo opet


da se trae samo duine najkra ih puteva, a ne i sami putevi. Dodatno,
c

c
radi pogodnosti ozna imo V0 = . Duina najkra eg puta D(i, j, k) od cvora
c

c
v i do cvora v j , uzimaju i u obzir posredne cvorove na putevima od v i do
c
c
c
v j samo one iz skupa Vk , izra unava se za k = 0, 1, 2, . . ., n na slede i na in.
Po etno, za k = 0,
c

D(i, j, 0) =

0,

(v i , v j ),
,

ako i = j
ako (v i , v j ) E
ina e
c

a za k = 1, 2, . . ., n,
D(i, j, k) = min D(i, j, k 1), D(i, k, k 1) + D(k, j, k 1) .

Re ima, najkra i put koji ide od v i do v j i prolazi samo kroz cvorove iz


c
c
c
c
c
c
skupa Vk je jednak kra em od dva mogu a najkra a puta. Prva mogu
nost je da najkra i put uopte ne prolazi kroz cvor vk to je onda duina
c

najkra eg puta od v i do v j koji prolazi samo kroz cvorove iz skupa Vk1 .


c

Druga mogu nost je da najkra i put (jedanput) prolazi kroz cvor vk to je


c
c

onda zbir duina najkra eg puta od v i do vk koji prolazi samo kroz cvorove
c

iz skupa Vk1 i najkra eg puta od vk do v j koji prolazi samo kroz cvorove


c
iz skupa Vk1 .
Pored toga, ne postoji drugi kra i put izmedu v i i v j od ova dva koji
c

vorove iz Vk . Ako bi postojao takav kra i put koji ne sadri


c
prolazi kroz c

c
cvor vk , tada bi to protivre ilo deniciji D(i, j, k 1), a ako bi postojao takav

kra i put koji sadri cvor vk , tada bi to protivre ilo deniciji D(i, k, k 1) ili
c
c

8.4. Najkraci putevi izmedu svih cvorova

245

D(k, j, k 1). U stvari, lako se proverava da ovo vai i ukoliko postoje grane
grafa G negativne duine, ali ne i ciklusi negativne duine.
Na slici 8.14 je ilustrovano izra unavanje duine D(i, j, k) prema pretc

hodnim formulama. Na toj slici, krajnji cvorovi v i i v j mogu pripadati ili


ne pripadati skupu Vk koji je predstavljen sivim delom grafa G.
G

vi

V Vk
Vk
vj

S LIKA 8.14: Izra unavanje D(i, j, k) u Flojdovom algoritmu.


c
Flojdov algoritam na psudo jeziku je jednostavna iterativna implementacija prethodne rekurzivne formule za izra unavanje duine najkra eg
c
c

puta izmedu svaka dva cvora. Ulazni graf G sa n cvorova je predstavljen

nn matricom susedstva M kod koje je element M(i, j) jednak duini grane

izmedu cvorova v i i v j ili je jednak ukoliko izmedu tih cvorova ne postoji


grana. Pored toga, M(i, i) = 0.
// Ulaz: teinski graf G predstavljen matricom susedstva M
// Izlaz: matrica D takva da D(i, j, n) = d(v i , v j )
algorithm floyd(G)
for i = 1 to n do
for j = 1 to n do
D[i,j,0] = M[i,j];
for k = 1 to n do
for i = 1 to n do
for j = 1 to n do
D[i,j,k] = min {D[i,j,k-1], D[i,k,k-1] + D[k,j,k-1]};
return D;

246

Teinski grafovi

Obratite panju na to da se u Flojdovom algoritmu izra unava trodic


menzionalna matrica D(i, j, k), ali to se moe zamisliti kao izra unavanje
c
niza dvodimenzionalnih matrica D k (i, j) za k = 1, 2, . . ., n. Matrica D k se
izra unava u k-toj iteraciji prve od tri ugnjedene for petlje. U nastavku
c

je prikazan ovaj niz dvodimenzionalnih matrica koje se dobijaju za dati


graf G u svakoj iteraciji te petlje.
G
a

20
f

D0

10

20

10

3
d

10

20

D1

D2

10

20

10

11

12

20

28

28

10

10

11

31

12

32

20

28

20

28

31

32

D3

D4

10

11

11

12

10

11

11

12

10

10

11

10

11

10

11

11

12

10

12

10

D5

D6

10

11

11

12

10

11

11

12

10

10

11

11

11

11

12

12

8.4. Najkraci putevi izmedu svih cvorova

247

Ispravnost Flojdovog algoritma moe se lako pokazati indukcijom po


broju iteracija prve od tri ugnjedene for petlje: nakon k iteracija te petlje,

D(i, j, k) sadri duinu najkra eg puta od cvora v i do cvora v j koji prolazi


c

samo kroz cvorove iz skupa Vk . Pored toga, ako je graf G predstavljen


matricom susedstva, vreme izvravanja Flojdovog algoritma je o igledno
c
O n3 . To sledi na osnovu toga to je u algoritmu vremenski dominantno
izvravanje trostruko ugnjedenih for petlji.

U slu aju kada svaka grana grafa ima nenegativnu duinu, Flojdov
c
algoritam se moe poboljati tako da se umesto trodimenzionalne matrice
koristi dvodimenzionalna matrica. Naime, onda su elementi u k-toj vrsti i
k-toj koloni matrice D k isti kao oni u matrici D k1 , poto je D k1(k, k) uvek
nula.
Preciznije re eno, za svako k = 1, 2, . . ., n vai D k (i, k) = D k1(i, k) za
c
svako i = 1, 2, . . ., n i vai D k (k, j) = D k1 (k, j) za svako j = 1, 2, . . ., n. Kako

se nijedan element ciji je jedan ili drugi indeks jednak k ne menja u ktoj iteraciji prve od tri ugnjedene for petlje, nova vrednost za D k (i, j)

moe se izra unati kao minimum stare vrednosti D k1 (i, j) i zbira novih
c
vrednosti D k (i, k) i D k (k, j), a ne kao minimum stare vrednosti D k1 (i, j)
c
i zbira starih vrednosti D k1(i, k) i D k1 (k, j). To zna i da se u Flojdovom
algoritmu umesto trodimenzionalne matrice D reda n n n moe koristiti
dvodimenzionalna matrica D reda n n.
Ova verzija Flojdovog algoritma je jednostavna modikacija originalne

verzije i ostavlja se citaocima za vebu. Obratite panju na to da treba


zapravo samo zanemariti tre i indeks matrice D.
c

Zadaci
1. Odredite sva povezuju a stabla grafa G na slici 8.15.
c
G

S LIKA 8.15.

248

Teinski grafovi

2. Dokaite da je graf povezan ako i samo ako ima povezuju e stablo.


c
3. Inverzni Kruskalov algoritam. Pokaite ispravnost slede eg algoritma
c
za konstruisanje minimalnog povezuju eg stabla teinskog grafa G =
c
(V , E). U algoritmu se polazi od celog grafa (V , E) i zatim se uklanjaju
grane u opadaju em redosledu njihove teine. Speci no, kako se dolazi
c
c
do neke grane e u ovom redosledu (po inju i od grane najve e teine),
c
c
c
grana e se uklanja ukoliko bi bez nje dotadanji graf i dalje bio povezan, a u suprotnom slu aju se grana e zadrava. (Savet: Dokaite
c
slede e svojstvo ciklusa grafa: Ako je e jedinstvena grana najve e teine
c
c
u nekom ciklusu grafa G, onda e ne pripada nijednom minimalnom
povezuju em stablu grafa G.)
c
4. Napiite i analizirajte algoritam za nalaenje povezanih komponenti
grafa G koji ne koristi pretragu u dubinu ili irinu. (Savet: Ideja algoritma je sli na Kruskalovom algoritmu.)
c
5. Napitite drugu verziju Primovog algoritma pod pretpostavkom da je

ulazni graf G sa n cvorova predstavljen teinskom matricom susedstva.


Ta verzija Primovog algoritma treba da se izvrava za vreme O(n2 )
nezavisno od broja grana.

6. Pokaite kako se najkra i putevi od datog cvora s do svakog drugog


c

cvora u grafu mogu rekonstruisati u Dijkstrinom algoritmu usput kako


se odreduju duine tih puteva.

7. Navedite kontraprimer grafa sa negativnim granama za koji Dijkstrin


algoritam ne radi ispravno.
8. Ukoliko je teinski graf G na slici 8.16 ulazni graf za algoritme iz ovog
poglavlja, slikovito ilustrujte izvravanje:
a) Kruskalovog algoritma;

b) Primovog algoritma od po etnog cvora b;


c

c) Dijkstrinog algoritma za dati cvor a;


d) Flojdovog algoritma.

8.4. Najkraci putevi izmedu svih cvorova

249

G
25

a
10

10

30

40
15

23

20

e
17

S LIKA 8.16.

9. Odredite vreme izvravanja algoritma dijkstra ukoliko se koristi matrica susedstva za ulazni graf G, povezane liste za skupove S i V S,

kao i niz d za duine najkra ih puteva od datog cvora s.


c
10. Napiite i analizirajte algoritam za problem najkra ih puteva od jednog
c

cvora u teinskom usmerenom acikli kom grafu.


c
11. Napiite Flojdov algoritam u kome se koristi samo jedna dvodimenzio
nalna matrica za duine najkra ih puteva izmedu svaka dva cvora grafa
c

sa nenegativnim granama.
12. Voralov algoritam. Problem povezanosti obi nog (neteinskog) usmec
renog grafa G sastoji se od utvrdivanja da li postoji put izmedu svaka

dva cvora. Ako je graf G predstavljen matricom susedstva M, problem


povezanosti grafa G svodi se na izra unavanje druge matrice P takve da
c

je P(i, j) = 1 ukoliko postoji put od cvora v i do cvora v j i P(i, j) = 0 u suprotnom slu aju. Napiite i analizirajte algoritam kojim se izra unava
c
c
matrica P. (Savet: Modikujte Flojdov algoritam.)

Literatura

[1]

Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman. Data Structures and Algorithms. Addison-Wesley, 1987.

[2]

Kenneth P. Bogart, Clifford Stein, and Robert Drysdale. Discrete


Mathematics for Computer Science. Key College, 2005.

[3]

Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and


Clifford Stein. Introduction to Algorithms. The MIT Press, second
edition, 2001.

[4]

Ronald L. Graham, Donald E. Knuth, and Oren Patashnik. Concrete


Mathematics: A Foundation for Computer Science. Addison-Wesley,
second edition, 1994.

[5]

Dejan ivkovi . Osnove dizajna i analize algoritama. Ra unarski


c
c
fakultet i CET, Beograd, 2007.

[6]

Dejan ivkovi . Foundations of Algorithm Design and Analysis. VDM


c
Verlag, 2009.

[7]

Miodrag ivkovi . Algoritmi. Matemati ki fakultet, Beograd, 2000.


c
c

[8]

Jon Kleinberg and va Tardos. Algorithm Design. Addison-Wesley,


2005.

[9]

Anany Levitin. Introduction to the Design and Analysis of Algorithms.


Addison-Wesley, second edition, 2006.

[10] James A. Storer. An Introduction to Data Structures and Algorithms.


Birkhauser Boston, 2002.
[11] Milo Tomaevi . Algoritmi i strukture podataka. Akademska misao,
c
Beograd, 2008.
[12] Mark Allen Weiss. Data Structures and Algorithm Analysis in Java.
Addison-Wesley, second edition, 2007.

Indeks

A
acikli ki graf, 188
c
algoritam, 4
analiza, 8, 2128
denicija, 6
dizajn, 8, 18
funkcija vremena izvravanja, 24
ispravnost i ekasnost, 17
iterativni, 108
izlaz, 6
jedini na instrukcija, 24
c
jednostavnost i jasno a, 17
c
osnovne konstrukcije, 25
pojednostavljena analiza, 46
primeri, 2840
pseudo jezik, 1113
rekurzivni, 108
ulaz, 6
veli ina, 23
c
vreme izvravanja, 24, 43
najgori slu aj, 24
c
vremenska sloenost, 24
asimptotska notacija, 5458, 66
O-zapis, 54
-zapis, -zapis, o-zapis, 58
asimptotsko vreme izvravanja, 43

B
ben mark podaci, 27
c
binarna pretraga, 48
binarni hip, 165
hip svojstvo, 166
operacije, 166

dodavanje cvora, 167


konstruisanje hipa, 168

uklanjanje najmanjeg cvora, 166


predstavljanje pomo u niza, 168
c
binarno stablo, 151

desno dete, 151


kompletno, 165
levo dete, 151
pravilno, 182
puno, 164
binarno stablo pretrage, 155
BSP svojstvo, 155
operacije, 156

dodavanje cvora, 158


ekasnost, 164

traenje cvora, 156

uklanjanje cvora, 160


bipartitan graf, 219
BSP operacije, 156
BSP svojstvo, 155

D
Dijkstrin algoritam, 237
implementacija, 240
poputanje, 241

reeni cvorovi, 237


specijalni put, 237
disjunktni skupovi, 177
operacije
konstruisanje skupa od jednog elementa, 177
objedinjavanje dva skupa, 177
odredivanje mati nog skupa, 177
c

predstavljanje pomo u stabala, 177


c
objedinjavanje po visini, 178
duina puta, 188
dvostruko povezana lista, 93

E
ekasnost BSP operacija, 164

ekscentri nost cvora, 221


c
Euklidov algoritam, 60

254

Indeks

rekurzivni, 110

F
Fibona ijev niz brojeva, 111
c
Flojdov algoritam, 243
funkcija vremena izvravanja algoritma,
24

G
graf, 186
acikli ki, 188
c
ciklus, 188
incidentna grana, 186
minimalno povezuju e stablo, 225
c
neusmeren, 187
bipartitan, 219
obilazak, 194
podgraf, 189
povezan, 189
povezana komponenta, 189
povezane komponente
nalaenje, 205
povezuju e stablo, 227
c
minimalno, 227
predstavljanje, 191
liste susedstva, 192
matrica susedstva, 191
pretraga u irinu, 195
analiza, 197
implementacija, 196
stablo, 198
pretraga u dubinu, 200
analiza, 202
stablo, 203
prost put, 188
Hamiltonov, 222
put, 188
duina, 188

rastojanje cvorova, 194


redak, 192
s-t povezanost, 194

stepen cvora, 187, 188


izlazni, 188
ulazni, 188

susedi cvora, 187

susedni cvorovi, 186


uma, 191

teinski, 223
usmeren, 187

H
Hanojske kule, 113
hip, Vidi binarni hip
hip operacije, 166
hip svojstvo, 166

I
implementacija pretrage u irinu, 196
incidentna grana, 186
invarijanta petlje, 20
inverzija niza, 142
iterativni algoritam, 108

izlazni stepen cvora, 188

J
jaka povezanost, 209
jako povezan graf, 190
jedini na instrukcija, 24
c
jedini ni model sloenosti, 9
c

K
kompletno binarno stablo, 165
korensko stablo, 145
kruni turnir, 142
Kruskalov algoritam, 229
implementacija, 231
kursor, 95

L
lista, 88
dvostruko povezana, 93
implementacija
pomo u nizova, 94
c
c
c
pomo u pokaziva a, 89
liste susedstva, 192

M
maksimalna suma podniza, 2934
kvadratni algoritam, 29
linearni algoritam, 75
rekurzivni algoritam, 142

Indeks

matrica, 79
matrica susedstva, 191
metod nagadanja, 132

minimalno povezuju e stablo, 225


c
Kruskalov algoritam, 229
implementacija, 231
Primov algoritam, 233
implementacija, 234
svojstvo ciklusa grafa, 248
svojstvo podele grafa, 227
mnoenje velikih celih brojeva, 137

N
najgori slu aj izvravanja algoritma, 24
c

najkra i putevi izmedu svih cvorova, 243


c

Flojdov algoritam, 243

najkra i putevi od jednog cvora, 236


c
Dijkstrin algoritam, 237
najmanji element niza, 2829
najve i element niza, 1415
c
najve i zajedni ki delilac, 19
c
c
neprekidni podniz, 30
neuporedive funkcije, 60
neusmeren graf, 187
bipartitan, 219
matrica susedstva, 191
niz listi susedstva, 193
niz, 73

O
obilazak binarnog stabla, 153
inorder, 153
postorder, 154
preorder, 153
obilazak grafa, 194
obilazak usmerenog grafa, 209
opti metod, 134
osnovne algoritamske konstrukcije, 25
osnovne strukture podataka, 71101

P
podaci, 2
podgraf, 189
pojednostavljena analiza algoritama, 46
ponor, 219
poputanje, 241
povezan graf, 189

255

povezana komponenta, 189


povezuju e stablo, 227
c
minimalno, 227
pravilno binarno stablo, 182
pravilo limesa, 59
predstavljanje grafova, 191
liste susedstva, 192
matrica susedstva, 191
pretraga u irinu, 195
analiza, 197
implementacija, 196
stablo, 198
pretraga u dubinu, 200
analiza, 202
stablo, 203, 210
primeri algoritama, 28
Primov algoritam, 233
implementacija, 234
proireni Euklidov algoritam, 70
problem
instanca, 6
reenje, 6
izlazni parametri, 5
ulazni parametri, 5
problem poznate li nosti, 141
c
problem sortiranja, 5
problem stabilnih brakova, 8087
problem vra anja kusura, 5
c
prost put, 188
Hamiltonov, 222
puno binarno stablo, 164
put u grafu, 188

R
ra unar sa proizvoljnim pristupom mec
moriji (RAM), 9
ra unarski model, 810
c
ra unarski problem, Vidi problem
c
randomizirani algoritam, 27

rastojanje cvorova, 194


red sa prioritetima, 175
implementacija
binarni hip, 176

red za cekanje, 98
redak graf, 192
rekurentne jedna ine, 116, 128
c
metod nagadanja, 132

metod stabla rekurzije, 129

256

opti metod, 134


rekurzivni algoritmi, 107140
bazni slu aj, 110
c
rekurentne jedna ine, 128
c

S
s-t povezanost, 194
skup, 104
skup povezanih komponenti, 205
nalaenje, 205
slobodno stablo, 190
sortiranje niza, 34
sortiranje izborom (select-sort), 39
sortiranje objedinjavanjem (mergesort), 117
analiza algoritma, 120
sortiranje razdvajanjem (quick-sort),
122
analiza algoritma, 126
medijana, 124
pivot, 123
sortiranje umetanjem (insert-sort),
37
sortiranje upotrebom hipa (heap-sort),
184
sortiranje zamenjivanjem (bubble-sort),
34
sportski navija , 67
c
srpska zastava, 67
stabilno vezivanje, 82
stablo, 145

cvorovi, 145
bra a (sestre), 147
c
dete, 146
dubina, 148
listovi, 147
potomak, 148
predak, 148
roditelj, 146
spoljanji, 147
unutranji, 147
visina, 148
binarno, 151
obilazak, 153
binarno stablo pretrage, 155
denicija
formalna, 146
rekurzivna, 147

Indeks

grane, 145
koren, 146
korensko, 145
podstablo, 148
reprezentacija

pomo u listi dece cvorova, 149


c
pomo u sasvim levog deteta i dec

snog brata cvorova, 150


slobodno, 190

stepen cvora, 182


struktura podataka, 148
visina, 148
stablo pretrage u irinu, 198
stablo pretrage u dubinu, 203, 210
direktna grana, 211
grana stabla, 204, 210
popre na grana, 211
c
povratna grana, 204, 211
stablo rekurzije, 129
stek, 96
operacija pop, 96
operacija push, 96
c
potkora enje, 97
prazan, 97
prekora enje, 97
c
pun, 97
vrh, 96

stepen cvora, 182, 187, 188


strukture podataka
disjunktni skupovi, 177
lista, 88
matrica, 79
niz, 73
osnovne, 71
red sa prioritetima, 175

red za cekanje, 98
skup, 104
stablo, 148
stek, 96

susedi cvora, 187

susedni cvorovi, 186


svojstvo ciklusa grafa, 248
svojstvo podele grafa, 227

uma, 191

Indeks

T
teinski grafovi, 223247
ternarna pretraga, 66
tipi ne funkcije vremena izvravanja, 52
c
topoloki redosled, 213
nalaenje, 214

ulazni stepen cvora, 188


usmeren acikli ki graf, 212
c
topoloki redosled, 213
nalaenje, 214
usmeren graf, 187
acikli ki, 212
c
jaka povezanost, 209
jako povezan, 190
matrica susedstva, 191
niz listi susedstva, 193
obilazak, 209
ponor, 219
pretraga u dubinu
stablo, 210

V
veli ina ulaza, 23
c
vezivanje
savreno, 80
stabilno, 82
virtuelna inicijalizacija niza, 101
Voralov algoritam, 249
vreme izvravanja algoritma, 24
asimptotsko, 43
najgori slu aj, 24
c
o ekivano, 27
c
prose no, 27
c
vremenska sloenost algoritma, 24

Z
zamena vrednosti dve promenljive, 13
zapis algoritama, 1013

257

Odlukom Senata Univerziteta Singidunum, Beogrd, broj 636/08 od 12.06.2008,


ovaj udbenik je odobren kao osnovno nastavno sredstvo na studijskim programima koji
se realizuju na integrisanim studijama Univerziteta Singidunum.

CIP -
,
004.421(075.8)
510.5(075.8)
004.6(075.8)
, , 1956Uvod u algoritme i strukture podataka /
Dejan ivkovi. - 1. izd. - Beograd :
Univerzitet Singidunum, 2010 (Loznica :
Mladost Grup). - IV, 257 str. : ilustr. ; 24
cm
Tira 240. - Bibliograja: str. 251. Registar.
ISBN 978-86-7912-239-1
a) b) ()
COBISS.SR-ID 172433420
2010.
Sva prava zadrana. Ni jedan deo ove publikacije ne moe biti reprodukovan u bilo kom
vidu i putem bilo kog medija, u delovima ili celini bez prethodne pismene saglasnosti
izdavaa.

You might also like