Sveuˇciliˇste u Zagrebu

Prirodoslovno Matematiˇcki Fakultet
- Matematiˇcki odjel

Robert Manger, Miljenko Maruˇ
si´
c

STRUKTURE PODATAKA
I ALGORITMI
skripta

Tre´ce izdanje
(novo poglavlje o algoritmima za sortiranje)
Zagreb, oˇzujak 2007.

Sadrˇ
zaj
1 UVOD
1.1 Osnovni pojmovi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Elementi od kojih se grade strukture podataka . . . . . . . . . . . . . . . . . . . . . . .
1.3 Zapisivanje i analiziranje algoritma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 LISTE
2.1 (Op´cenita) lista . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Implementacija liste pomo´cu polja . . . . . . .
2.1.2 Implementacija liste pomo´cu pointera . . . . .
2.2 Stog (stack) . . . . . . . . . . . . . . . . . . . . . . . .
2.2.1 Implementacija stoga pomo´cu polja . . . . . .
2.2.2 Implementacija stoga pomo´cu pointera . . . . .
2.3 Red (queue) . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1 Implementacija reda pomo´cu cirkularnog polja
2.3.2 Implementacija reda pomo´cu pointera . . . . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

3 STABLA
3.1 (Uredeno) stablo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Obilazak stabla . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Implementacija stabla na osnovu veze “ˇcvor → roditelj” . .
3.1.3 Implementacija stabla na osnovu veze “ˇcvor → (prvo dijete,
3.2 Binarno stablo . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Implementacija binarnog stabla pomo´cu pointera . . . . . .
3.2.2 Implementacija potpunog binarnog stabla pomo´cu polja . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

. . .
. . .
. . .
idu´ci
. . .
. . .
. . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

. . . .
. . . .
. . . .
brat)”
. . . .
. . . .
. . . .

4 SKUPOVI
4.1 (Op´ceniti) skup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Implementacija skupa pomo´cu bit-vektora . . . . . . . . . . . . . . .
4.1.2 Implementacija skupa pomo´cu sortirane vezane liste . . . . . . . . .
4.2 Rjeˇcnik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 Implementacija rjeˇcnika pomo´cu bit-vektora . . . . . . . . . . . . . .
4.2.2 Implementacija rjeˇcnika pomo´cu liste . . . . . . . . . . . . . . . . .
4.2.3 Implementacija rjeˇcnika pomo´cu rasute (hash) tablice . . . . . . . .
4.2.4 Implementacija rjeˇcnika pomo´cu binarnog stabla traˇzenja . . . . . .
4.3 Prioritetni red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Implementacija prioritetnog reda pomo´cu sortirane vezane liste . . .
4.3.2 Implementacija prioritetnog reda pomo´cu binarnog stabla traˇzenja .
4.3.3 Implementacija prioritetnog reda pomo´cu hrpe . . . . . . . . . . . .
4.4 Preslikavanje i relacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1 Implementacija preslikavanja pomo´cu hash tablice ili binarnog stabla
4.4.2 Implementacija relacije pomo´cu bit-matrice . . . . . . . . . . . . . .
4.4.3 Implementacija relacije pomo´cu multi-liste . . . . . . . . . . . . . . .
1

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

3
3
5
6

.
.
.
.
.
.
.
.
.

7
7
8
10
11
13
14
15
16
17

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

19
19
22
23
24
26
28
29

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

31
31
32
32
33
33
33
35
38
42
43
43
43
47
48
50
50

ˇ
SADRZAJ

2
5 ALGORITMI ZA SORTIRANJE
5.1 Sortiranje zamjenom elemenata . . . . . . . . . . . . . . . . . .
5.1.1 Sortiranje izborom najmanjeg elementa (selection sort) .
5.1.2 Sortiranje zamjenom susjednih elemenata (bubble sort)
5.2 Sortiranje umetanjem . . . . . . . . . . . . . . . . . . . . . . .
5.2.1 Jednostavno sortiranje umetanjem (insertion sort) . . .
5.2.2 Viˇsestruko sortiranje umetanjem (Shell sort) . . . . . .
5.3 Rekurzivni algoritmi za sortiranje . . . . . . . . . . . . . . . . .
5.3.1 Saˇzimanje sortiranih polja (merge) . . . . . . . . . . . .
5.3.2 Sortiranje saˇzimanjem (merge sort) . . . . . . . . . . . .
5.3.3 Brzo sortiranje (quick sort) . . . . . . . . . . . . . . . .
5.4 Sortiranje pomo´cu binarnih stabala . . . . . . . . . . . . . . . .
5.4.1 Sortiranje obilaskom binarnog stabla traˇzenja (tree sort)
5.4.2 Sortiranje pomo´cu hrpe (heap sort) . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

53
53
53
54
56
56
57
58
58
60
61
63
63
65

6 OBLIKOVANJE ALGORITAMA
6.1 Metoda “podijeli pa vladaj” . . . . . . . . . . . . . . . . . . . .
6.1.1 Opet sortiranje saˇzimanjem (merge sort) . . . . . . . . .
6.1.2 Traˇzenje elementa u listi . . . . . . . . . . . . . . . . .
6.1.3 Mnoˇzenje dugaˇckih cijelih brojeva . . . . . . . . . . . .
6.2 Dinamiˇcko programiranje . . . . . . . . . . . . . . . . . . . . .
6.2.1 Odredivanje ˇsanse za pobjedu u sportskom nadmetanju
6.2.2 Rjeˇsavanje 0/1 problema ranca . . . . . . . . . . . . . .
6.3 “Pohlepni” pristup . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.1 Optimalni plan saˇzimanja sortiranih listi . . . . . . . . .
6.3.2 Rjeˇsavanje kontinuiranog problema ranca . . . . . . . .
6.4 Backtracking . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.1 Rjeˇsavanje problema n kraljica . . . . . . . . . . . . . .
6.4.2 Rjeˇsavanje problema trgovaˇckog putnika . . . . . . . . .
6.5 Lokalno traˇzenje . . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.1 2-opt algoritam za problem trgovaˇckog putnika . . . . .
6.5.2 Traˇzenje optimalnog linearnog rasporeda . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

69
69
69
70
70
72
72
73
74
75
75
77
78
80
82
83
85

Literatura

87

1

UVOD
1.1

Osnovni pojmovi

U raˇcunarstvu se susre´cemo s dva osnovna pojma:
strukture podataka . . . “statiˇcki” aspekt nekog programa. Ono sa ˇcime se radi.
algoritmi . . . “dinamiˇcki” aspekt programa. Ono ˇsto se radi.
Strukture podataka i algoritmi su u nerazluˇcivoj vezi: nemogu´ce je govoriti o jednom a da se ne
spomene drugo. U ovom kolegiju prouˇcavat ´cemo baˇs tu vezu: promatrat ´cemo kako odabrana struktura
podataka utjeˇce na algoritme za rad s njom, te kako odabrani algoritam sugerira pogodnu strukturu
za prikaz svojih podataka. Na taj naˇcin upoznat ´cemo se s nizom vaˇznih ideja i pojmova, koji ˇcine
osnove raˇcunarstva.
Uz “strukture podataka” i “algoritme”, ovaj kolegij koristi joˇs nekoliko naizgled sliˇcnih pojmova.
Objasnit ´cemo njihovo znaˇcenje i medusobni odnos.
tip podataka . . . skup vrijednosti koje neki podatak moˇze poprimiti (npr. podatak tipa int moˇze
imati samo vrijednosti iz skupa cijelih brojeva prikazivih u stroju).
apstraktni tip podataka (a.t.p.) . . . zadaje se navodenjem jednog ili viˇse tipova podataka, te jedne
ili viˇse operacija (funkcija). Operandi i rezultati navedenih operacija su podaci navedenih tipova.
Medu tipovima postoji jedan istaknuti po kojem cijeli apstraktni tip podataka dobiva ime.
struktura podataka . . . skupina varijabli u nekom programu i veza medu tim varijablama.
algoritam . . . konaˇcni niz instrukcija, od kojih svaka ima jasno znaˇcenje i moˇze biti izvrˇsena u
konaˇcnom vremenu. Iste instrukcije mogu se izvrˇsiti viˇse puta, pod pretpostavkom da same
instrukcije ukazuju na ponavljanje. Ipak, zahtijevamo da, za bilo koje vrijednosti ulaznih podataka, algoritam zavrˇsava nakon konaˇcnog broja ponavljanja.
implementacija apstraktnog tipa podataka . . . konkretna realizacija dotiˇcnog apstraktnog tipa
podataka u nekom programu. Sastoji se od definicije za strukturu podataka (kojom se prikazuju
podaci iz apstraktnog tipa podataka) te od potprograma (kojima se operacije iz apstraktnog
tipa podataka ostvaruju pomo´cu odabranih algoritama). Za isti apstraktni tip podataka obiˇcno
se moˇze smisliti viˇse razliˇcitih implementacija - one se razlikuju po tome ˇsto koriste razliˇcite
strukture za prikaz podataka te razliˇcite algoritme za izvrˇsavanje operacija.
Svako od potpoglavlja 2.1–4.4 obraduje jedan apstraktni tip podataka. Promatraju se razne implementacije za taj apstraktni tip podataka te njihove prednosti i mane. Na taj naˇcin upoznat ´cemo
mnogo apstraktnih tipova podataka, te joˇs viˇse struktura podataka i algoritama. Daljnja potpoglavlja
5.1–5.4 obraduju algoritme za sortiranje. U oblikovanju algoritama za sortiranje primjenjuju se pojedini apstraktni tipovi odnosno strukture podataka iz prethodnih poglavlja. Preostala potpoglavlja
6.1–6.5 posve´cena su op´cenitim metodama (strategijama) koje mogu sluˇziti za oblikovanje sloˇzenijih
algoritama. Znanje iz ovog kolegija trebalo bi nam omogu´citi da bolje programiramo. Naime, razvoj
programa (metodom postepenog profinjavanja) moˇze se promatrati u skladu sa sljede´cim dijagramom.

3

Bez tih operacija radilo bi se o tipu.y3). Dakle za z1 oblika (x1... .y2). dobiva se z3 oblika (x3.. y3=y1+y2. globalni algoritam zapisan u pseudo jeziku (poziva operacije iz a..z2. Za apstraktni tip podataka COMPLEX je vaˇzno da su prisutne operacije ADD( ) i MULT( ).... pretvorene u potprograme) . COMPLEX z2. tako da bude x3=x1+x2. rjeˇsenje problema Slika 1.p. ..y1).) globalni algoritam zapisan u progr. y3=x1*y2+y1*x2..z2. ... Dakle za z1 oblika (x1...... struktura podataka i algoritama u postupku rjeˇsavanja problema. COMPLEX *z3) {... . podaci ovog tipa su uredeni parovi podataka tipa scalar... . Na vjeˇzbama ´ce biti izloˇzen cjelovit primjer za rjeˇsavanje problema metodom postepenog profinjavanja.} (algoritmi upotrijebljeni u potprogramima su trivijalni). . . takoder tipa COMPLEX.. Iz ovog dijagrama vidi se uloga apstraktnih tipova podataka. neformalno opisani globalni algoritam rjeˇsavanja problema strukture podataka .y3). Slijedi primjer za apstraktni tip podataka.p. . .... } COMPLEX. Dodatna dimenzija “apstraktnosti” sastoji se u tome ˇsto nismo do kraja odredili ˇsto je tip scalar.t. z2 oblika (x2. .z2 tipa COMPLEX raˇcuna se njihov zbroj z3.. Takoder se vidi da se programiranje u podjednakoj mjeri sastoji od razvijanja struktura podataka kao i od razvijanja algoritama. . re im Implementacija apstraktnog tipa podataka COMPLEX se sastoji od prethodne definicije tipa. scalar im. ADD(z1..... . Struktura podataka pogodna za prikaz kompleksnog broja bila bi tipa: typedef struct { scalar re.1 Postupak rjeˇsavanja problema.t. i tada kompleksne brojeve ne bismo mogli razlikovati od uredenih parova skalara...&z3) . COMPLEX z2.. To je naime nebitno za prouˇcavanje struktura podataka i algoritama (vaˇzan je odnos medu varijablama a ne njihov sadrˇzaj). COMPLEX .} void MULT (COMPLEX z1.. .. COMPLEX *z3) {. Definiramo apstraktni tip podataka koji odgovara matematiˇckom pojmu kompleksnih brojeva: Apstraktni tip podataka COMPLEX scalar . .. za zadane z1.4 1... dobiva se z3 oblika (x3. .z2 tipa COMPLEX raˇcuna se njihov umnoˇzak z3... takav da je x3=x1*x2-y1*y2.. takoder tipa COMPLEX.y2). jeziku (operacije iz a.&z3) .. MULT(z1.. z2 oblika (x2.te od funkcija oblika: void ADD (COMPLEX z1. . .. za zadane z1. bilo koji tip za koji su definirane operacije zbrajanja i mnoˇzenja.y1). UVOD apstraktni tipovi podataka matematiˇcki model problem . ..

. Uvodimo posebne nazive za cjeline....... (slog. ... Dijagram pokazuje primjer strukture podataka koja se sastoji od niza zapisa povezanih pomo´cu pointera. redosljed i tip ´celija je unaprijed zadan i nepromjenljiv. i . i sliˇcno.. zapis ˇcije pojedine komponente su polja.. Sadrˇzaj kursora je indeks elementa kojeg treba pokazati.... . Polja i zapisi se mogu kombinirati.. .. 1.. . Pojedina ´celija se zove komponenta zapisa. koje ne moraju biti istog tipa.To je relativan pojam (neˇsto se u jednom trenutku moˇze smatrati ´celijom. uvodimo pravila kako se strukture prikazuju dijagramima.....2. Broj ´celija je unaprijed zadan i nepromjenljiv... naˇcine udruˇzivanja i naˇcine povezivanja. Mehanizam udruˇzivanja manjih dijelova strukture u ve´ce. varijabla koju promatramo kao zasebnu cjelinu. Polje . . a kasnije se moˇze gledati unutraˇsnja grada iste cjeline). zapis ˇcija komponenta je zapis.. .2 5 Elementi od kojih se grade strukture podataka Struktura podataka se sastoji od manjih cjelina koje se udruˇzuju u ve´ce i medusobno povezuju vezama..... uzimamo da su indeksi 0...... . . ... Sadrˇzaj pointera je adresa ´celije koju treba pokazati.............. Jedna ´celija se zove element polja i jednoznaˇcno je odredena pripadnom vrijednoˇs´cu indeksa.. structure u C-u)... (array u C-u)... . Pointer je ´celija koja pokazuje neku drugu ´celiju.. Broj.. Kursor ..... N-1. .... takoder sluˇzi za uspostavljanje veze izmedu dijelova strukture... .. . Pointer .. 2. . ... Takoder mehanizam udruˇzivanja manjih dijelova strukture u ve´ce..c.. no koje su pohranjene na uzastopnim adresama. Kursor je ´celija tipa int koja pokazuje na element nekog polja. Takoder.. Zapis ˇcini viˇse ´celija. Na primjer. ´ Celija . . 0 1 2 3 4 5 6 Zapis ... Polje ˇcini viˇse ´celija istog tipa pohranjenih na uzastopnim adresama.... ELEMENTI OD KOJIH SE GRADE STRUKTURE PODATAKA 1. te od jednog polja zapisa.. .. Svaka ´celija ima svoj tip i adresu.. ...1.. . gdje je N cjelobrojna konstanta. sluˇzi za uspostavljanje veze izmedu dijelova strukture.. polje od polja. . moˇzemo imati polje zapisa. Po ugledu na C.. Zapisi su joˇs medusobno povezani kursorima.

..... . Pod analizom algoritma podrazumijevamo procjenu vremena izvrˇsavanja tog algoritma... . Tada definiramo T (n) kao vrijeme u najgorem sluˇcaju.... ..... s Slika 1.. ........ .... . .... ........c .. dakle kao maksimum za vrijeme izvrˇsavanja po svim skupovima ulaznih podataka veliˇcine n. Vrijeme poistovje´cujemo s brojem operacija koje odgovaraju´ci program treba obaviti.... .. ....... ... dakle smatra se da su svi skupovi ulaznih podataka jednako vjerojatni..... ......... UVOD ....... ....... . 3 .. invertiranje traje 27 puta dulje.. .... .. .. ... Da bi mogli govoriti o oˇcekivanju.... . ˇ Cesto se deˇsava da T (n) ne ovisi samo o veliˇcini skupa ulaznih podataka n.. ... vrijeme izvrˇsavanja Gaussovog algoritma za invertiranje matrice je O(n3 )... Nismo precizno utvrdili koliko ´ce sekundi trajati naˇs program.. .. .. gdje su neki nizovi naredbi zamijenjeni slobodnim tekstom... .. .......... . .......8 0 .... Jedino ˇsto znamo je sljede´ce: ........ ....... Obiˇcno ´ce biti rijeˇc o “skiciranom” nedovrˇsenom) kodu........ ..6 1 . .. . invertiranje bi moglo trajati i do 8 puta dulje.. ....... tada njegovo vrijeme izvrˇsavanja izraˇzavamo u obliku T (n) gdje je n duljina niza realnih brojeva... ........ .. ......... ........... ... .2 Primjer strukture podataka....2 2 ..... nego takoder i o vrijednostima tih podataka.. . 2 5.. tada njegovo vrijeme izvrˇsavanja izraˇzavamo kao T (n)...... ...... ... ...3 Zapisivanje i analiziranje algoritma Kao jezik za zapisivanje algoritama sluˇzit ´ce nam programski jezik C. . .... i izraˇzavamo kao funkciju oblika T (n).. .. ... . ..... gdje je n red matrice... .4 -1 ........ .... . ..... 3 7... ......... Sliˇcno....... ......... 1..... Npr.... umjesto algoritama pisat ´cemo program (ili funkciju) u C-u koji radi po tom algoritmu. . . .. ako promatramo algoritam za invertiranje matrica. ............. .... .. .. ............ 1. ... . ako promatramo algoritam koji sortira niz realnih brojeva. .. ............. ... .... ... .... ... ... ................ 1 ..c ... .... .. Funkciju T (n) nema smisla precizno odredivati.. ................ .. Npr. algoritam za sortiranje moˇzda brˇze sortira niz brojeva koji je “skoro sortiran”.............. . dovoljno je utvrditi njen red veliˇcine.. .. ... .... gdje je n neka mjera za veliˇcinu skupa ulaznih podataka... Obiˇcno se pretpostavlja uniformna distribucija.. ..... Takoder se tada promatra vrijeme u prosjeˇcnom sluˇcaju Tavg (n).. itd.. . moramo pretpostaviti distribuciju za razne skupove ulaznih podataka veliˇcine n. Naprimjer.......... Dakle... .. .. Time smo zapravo rekli da T (n) ≤ const · n3 .. a sporije niz koji je “jako izmijeˇsan”. ............. . . ....ako se red matrice utrostruˇci....... ....6 1...ako se red matrice udvostruˇci.. 1 3. . ..... . .. . koje se dobiva kao matematiˇcko oˇcekivanje vremena izvrˇsavanja.. ... . . . 0 ..... .

je samo jedna od mogu´cih varijanti. Sliˇcno. Vaˇzno svojstvo liste je da su njeni elementi linearno uredeni s obzirom na svoju poziciju.Kao rezultat pretraˇzivanja baze podataka obiˇcno se dobiva lista zapisa. . Ako je n = 0. kaˇzemo da je lista prazna. Primjer: LISP (List Processing). T). . S. identitet elementa odreden je njegovom pozicijom (rednim brojem) a ne njegovom vrijednoˇs´cu. Petrovi´c Marija. godine a po zanimanju su matematiˇcari.. . To se moˇze uˇciniti na razne naˇcine. N. . trebamo definirati operacije koje se obavljaju na listama. e1). . . . . Zapravo se radi o listi oblika : ((a1 . .p. 7 . gdje je 0 ≤ e1 < e2 < . Za n ≥ 1. Podaci koji ˇcine listu nazivaju se njeni elementi. . . .2 LISTE 2. . . (a2. . rijeˇc ZNANOST se moˇze interpretirati kao (Z. Broj elemenata u listi nije fiksiran: elementi se mogu ubacivati ili izbacivati na bilo kojem mjestu .Polinom u matematici biljeˇzimo na sljede´ci naˇcin: P (x) = a1 xe1 + a2 xe2 + . bilo koji tip.t. N. redak u tekstu je lista znakova (ukljuˇcuju´ci i bjeline). podatak tipa LIST je konaˇcni niz (ne nuˇzno razliˇcitih) podataka tipa elementtype. Da bi matematiˇcki pojam liste pretvorili u apstraktni tip podataka. . . U teoretskim razmatranjima listu obiˇcno biljeˇzimo ovako: (a1 .U nekim programskim jezicima lista je osnovni objekt od kojeg se grade svi ostali. . . . Npr. Kaˇzemo da je ai ispred ai+1 . O. A. Ovdje je n ≥ 0 tzv. .). . Cijeli tekst je lista redaka. . < en . a2. U nastavku navodimo nekoliko primjera za liste. Markovi´c Pero. te da je ai iza ai−1.na taj naˇcin lista moˇze rasti ili se smanjivati. (an. + an xen . Mogu´ce je da su neki od elemenata liste jednaki. duljina liste.1 (Op´ cenita) lista Lista je konaˇcni niz (od nula ili viˇse) podataka istog tipa. postavljamo upit: ispisati prezimena i imena ljudi koji su rodeni 1960. a2 drugi. an). Primijetimo da dva razliˇcita elementa imaju istu vrijednost.Rijeˇc u nekom tekstu je lista znakova. Rezultat je oblika: (Babi´c Mato. a1 je prvi element. en)). an zadnji element. Npr. e2 ). Naˇs a. LIST . Primijetimo da lista nije isto ˇsto i polje. . sortirano po abecedi. Apstraktni tip podataka LIST elementtype . . .

. ap−1 . . Postoje dva osnovna pristupa: . an). puno prazno . .&L) . PREVIOUS(p. . . Mi ´cemo od svakog pristupa opisati samo jednu (najtipiˇcniju) varijantu... PREVIOUS( ) je nedefinirana za p == FIRST(L).. MAKE NULL(&L) funkcija pretvara listu L u praznu listu. x).. vra´ca se END(L). (Sluˇzimo se pointerom ili kursorom. .L) == END(L). Slika 2. n-tom elementu. pa se mora eksplicitno zapisati. podatak ovog tipa sluˇzi za identificiranje elementa u listi. an). . END(L) . funkcija vra´ca element na poziciji p u listi L. . ..n-1 MAXLENGTH-1 an . an. ... NEXT(p. ... . DELETE(p.) . Rezultat nije definiran ako L nema pozicije p ili ako je p == END(L). i vra´ca poziciju END(L)... .. .) Oba pristupa dozvoljavaju razne varijante.. ... .. . Dakle. . Duljina liste je ograniˇcena.p. .. . ...1 Implementacija liste pomo´cu polja. ukoliko je lista L oblika (a1 . . Smatramo da su u listi (a1 . . tada je NEXT(p. . . . . . funkcije koje vra´caju poziciju iza odnosno ispred p u listi L. an) tada L postaje (a1 ..8 2. .. (Koristimo polje.. RETRIEVE(p. . ap. . dakle za zadavanje pozicije u listi... . . ... S druge strane. LISTE position . Lagano je proˇcitati i-ti element. . . . Ako je p == END(L) tada L postaje (a1 .L) . . FIRST(L) . funkcija koja vra´ca poziciju na kraju liste L.L). .L) . Pritom se elementi koji su dotad bili na poziciji p i iza nje pomiˇcu za jednu poziciju dalje. funkcija vra´ca prvu poziciju u listi L. .“logiˇcki” redoslijed elemenata u listi poklapa se s “fiziˇckim” redoslijedom tih elemenata u memoriji. .. . Takoder imamo jedan kursor koji pokazuje gdje se zadnji element liste nalazi u polju. a2.. . Obje funkcije su nedefinirane ako L nema pozicije p. ubacivanje i izbacivanje u sredini liste zahtijeva fiziˇcko pomicanje (prepisivanje) dijela podataka. Takoder je lagano ubacivanje i izbacivanje na kraju liste. ako je L oblika (a1. a2.... . . . . INSERT(x. funkcija izbacuje element na poziciji p iz liste L.1 Implementacija liste pomo´ cu polja Elementi liste su spremljeni u uzastopnim ´celijama jednog polja. ap+1 ... . Ako u L ne postoji pozicija p. an) definirane pozicije koje odgovaraju prvom. NEXT( ) je nedefinirana za p == END(L). . . .. . .“logiˇcki” redoslijed se ne poklapa s “fiziˇckim”. .. funkcija ubacuje podatak x na poziciju p u listu L. a2. . x. U nastavku ´cemo opisati neke strukture podataka koje mogu sluˇziti za prikaz liste.&L) .. ... an).1. . a2. ap−1 . Ako je p zadnja pozicija u L... . drugom. . Ako je L prazna. a2. ..... rezultat je nedefiniran... Dakle.. . 2. a takoder i pozicija na kraju liste (neposredno iza n-tog elementa). a2. . . .. tada L postaje (a1 . Rezultat je nedefiniran ako je p == END(L) ili ako L nema pozicije p. .. .. elements 0 a1 1 a2 2 a3 last n-1 . .

nema mnogo ubacivanja/izbacivanja u sredinu liste. q <= L ptr->last.. LIST *L ptr) { position q.L) odnosno PREVIOUS(p. L ptr->elements[p] = x.. Vrijeme izvrˇsavanja za INSERT( ) i DELETE( ) je O(n). Implementacija liste pomo´cu polja se smatra pogodnom pod sljede´cim uvjetima: . for (q = p.. } position MAKE NULL (LIST *L ptr) { L ptr->last = -1. else { L ptr->last--. a za ostale operacije je O(1).jedno mjesto dalje */ L ptr->elements[q+1] = L ptr->elements[q]. RETRIEVE(p. return 0. typedef int position. } LIST. Kontrolira se da li su parametri u dozvoljenom rasponu.elements[p].L) vra´ca L.. L ptr->last++.. else { for (q = L ptr->last.jedno mjesto natrag */ L ptr->elements[q] = L ptr->elements[q+1]. q++) /* pomakni elemente na pozicijama p+1. (OPCENITA) LISTA 9 Implementacija liste pomo´cu polja moˇze se precizno izraziti u C-u.´ 2.L) vra´caju p+1 odnosno p-1. p+2. . if ( (p > L ptr->last ) || (p < 0) ) error("position does not exist"). NEXT(p. p+1.1. position END (LIST L) { return (L. position p. . if (L ptr->last >= MAXLENGTH-1) error("list is full"). #define MAXLENGTH . LIST *L ptr) { position q. FIRST(L) uvijek vra´ca 0.last + 1). } void INSERT (elementtype x. q >= p. } } Ostali potprogrami su vrlo jednostavni. /* zaustavlja rad i ispisuje poruku */ else if ( (p > L ptr->last+1 ) || ( p < 0 ) ) error("position does not exist"). /* neka pogodna konstanta */ typedef struct { int last. } } void DELETE (position p...mogu´ce je zadati (ne preveliku) gornju ogradu za duljinu liste. q--) /* pomakni elemente na pozicijama p.. elementtype elements[MAXLENGTH].

.... p->next->element = x.. S druge strane neˇsto je teˇze proˇcitati i-ti element: potrebno je redom ˇcitati prvi. } position MAKE NULL (LIST *Lptr) { *Lptr = (celltype*) malloc(sizeof(celltype)).. position p) { position temp. . } . .... q = L..... . p->next = (celltype*) malloc(sizeof(celltype))...... Znaˇci.... ....... Pozicija END(L) je pointer na zadnju ´celiju u vezanoj listi.. ... position END (LIST L) { /* vra´ ca pointer na zadnju ´ celiju u L */ position q. while (q->next != NULL) q = q->next. . Postoji i polazna ´celija (header) koja oznaˇcava poˇcetak liste i ne sadrˇzi nikakav element. . i-ti element.. .1. . } void INSERT (elementtype x. pozicija od a1 je pointer na header.. ...... itd. .... . Lagano se ubacuju i izbacuju elementi na bilo kojem dijelu liste. typedef celltype *position.2 Implementacija liste pomo´ cu pointera Lista se prikazuje nizom ´celija.. . c ... drugi. . typedef celltype *LIST.. an s header Slika 2. Svaka ´celija sadrˇzi jedan element liste i pointer na istu takvu ´celiju koja sadrˇzi idu´ci element liste. temp = p->next.. Implementacija se ovako moˇze opisati u C-u: typedef struct cell tag { elementtype element. . a2 c .. } celltype. a1 c ... ......... .. Ovakva struktura se obiˇcno zove vezana lista. .. . c L ....2 Implementacija liste pomo´cu pointera... Listu poistovje´cujemo s pointerom na header. p->next->next = temp..10 2.. takoder je teˇze odrediti kraj liste ili prethodni element. Ova pomalo neprirodna definicija se uvodi zato da bi se efikasnije obavljale operacije INSERT( ) i DELETE( ).... Pozicija elementa ai je pointer na ´celiju koja sadrˇzi pointer na ai . return(*Lptr). ..... return q. .. (*Lptr)->next = NULL... pozicija od a2 je pointer na ´celiju u kojoj je zapisan a1 . LISTE 2. struct cell tag *next.. . .

..... NEXT( ).. .. ............... .... .. x ....... Implementacija liste pomo´cu pointera smatra se pogodnom pod sljede´cim uvjetima: ... ...... ...2. Stog se takoder naziva i stack. . temp = p->next. . .... .. . .. .. ............ p . .... c .... ..... ............. .. ........... . . ........ .. LIFO lista (last-in-first-out) te “pushdown” lista........ ..nije nam potrebna operacija PREVIOUS( ). c . ... ...... .c .............. .................... STOG (STACK) 11 void DELETE (position p) { position temp.. .. . ..... c c ......... ..... b b ... .... ...... .. c c .. .2 Stog (stack) Stog je specijalna vrsta liste u kojoj se sva ubacivanja i izbacivanja obavljaju na jednom kraju koji se zove vrh. . .. .. .. .. ..... p a c ...3 Dijagram za INSERT( )..... c ...... free(temp) } . ..... p->next = p->next->next. ........ . ..... ..... . ... i RETREIVE( ) su vrlo jednostavni (svode se na jednu naredbu za pridruˇzivanje). ........ ....... . ... .. Potprogrami FIRST( ). . . . temp Slika 2.... ..2.. ...... .................. .... . . ... .... . .. 2. . c ... ...... ... .....4 Dijagram za DELETE( )..... Lako se vidi da je vrijeme izvrˇsavanja za END( ) i PREVIOUS( ) O(n)... c .. ........ ....... .. a c ............. .. ......... ... p c ................ .... .. ...... ................. a ... c ..... ....... .. ... ............... ... . b ..... .. . . . ..... . temp Slika 2.... .. .. . PREVIOUS( ) se ne da lijepo implementirati: jedini naˇcin je da prodemo cijelom listom od poˇcetka do zadane pozicije...... .duljina liste jako varira ... .. . .. .... a za sve ostale operacije O(1)...ima mnogo ubacivanja/izbacivanja u listu ...... .........

.. call A3 t: ... Kad susretnemo operand. ... .. dakle umjesto (A/(B ↑ C)) ∗ D + E piˇsemo ABC ↑ /D ∗ E+. .... . .. . . Raˇcunanje se provodi ˇcitanjem postfix izraza s lijeva na desno.. Kad potprogram zavrˇsi rad uzima se adresa s vrha stoga te se na nju prenosi kontrola (na slici: q je adresa povratka u operacijski sustav). . .. Pascal... ... . BASIC-a) raˇcuna vrijednost aritmetiˇckog izraza. osim kao specijalni sluˇcaj liste. . .... .... ... stavimo ga na stog.... C. Kad susretnemo operator.. . proc A1 . .12 2... ..... . an Slika 2. Na stog se mogu stavljati i adrese iz istog potprograma (rekurzivni potprogrami). Slika 2.. Mnogi jezici (kao npr. end. . Potrebno je da program pamti adrese povratka u nadredenu proceduru.....Glavni program poziva potprograme... call A2 s: . . obavimo operaciju i rezultat vra´camo na stog... . LISTE vrh stoga ... .. Jednostavnije je ako se umjesto konvencionalne notacije koristi tzv. end. proc A2 . Stog se.. end.5 Organizacija stoga.Hrpa tanjura u restoranu.. t s r q Slika 2. prog MAIN .6 Pozivi potprograma unutar programa.. . ..7 Sadrˇzaj stoga prilikom poziva potprograma. Slijede primjeri: . hrpa knjiga na podu. Kod ulaska u novi potprogram na stog se stavlja adresa povratka u nadredeni potprogram... Obiˇcno ga se tada definira ovako.. proc A3 . . PL/I) u tu svrhu koriste stog. postfix notacija..... moˇze smatrati i posebnim apstraktnim tipom podataka.. skidamo sa stoga onoliko operanada koliko taj operator traˇzi. . a potprogrami pozivaju svoje potprograme...Interpreter viˇseg programskog jezika (npr. . call A1 r: . a1 a2 . end...

EMPTY( ). .. /* pogodna konstanta */ typedef struct { int top... STACK . . . Slijedi implementacija u C-u... ... } .. PUSH( ). funkcija ubacuje element x na vrh stoga S. dakle prema manjim indeksima polja. MAXLENGTH-1 an . TOP(S) . .&S). elementtype elements[MAXLENGTH]. potprogrami MAKE NULL( ).. . . s jednom malom modifikacijom.. Kao ˇsto vidimo.. PUSH(x.. elements 0 . . Inaˇce vra´ca “laˇz”.... void MAKE NULL (STACK *S ptr) { S ptr->top = MAXLENGTH. funkcija koja vra´ca “istinu” ako je S prazan stog.S).1 Implementacija stoga pomo´ cu polja Ova se implementacija zasniva na strukturi podataka koju smo opisali za op´cenitu listu.... } STACK. Stoviˇ se. to je ekvivalentno s INSERT(x. . funkcija vra´ca element koji je na vrhu stoga S (stog ostaje nepromijenjen).. promatrane implementacije se mogu i pojednostaviti. . .. ˇ Svaka implementacija liste moˇze se upotrijebiti i kao implementacija stoga. To je ekvivalentno s DELETE(FIRST(S). . .. . k a1 a2 . .. . . U terminima operacija s listama. listu umjesto u “gornji” smjeˇstamo u “donji” dio polja. podatak tipa STACK je konaˇcni niz podataka tipa elementtype. ... . . . POP(&S) . .2. . #define MAXLENGTH .. top k .. budu´ci da se sa stogom obavljaju jednostavnije operacije nego s op´cenitom listom. .. EMPTY(S) . Da prilikom ubacivanja/izbacivanja ne bi morali prepisivati ostale elemente.... . TOP( ) se svi svode na po jednu naredbu. MAKE NULL(&S) . 2. .......8 Implementacija stoga pomo´cu polja. . funkcija pretvara stog S u prazni stog. .. . STOG (STACK) 13 Apstraktni tip podataka STACK elementtype .&S). zadnji element Slika 2. To je ekvivalentno s RETRIEVE(FIRST(S)... POP( ). Stog raste “prema gore”.FIRST(S). . bilo koji tip.2.&S) . . . prvi element drugi element . funkcija izbacuje element s vrha stoga S.2.. .

. a1 c .top])... Ostala tri potprograma su gotovo trivijalni: MAKE NULL(&S) pridruˇzuje S = NULL. else S ptr->top++. } elementtype TOP (STACK S) { if (EMPTY(S)) error("stack is empty")......elements[S. STACK *S ptr) { if (S ptr->top == 0) error("stack is full")...14 2. LISTE int EMPTY (STACK S) { if (S.... . ... Budu´ci da kod stoga ne postoji pojam “pozicije”.... .9 Implementacija stoga pomo´cu pointera. } void PUSH (elementtype x.........2 Implementacija stoga pomo´ cu pointera Ova se implementacija zasniva na vezanoj listi (vidi potpoglavlje 2.. else return (S. ve´c je dovoljan pointer na prvu ´celiju.. Potprogrami PUSH( ) i POP( ) liˇce na INSERT( ) i DELETE( ) iz implementacije liste pomo´cu pointera..2.... Mana je da se stog moˇze prepuniti ako je MAXLENGTH premali. ... TOP(S) vra´ca S->element (ako je S neprazan).. an s Slika 2. ... O(1). else return 0.. 2. nije nam viˇse potrebna polazna ´celija (header).1).... a2 c . .. .. .. S ptr->elements[S ptr->top] = x. else { S ptr->top--. .. } Implementacija stoga pomo´cu polja je vrlo pogodna.... zato jer je vrijeme izvrˇsavanja bilo koje operacije konstantno. EMPTY(S) se svodi na provjeru da li je S == NULL. . } } void POP (STACK *S ptr) { if (EMPTY(*S ptr)) error("stack is empty").. S c . Stog se poistovje´cuje s pointerom na poˇcetak vezane liste... . . Celija je isto gradena kao u 2. .. . .. . . ..1.top >= MAXLENGTH) return 1... no neˇsto su jednostavniji budu´ci da rade samo na poˇcetku liste. .... ´ Time se struktura pojednostavnjuje... tj. Vrh stoga je na poˇcetku vezane liste..... ...

Ljudi koji ˇcekaju na ˇsalteru banke ˇcine red.. .. .10 Red.p..&Q). red se moˇze definirati kao posebni apstraktni tip podataka.Sliˇcni primjeri se pojavljuju: kod koriˇstenja jedne jedinice magnetske trake. . .. Vrijeme izvrˇsavanja bilo koje operacije je O(1). ..END(Q). . . a izbacuju na suprotnom kraju (ˇcelo). a2 a3 .Q). 2.t. . ime-datoteke-k Slika 2.. inaˇce “laˇz”.. . .2. To je ekvivalentno s RETRIEVE(FIRST(Q). Implementacije reda se opet mogu dobiti iz implementacija liste.3 Red (queue) Red (queue) je specijalna vrsta liste. Apstraktni tip podataka QUEUE elementtype . . Da bi korisnik mogao poslati datoteku na ˇstampanje ˇcak i onda kad je ˇstampaˇc zauzet. Korisnik ˇsalje datoteku na zaˇcelje reda. Navodimo nekoliko primjera za red. . . Elementi se ubacuju na jednom kraju liste (zaˇcelje). . . .. . funkcija vra´ca “istinu” ako je Q prazan red. .&Q) ... Ekvivalentno s DELETE(FIRST(Q). koji odjednom moˇze ˇstampati samo jednu datoteku. RED (QUEUE) 15 Implementacija pomo´cu pointera naizgled zaobilazi problem prepunjenja. U terminima a... ˇ Stampaˇ c ˇstampa datoteku sa ˇcela reda.&Q).. Drugi naziv: FIFO lista (first-in-first-out). MAKE NULL(&Q) . . QUEUE .-a LIST. ENQUEUE(x. funkcija pretvara red Q u prazan red. . funkcija vra´ca element na ˇcelu reda Q (red ostaje nepromjenjen). bilo koji tip.. a1 .. . zaˇcelje Slika 2.. ... .11 Niz datoteka u redu za ˇstampanje. ili kod izvodenja programa u batch obradi. u print-serveru se formira red: ime-datoteke-1 ime-datoteke-2 . . . DEQUEUE(&Q) ..... . ˇcelo an . uz odgovaraju´ca pojednostavnjenja ili modifikacije. EMPTY(Q) . Kao i stog. funkcija ubacuje element x na zaˇcelje reda Q.. to je ekvivalentno s INSERT(x.Lokalna mreˇza ima samo jedan ˇstampaˇc. FRONT(Q) .. podatak tipa QUEUE je konaˇcni niz podataka tipa elementtype. .3. funkcija izbacuje element na ˇcelu reda Q.

............. . . ........ Slijedi zapis implementacije u C-u: #define MAXLENGTH ..... . ..... . ......... . . ... . ... .. ..1 2..... ........... ... ..... . . ..... . Q ptr->rear = MAXLENGTH-1. } void MAKE NULL (QUEUE *Q ptr) { Q ptr->front = 0... . ...... ..... .. . ... .. ........ .. ... .. . . .. ... . . ... ....... ...... ... .... ... .... ... ... int front.... . .. .......... .. .... . . .......... .. . .. . . ... . ... .......... .. ... Operacija ENQUEUE( ) se tada obavlja u konstantnom vremenu......... .. . ......... . ..front) return 1. .... . . . ........ .. . ....... .... Tada viˇse nema prepisivanja........ ... .... .................. ... red “putuje” poljem u smjeru kazaljke na satu. ... ... . ... .. .... ... .. makar u poˇcetnom dijelu polja ima mjesta...... .... ........................... . .. ...... No.. .... ....... ........ ...... .... .. . red ne moˇze imati viˇse od MAXLENGTH .... .. ..... ..... ... ..... . .. . ...... ... ....... ........... . .. /* dovoljno velika konstanta */ typedef struct { elementtype elements[MAXLENGTH]...... .. .. . . .. ....... .. . ..... Red zauzima niz uzastopnih ´celija polja...... ... ..... . ....... ... } QUEUE. ..... ............ . . MAXLENGTH-1 jedno prazno mjesto rear 0 1 red front Slika 2. ..... . .. ........... ... .. .. Joˇs bolje rjeˇsenje je cirkularno polje.. ... ... ... . ... . ........ .... .......... ........ . . ... .... .. ..... ... . . int addone (int i) { return ((i+1) % MAXLENGTH). . ... . . .. .. ................ . } ... . . .. ...... .. ..... .. ..... . . ........ no pojavila se nova nepogodnost: ubacivanjem/izbacivanjem red “putuje” prema “donjem kraju” polja.... LISTE Implementacija reda pomo´ cu cirkularnog polja Mogli bismo doslovno preuzeti implementaciju liste pomo´cu polja (poglavlje 2. ...... .. . . . . ....... .. . ......3. else return 0........ ... .... .. . Dosegnut ´cemo donji kraj. . .. ....... .... ..... . Zamiˇsljamo da nakon zadnjeg indeksa ponovo slijedi poˇcetni indeks.... .. . .... ... .. .... . ... .12 Implementacija reda pomo´cu cirkularnog polja... . . . .. ... ...... ... ... Da bismo razlikovali situaciju praznog reda i posve punog reda (onog koji zauzima cijelo polje).. ....... . Tome moˇzemo doskoˇciti tako da uvedemo joˇs jedan kursor na poˇcetak reda..... .... ......... .. . . . ... .. Uslijed ubacivanja/izbacivanja elemenata.. ..... . . .... .....1 . ......... budu´ci da ne zahtijeva pomicanje dotadaˇsnjih elemenata liste...... ........ . .... . .. ... ... . .. .... . . Cirkularnost se postiˇze tako da s indeksima raˇcunamo modulo MAXLENGTH............ ......... . .. ....... ..... . . ......... . ......... . ... ... . . . ...... . . ....... ..... ..... . .. . ...... . ..... .................... . . ... ..... .. ....... .... .... .. jer zahtjeva da se cijeli ostatak reda prepiˇse za jedno mjesto “gore”.. .... ..... . . Postoji kursor na ˇcelo i na zaˇcelje............ ... .... .. .. .... . .......... .. ...... . .... ........ . .. } int EMPTY (QUEUE Q) { if (addone(Q.. .... .. . ... .... .. .. ..a1 je ˇcelo)..... .. .... ......... . . . ... ....... ... . .... .. ...... . .. .. . ... ... .... .rear) == Q...... .. . ........ ... .. . . . .. . .. .........16 2. ......... dogovorit ´cemo se da izmedu ˇcela i zaˇcelja mora biti bar jedno prazno mjesto... . . Znaˇci.. rear... ..1 elemenata. .. DEQUEUE( ) nije jednako efikasna. . ....... .. .. ......

........ ..1. Q ptr->rear = Q ptr->front............. c c front rear Slika 2. ..2. typedef struct { celltype *front... . typedef struct cell tag { elementtype element. . ... void MAKE NULL (QUEUE *Q ptr) { Q ptr->front = (celltype*)malloc(sizeof(celltype)). a1 c .... . Header olakˇsava prikaz praznog reda. QUEUE *Q ptr) { if (addone(addone(Q ptr->rear)) == (Q ptr->front)) error("queue is full"). RED (QUEUE) 17 void ENQUEUE (elementtype x..... Vrijeme izvrˇsavanja bilo koje operacije je opet O(1).13 Implementacija reda pomo´cu pointera. .. Dodajemo joˇs i pointer na kraj vezane liste.. Poˇcetak vezane liste je ˇcelo reda. . 2.. . ..... struct cell tag *next.. Q ptr->elements[Q ptr->rear] = x...3. header c . else return (Q..... } QUEUE..elements[Q.3.. else Q ptr->front = addone(Q ptr->front)... else { Q ptr->rear = addone(Q ptr->rear).. a2 c . . an . } Vrijeme izvrˇsavanja bilo koje operacije je ograniˇceno konstantom.. Q ptr->front->next = NULL.2 Implementacija reda pomo´ cu pointera Isto kao u poglavlju 2... } elementtype FRONT (QUEUE Q) { if (EMPTY(Q)) error("queue is empty").front]). . *rear.. } s .... } celltype.. } } void DEQUEUE (QUEUE *Q ptr) { if (EMPTY(*Q ptr)) error("queue is empty"). . dakle O(1).

. ...... .... . Q ptr->rear->next = NULL..... ........ ... Slika 2..... Q ptr->front = Q ptr->front->next...rear) return 1.. ........... . ....... ........ s . . .. int EMPTY (QUEUE Q) { if (Q. . .. ...prazni red. ... . } } temp c ....... ..... .. . .. ... ....... } . ...... Q ptr->rear Slika 2. . ...... . . .. else return (Q... ... . .... . else return 0........... ..... . . b ... ....... . ................. . void DEQUEUE (QUEUE *Q ptr) { celltype *temp.. if (EMPTY(*Q ptr)) error("queue is empty")..... . c a .. . . ...... . ..... .... .... .... Slika 2... ........c Q ptr->front s . ..... .. ... elementtype FRONT (QUEUE Q) { if (EMPTY(Q)) error("queue is empty")..... Q ptr->front Q ptr->rear c c c . .. . LISTE ....... c ... .... . .. } x .... Q ptr->rear = Q ptr->rear->next. ...... ..............18 2.front == Q... ...... free(temp)..... ................ .... else { temp = Q ptr->front... . .......... ..... c .. ..c .... s .. Q ptr->front Q ptr->rear c c ........ . . .. . .. ... } void ENQUEUE (elementtype x..........14 Dijagram za MAKE NULL( ) . ......... ...... . Q ptr->rear->element = x......... . .. .. . QUEUE *Q ptr) { Q ptr->rear->next = (celltype*)malloc(sizeof(celltype)). .16 Dijagram za DEQUEUE( )..15 Dijagram za ENQUEUE( )...front->next->element). a .... ......... c b .... ..... ......

. .. . .. . . . . ..... . . . r2..... .. . ... .. . .. . . .. . . .. . ..... ..... . . .. .. .. .. . .. .. . . . .. . ....... .. . . .... .. .. . .... .. ... ... . . T2 . . .. .... . . a svaki od preostalih ˇcvorova ima toˇcno jednog roditelja. . ... .. .. ... . . . . .. . .1 (Uredeno) stablo Za razliku od liste.. . . . ... Tk su djeca od r.... .... ... . . . . .. rk od T1 . . . . .. . . ..... . . . . . ...... . .. .. . . . . .. . .... . . . ........ ...Sadrˇzaj neke knjige moˇze se shvatiti kao stablo (i to zaista uredeno): 19 . Korijeni r1 . .. ... . .. .. ... .postoji jedan istaknuti ˇcvor r koji se zove korijen od T .. . . ... ... ..... . .. . . .. . . ... . .. . . .. ... . .. . . . r T T T Slika 3. . . ... .. .. .. . . .... .... . . . . . . T2 . ... . .. . . . . . .... . ... .3 STABLA 3. . ... . .. ... .. ... . . .... ... .. .... . ... .... . . .. .. .. ..... .. . .. . . ... . . .. .. ...1 Stablo T ...ostali ˇcvorovi grade konaˇcni niz (T1 . . ... stablo se zasniva na hijerarhijskom uredaju.. .. ... .. Tk ) od 0 ili viˇse disjunktnih (manjih) stabala.. . . . .. .. . . Uredenost stabla se oˇcituje u tome ˇsto medu pod-stablima postoji linearan uredaj (zna se koje je prvo. .. ... .. . .... Pritom: . .. . ..). ... . ... 1 2 k . .. . Dakle medu podacima postoji odnos “podredeni-nadredeni” ili “dijete-roditelj”. . . ... .. .. .. . koje drugo. .. . .. .. .. .. .. . .. . . .. ... . .. .. . T2 .. . ... . .. .. .. . .... .... .. . . . .. ...... ... .. .. . .... ... .. . .. . . . . .. . . . .. . . Slijede primjeri uredenih stabala. .. . . . . . . .. zasnovane na linearnom uredaju podataka. ... . . .. . .... ... . .. ... . . .. . . (Uredeno) stablo T je neprazni konaˇcni skup podataka istog tipa koje zovemo ˇ cvorovi. . Primjetimo da korijen nema roditelja. .. .. . .... . .. .. a r je njihov roditelj. . .. . .. . . . . .... . . .. . Manja stabla T1 .. Tk se zovu pod-stabla korijena r..... ..... . . . Ovo je bila rekurzivna definicija. .. . . . . . . .. .

......... Duljina tog puta je m − 1.. ..2 2. . .... .... .......... ... . .. .. .. . . .. .... .... pozicija (u kontekstu listi). . ...... . . . ..... ... .. ........ 1.. . .... Nivo 1 ˇcine djeca korijena. . .. Djeca istog ˇcvora zovu se bra´ ca...... porodiˇcno stablo.. .. .. ...... ........ korijen je predak za sve ostale ˇcvorove u stablu. ......... .......... . ..2 Slika 3... . .. .. . Stablo iz zadnjeg primjera je oznaˇ ceno stablo. .... ... . . ...... .. ...... ... . . . .... ..... 2.. . . Znaˇci. . ......... ..... .. ... i2..... ... . .. .... . .. .... je jedna od mogu´cih varijanti.. .. . .. .... . . . .2.. . .1. ... .. . . .. .. . ....... . . . ... .. . ... .. . Naˇs a..... .. ..... Niz ˇcvorova i1 ..... . . 3... ....3.20 3... Unutraˇ snji ˇ cvor je ˇcvor koji nije list. ........ Uredenost stabla je vaˇzna ako su operacije ne-komutativne...... ...... . . Oznaka ˇcvora sluˇzi za informaciju (dva ˇcvora mogu imati istu oznaku).. .. . . ... struktura drˇzave. . ... . . . . .. . ........ . Cvorovi bez djece predstavljaju operande.. .... . 2..... .. .. .......... . Ime ˇcvora sluˇzi za identifikaciju (u istom stablu ne mogu postojati dva ˇcvora s istim imenom). . .. . To se opet moˇze uˇciniti na razne naˇcine. .... . ...... . ... . .... ... .. .... . ... ... . . ... ... . .. . . ..1. ... . . .... ......... . ... ... svakom ˇcvoru je pridruˇzen dodatni podatak koji zovemo oznaka.. .. . ........... Razlikujemo ˇcvor (tj... .......... .. ..... ..... . .... .. . . .. m − 1) zove se put od i1 do im . .... ... ... ...... 1.............. .. . .. . potrebno je definirati i operacije koje se obavljaju sa stablima. Da bismo matematiˇcki pojam stabla pretvorili u apstraktni tip podataka. ......... ...1...... .. . . . ......... .. .... njegovo ime) od oznake.... ... .. .. ..... .. .. . itd... ...... . . ...... ..... ..... .. . .. 2.. a oni su njegovi potomci. .. . ... .. . . . . ... .. .. . . .... tj...... . .... . 2..2.. . . . . .2 Sadrˇzaj knjige prikazan kao stablo. . . ... ....... ... .. Za svaki ˇcvor razliˇcit od korijena postoji jedinstveni put od korijena stabla do tog ˇcvora... ..... .. ...... .... List je ˇcvor bez djece.. .... . ... .. . . ... . Sliˇcni primjeri su: organizacija poduze´ca........... . . .. ...... ....p. ..... . ..... .. ...... .... ..1 2.... . . 1.... ..... oznaka...... ......... .. im takvih da je ip roditelj od ip+1 (p = 1. ... ......... .. .. ... ....... .. ... .. ... .. .. ... ...2 3............... . .3 Aritmetiˇcki izraz (a + b) ∗ (a + √ c) prikazan kao stablo. .... . . ... 1. . ... ..... . .. .. .. ˇcvor (u kontekstu stabla) redom analogni pojmovima: lista. ...... ... .. .. . . ..... . . . nivo 2 njihova djeca. .. . .. .. .. . ....... . .. .. ........ ... . ..... . ..... . .. . * 0 + + 1 2 √ a 3 b 4 a 5 6 c ... .1 2..1. . .1.... ....... .... .... ... ... ..... ..... ... ... .. ...1.. ........ ... ...... .. .. .. ... . . .. .. .... . ... ... element.. . ...... . .. Uoˇcimo da su pojmovi: stablo... .... ... . organizacija oruˇzanih snaga... . ..... . . . .... . 7 Slika 3.. . 1... . . .. 2.. ...... . . . . .... . . ..... ........ . .. . ...... .. .... .... . .. .. .. .. . . .. ... .. . .. .. .. ... . . .. STABLA 1.. √ ˇ .... Visina stabla je maksimalni neprazni nivo.... ... . ......t.... .. 2.......... .... . .2.. ..... .. ..... .. .. . ..... ....... . ..3 2. . ........ ......... .... .... . .. . ..... ..... . . . Nivo s je skup ˇcvorova stabla sa svojstvom da jedinstveni put od korijena do tog ˇcvora ima duljinu s. Nivo 0 ˇcini sam korijen (po dogovoru). ... ... a j je potomak od i.. ... .. ........ ... .. .... .. .... . .... . ...... ...1. . ...... ....... .. .. ... .... .. .. .... . . . .. . .. .... . . Ako postoji put od ˇcvora i do ˇcvora j tada je i predak od j. . ... ... ..... . ..... .. ..... . .. .. . .... ...Grada aritmetiˇckog izraza (a + b) ∗ (a + c) se moˇze prikazati stablom.... .1 2.. .. .. . .. ... . ........ .. a ostali ˇcvorovi raˇcunske operacije. .. . . .. .. ... .. .. . ... ..... . .. .. ............ ...... ... . .. . 2.....

.........1..... . . . .. NEXT SIBLING(i. .. ....T) . ... . .. .. ..T) ...... funkcija vra´ca roditelja ˇcvora i u stablu T. . labeltype .. . .. .i. .... .. .. ..... ... Nije definirana ako i ne pripada T.... ....... . .... funkcija u stablo T ubacuje novi ˇcvor s oznakom l... .. (UREDENO) STABLO 21 Apstraktni tip podataka TREE node ... ... .. ... ...... . . . ..&T) .... .. . .... vra´ca LAMBDA... . . podatak tipa TREE je (uredeno) stablo ˇciji ˇcvorovi su podaci tipa node (medusobno razliˇciti i razliˇciti od LAMBDA)...T) . ..... . Funkcija vra´ca novi ˇcvor.... ....T) ..... . ..4 Dijagram za INSERT CHILD( ). .. ..... . . FIRST CHILD(i. . .. .... TREE .. . . ... . . . .... ... ...... . INSERT CHILD(l... ... . .... ... ..... . ... ..... . Nije definirana ako i ne pripada T.. . . ... ... .. . U skupu node uoˇcavamo jedan poseban element LAMBDA (koji sluˇzi kao ime nepostoje´ceg ˇcvora)..... ... i l Slika 3.. funkcija vra´ca korijen od stabla T.. .. . i l Slika 3... funkcija vra´ca oznaku ˇcvora i u stablu T. funkcija pretvara stablo T u stablo koje se sastoji samo od korijena s oznakom l. . . . ........i.. PARENT(i. tada vra´ca LAMBDA. ...... . . . .. Ako je i korijen.. Nije definirana ako i ne pripada T.. . ....... .. .. ..... .. .... ........ .... . ... .... .5 Dijagram za INSERT SIBLING( ).... .. ......... . .. . . Svakom ˇcvoru je kao oznaka pridruˇzen podatak tipa labeltype...... .. . Funkcija vra´ca novi ˇcvor. . .. ... . ..... DELETE(i.. ili ako i ne pripada T ili ako i ima djece......... .... .. . . tada vra´ca LAMBDA.. . . ... INSERT SIBLING(l........ .... . ... . funkcija izbacuje list i iz stabla T.. .. . . Nije definirana ako i ne pripada T.. .. Nije definirana ako je i korijen.. .. . .. Nije definirana ako i ne pripada T. . ... ... ..&T) ........ .... . . ....... ROOT(T) .. ...... .. .. .. ...&T) .. ... . . . . . tako da ta oznaka postane l.. . .. .... . ... ... funkcija vra´ca prvo po redu dijete ˇcvora i u stablu T.. LABEL(i..... funkcija vra´ca idu´ceg po redu brata ˇcvora i u stablu T... njegovo ime). CHANGE LABEL(l.. funkcija u stablo T ubacuje novi ˇcvor s oznakom l.. . ... ... . bilo koji tip (oznake ˇcvorova)... ... .... .. . .. . .. MAKE ROOT(l.. .. tako da on bude idu´ci po redu brat ˇcvora i. . ... . . ........ ... .. funkcija mijenja oznaku ˇcvora i u stablu T... . .... ..&T) . .. Nije definirana ako je i korijen ili ako i ne pripada T... . .. .. . .. .. . Ako je i list.........i.... ..... ...... tako da on bude prvo po redu dijete ˇcvora i.. . ..........&T) .... .... ...... . . Vra´ca ˇcvor koji sluˇzi kao korijen (tj. . . .....3. .. Ako je i zadnji brat... ... Nije definirana ako i ne pripada T. . . . ...... .. . .. .. . bilo koji tip (imena ˇcvorova). .

. .. . . . printf (". ....0. .. .... ......... .. . ... ..... .. . . ... .. .9. ...1 Obilazak stabla Obilazak stabla je algoritam kojim “posje´cujemo” ˇcvorove stabla... ...... .... . . ... .6 Obilazak stabla.. Ova tri algoritma zadajemo rekurzivno. . . ... .. ..5. .. .... .. .... . .. ... . ........ . . ......... ..... .. zatim obilazi T2 .. .. ... zatim obilazi T2 .. ... .... . ... .. .. . .. ...... . ...... .. .. .... . ..... .. ... .... . . .. . najprije obilazi T1 .. . .... . .. ..2. ...... . .... ...... ....7. Primjetimo da svaki obilazak uspostavlja jedan linearni uredaj medu ˇcvorovima.T). . ... na kraju obilazi Tk . . . ..T). .. .. . . .. TREE T) { /* obilazi se pod-stablo od T kojeg ˇ cini ˇ cvor i s potomcima */ node c.... . ... . .. ........ .. .. . . na kraju posje´cuje r... . . . . .. . .6.. . ispisati oznake)... na kraju obilazi Tk .. .. .. ... . .... .. . .. zatim obilazi Tk . . . .... . ... . . ... Neka je T stablo sastavljeno od korijena r i pod-stabala T1 . . .. ... .. . . . . tako da svaki ˇcvor posjetimo toˇcno jednom.. . ......... .T). . . .. . .... .. . } } . . .... obavljati i razne druge vrste obrade ˇcvora.. ..22 3.. . . . U sljede´cem potprogramu operacija posje´civanja ˇcvora pretvorena je u ispis oznake ˇcvora. ... .. . . .... ... To je potrebno ako ˇzelimo obaviti neku obradu nad svim ˇcvorovima (npr. .. ..... . ... .. .. . .. ..... . . .5.... . ...9. ....6..2... . .T))....... . ˇ Razlike izmedu triju obilazaka vidljive su iz primjera... .. . ..... ... ... . . ... . .. . . .8..... .. .. POSTORDER( ) .. . ....... .. . .... . .. .....2.. ... . . . .... . . ... ..... while (c != LAMBDA) { PREORDER (c...5.... .... .. .... .... ... .. . ..... ... ... .. ..... . ....... T2. .... ...... ..... c = NEXT SIBLING(c..... ...3.... . . ..... .. .... ....... . . . ........ ... . void PREORDER (node i....... . .. . Mogle bi se.3 POSTORDER( ): 1.. . . . . . .. . .. ....... . . .. .. . . ... . .. . .. ...... .. .. . najprije posje´cuje r.. Najpoznatiji obilasci su: PREORDER( ). .. . .......... .. . ..... ... .. .. . . ....1.. . Cvorove stabala na slici algoritmi obilaze u sljede´cem redosljedu: PREORDER( ): 0.......... ...... ..... .. . . . . najprije obilazi T1 . . .... .. . . . . ... .. .. ............. .... ..... ...... . .. .. ... .. .. .... . . .. .. .... . .. ... .. .. Tk od korijena (vidi sliku uz defininiciju stabla). . .7.. . .... zatim obilazi T1 . ... . . . ... .... . ..... ... . .... . ... .... . STABLA 3.... ... . . ...... naravno.4..... . ........ . .. ....3. .8. .... .......... .8. .... . . ..... ...... ... . . ...... . . .. .. . . .. INORDER( ) ... . . ... . ... .. U apstraktnom tipu podataka TREE algoritmi obilaska mogu se zapisati kao potprogrami. 0 1 2 4 7 3 5 8 6 9 Slika 3.. .. POSTORDER( ).. . zatim posje´cuje r. .. . ...... . . . LABEL(i.. .7.. . .... .. ... .. ...9. .6 INORDER( ): 1... .. . . .... . . .. .. ...... . ....... .. . . .............. .. .. ... ... .... . .. ... . ... . ... .......... .. .. . . . ... .. .. . . ... . . .... .. ..4.... . . .... . .. . ..........0 ..... ... .. .... .... . .. . ... .. . ..... . . . .. . . INORDER( ).. Tada: PREORDER( ) ... .. .. . ...... .... . ........ . .........1. ... . . . .... zatim obilazi T2 .. ..".... . .... .. .4.. . ... .. c = FIRST CHILD(i.....

... .. .... .... .. .... . . .... .. .. . . ... .. .. . . . . .... . .. ... . . . .. .. ........ ...... .. .. ... ......... . .... ... ... . ... .... ... ..... ... ... . ... ...... .... . .... ... . .... . . . ..... .. . . .. .. ..... . . ... ................ .. ......... . . . .. ... .. ... .. . ...... ...... ... . . ..... .. .. . .. .... ..... . ... .......... ..... ......... . ........ .... ....... .. . . . . .... . .. .. .. ..... ..... .. .. ...... .... . .... .... .... .. ... ... ....... . . .. .. .............. . .. . .................. . . ..... ... .. . .. ..... . ..... ... . ..... . . .... .. .... ..... ..... .. . ... . . . . ........ ..... ... ... .... .. ..... ... .... . . ... ... ... ... . ....... .. ... . . .. ...... 0 a b c 1 2 d e 3 a c 4 8 6 7 d 5 b 9 root 0 0 1 2 3 4 5 6 7 8 9 label a b c d e a d e c b parent -1 0 0 1 1 4 4 4 2 2 e Slika 3.. .. ... ..... . ... . . .. .... ... . . . ... . ... .. .. .. . .. . ... . . . . .. . ..... . ...... ..... .......... ..... . .... Stablo prikazujemo poljima. .... .. . . .. ... .. . .. . .1... ...... .. . .... ...... .. ..... labeltype label[MAXNODES]. .. . .. .... .... .... . . .. ..... . ...... . ... .. .. s obzirom na razne prikaze skupa ˇcvorova. .. .... . .. . . .. . .. .. .. gdje je n broj ˇcvorova... . ... ... . .. ... ... . .. . .. .... . .. ... . . ... . . ..... . ... ...... ...... .... ... . . .... . .... .... .... ............... . .. . .. . . 1.. .. ...... .... ... .... .. . .. ..... . . .... .. . ... ... .. . . ..... .... ..... Dakle: #define MAXNODES . .. .. .. .. . .. ... .... .. ... . . ...... .. .. ... .. .. ...3. . .. ..... 3. .. .. ... .. .. . .. . .. .. node parent[MAXNODES]... . . . ......... . .. .... . ... ........... .... .. .. . ... . .... .. ... .... . . ..... ... .. ..... ....... . .. . . i-te ´celije polja opisuju i-ti ˇcvor i u njima piˇse oznaka tog ˇcvora odnosno kursor na roditelja. . ..... . . .. . . .. .. .. .. .... .. ... .. . . ... . .. . typedef struct { node root... .... .. .... . .. ....7 Podstablo od T s korijenom i..... ... ... . .. ....2 Implementacija stabla na osnovu veze “ˇ cvor → roditelj” Zasniva se na tome da svakom ˇcvoru eksplicitno zapiˇsemo njegovog roditelja.... ... ...... . .. ...... . ... .. .. ... ... ... ..... ... .... .... .. ..... .. . . .. ...... .. ... . .. . ... . ... ..... ....... Mi uzimamo (bez velikog gubitka op´cenitosti) da su imena ˇcvorova cijeli brojevi 0.. . .... ....... .... ..... . . ... .. ... .. ......... .. . ... . ...... . .... . ...... . .. ..... ... . .. .. ..... .... ......... . .. . ... . ...... .. ... ....... . ... ... . . ........ ..... . ... . .... .... ... . . ... ..8 Implementacija stabla na osnovu veze “ˇcvor → roditelj”.. .... .. . ....... . ...... .. } TREE. . .. ..... ... ... . . .. .. ....... ..... . .. . ..... .... .. .. .. .... Mogu´ce su razne varijante.. ... ..... .... .. .. .. . .... .. . . . .. . .... . ...... ... .. .. ...... ...... ..... ... ...... . . ... .. .. . . .. .. .... . . . . ...... .......... . . . . ........ .. .... . ... .... ....... i Slika 3... . ..... .. .. .. ...... . .. .. . ... . . ......... .. . . . .. ... . (UREDENO) STABLO 23 T ..... .. . . ... .. ....... ...... 2. ..... . ... . . .. .... .... ....... . ... ... .. . .... . /* dovoljno velika konstanta */ #define LAMBDA -1 typedef int node... .. . ... . .. ...... ... ... .. . .. ... .. ..... . . .. . .. .. . . . . ... ..... ..... ... . .. .... .... ... . . ... .. ... . ........ .......... ... .. .. . ..... .... .. . . . . .. .... . ... .. ... . . ... .. .. . ... .. . .. .. .... .. .. ...... ... ... ... . . .. ... . . .... ...... .... .. . ... .... .. . . ... ..... ......... ...... ........ . . . ... ..... .... .. . .. .. ... .. ....... . . .. . . .. . . .. ....... .. . .. .. ..... .1...... ...... .. n − 1.. ... ....... . ...

. /* ne postoji idu´ ci brat */ } Opisana implementacija je dobra ako: nema mnogo ubacivanja/izbacivanja ˇcvorova. .. ... ...... ... .. .. .. .... . . . Tada vrijedi: node NEXT SIBLING (node i. . .. ........ . ... .. } node struct.. .. . ... ..... p = T.. ... ........ . . . j<MAXNODES... .. . ... . .parent==i). ...... . . . . /* dovoljno velika konstanta */ typedef int node. ... .. .... ....... return LAMBDA.. ......... .. .... . ... next sibling.. . .... . for (j=i+1. Polje predstavlja “zalihu” ´celija od kojih ´ce se graditi stabla. . ..... Veza od ˇcvora do djeteta odnosno brata moˇze se realizirati pomo´cu pointera ili pomo´cu kursora.. .. . ... . .. ...... . .. . TREE T) { node j. . .... .. ... .. . . ..3 Implementacija stabla na osnovu veze “ˇ cvor → (prvo dijete. ... .... . . 3... . .. .. Daljnja mana je da se ne pamti redosljed bra´ce . ....... . ..... ˇciji poredak pokazuje globalni kursor avail. .. .. . ... idu´ ci brat)” Zasniva se na tome da svakom ˇcvoru eksplicitno zapiˇsemo njegovo prvo dijete.. .. ... . . #define MAXNODES . i-ta ´celija opisuje i-ti ˇcvor. .. .. .. .... ..... .. .. ..... .. . .. ... ... .... .... ... ... T[i]. dakle: typedef int TREE.. . .... . .... .... . ..... ..24 3. . .... ... Opisana struktura dobro podrˇzava operacije PARENT( ) i LABEL( )....... .. .. ... .. .. .. .............. ..parent[i]. .. . . .. . .... . ... ..... .... .. ......... u komponenti next sibling. . Moˇzemo ih oznaˇciti i prepoznati tako da im upiˇsemo neku nemogu´cu vrijednost (npr.. neke od ´celija su slobodne.1. .... ... . Sve slobodne ´celije (koje ne pripadaju ni jednom stablu) povezane su u vezanu listu. .. T2 F 2 E G 0 H 6 3 ...parent[j] == p) return j. STABLA Kursor root pokazuje gdje se nalazi korijen stabla.. ... . . . . Razna stabla s kojima radimo troˇse ´celije iz istog (jedinstvenog) polja SPACE[]. ...... typedef struct { labeltype label. Razmatrat ´cemo varijantu s kursorima... .. Slobodnu memoriju zauzmemo globalnim poljem SPACE[]. ... Ipak.. . ... ... ..... . ........stablo je zapravo neuredeno... nije potrebna uredenost stabla.. .. node first child. .. .. .. .. .... ... preteˇzno se koriste operacije PARENT( ). moˇzemo uvesti umjetno pravilo da su bra´ca poredana po svojim imenima (indeksima). .... .. .... . ..... . ..... ... .. j++) /* u polju traˇ zimo ´ celiju nakon i-te u kojoj je upisan isti roditelj */ if (T.. te njegovog idu´ceg brata.. .. . . . .... .. . .. .. . ... Ako je MAXNODES ve´ci od stvarnog broja ˇcvorova... ... T1 9 A B C 4 10 D 1 .. ... . ................. .. . .. .. . ... ... .. .. . . . . Slobodne ´celije se veˇzu kursorima smjeˇstenim npr. .. Stablo se poistovje´cuje s kursorom na korijen. .. . .... .. . . p.... LABEL( ). .. Ostale operacije zahtijevaju pretraˇzivanje cijelog polja. Imena ˇcvorova su cijeli brojevi. . Stablo je prikazano kao vezana struktura ´celija.. .... .. ... node struct SPACE[MAXNODES].. ..

...... . ...... .. node i) { node temp... ...... avail = SPACE[avail]..... ... ..... .... return temp. ili kad se radi s viˇse stabala koja se spajaju u ve´ca ili kada se intenzivno koriste veze od roditelja prema djeci..next sibling = SPACE[i]..... . SPACE[temp]... (dosadaˇsnje prvo dijete od i) Slika 3........ 5 . (UREDENO) STABLO 25 SPACE .. ...... ...3. ... . ....... .... ... . ... 8 .. SPACE[temp]. .. Npr.... .. ..... . ..first child = temp... .. B ...... 4 . .... .. } } i temp ..... .. . next. . .. 7 . ..... . 3 . . T1 9 T2 2 avail 5 0 F -1 6 1 D -1 -1 E 0 -1 H -1 -1 B -1 ... . -1 (novo prvo dijete od i) .. . . B . ... .... ...... ..... B B . . .. .label = l.. B B B .......10 Dijagram za INSERT CHILD( )..... .. l .... ... ..... Slika 3.... SPACE[i]. . .. 6 .1. else { temp = avail.. .....next sibling. if (avail == -1) error("no space").... ...... . ... .. . ......... . . . ............ Opisana implementacija je pogodna onda kada ima puno ubacivanja/izbacivanja ˇcvorova. .... . .first child = -1... .. Sve operacije osim PARENT( ) mogu se efikasno implementirati.: node INSERT CHILD (labeltype l....... 2 .. ..first child...... ...... . 9 10 11 G -1 3 8 -1 10 A 4 -1 C 1 -1 7 11 label first.9 Stabla T1 i T2 koriste ´celije iz istog polja. ...... ... .. . SPACE[temp]....... . . . ...... ..B. . .

.... .. Pri tome vrijedi: ...... ... . .... ....... .. ...... . . . ..... ili . .. . .. .. ... . Korijen od TL (ako postoji) je lijevo dijete od r. tada se binarna stabla TL i TR zovu lijevo i desno pod-stablo.. ...... . . ... .... ........ . .. .. ... .. ......11 Binarno stablo.. ... .. ..... .. . ... ..... .. . .. . . .. .. ..... . ..... ..12 Dva razliˇcita binarna stabla.. . .. r T T Slika 3. .. . . Primjetimo da binarno stablo nije specijalni sluˇcaj uredenog stabla.... .. ... ..... . .... ..... .T je prazan skup (prazno stablo) . .. . . . .. .. . .. ...... STABLA Ako nam je takoder potrebna i operacija PARENT( )....... . .. ... .... .. .... .. .. . ..... . ..... . ...... .. . . . . . .. .. .. .. .. . .. .. .. . ... ..... .. .... ... . . Primjenjuju se isti algoritmi obilaska.. . . .. . .... . . .. .... .. . . .. .. ...... . ... ... ... ... ... . . . ..... .. . .... . .... . .. .. .. .. .... . . . . L R .. .... ..... .. ... ...... ... . ....26 3. . . . .... Radi se o neˇsto jednostavnijem i pravilnije gradenom objektu kojeg je lakˇse prikazati u raˇcunalu.. . . ........ .. . a ostali ˇcvorovi grade uredeni par (TL ....... .. ... . . ... ..... . . .. . .. .. .. . . TR ) disjunktnih (manjih) binarnih stabala.. .. ... . ..... ...... .... .... . .... . ... Naime: ... .. .. ..... .. ........ .. .. . . . .. ... ... .. .. ...binarno stablo moˇze biti prazno....... ... .. . .... . .. . ..... . ... a r je njihov roditelj... Ako T sadrˇzi korijen r... . .. ... . . .... ... .. ..postoji istaknuti ˇcvor r koji se zove korijen od T ....... ... .. .... . korijen od TR (ako postoji) je desno dijete od r.. .. ... . .. ... ... ... .. . ... . . .... .. .. ..... . . . . .... . . ..... .. . ..... .. . . ... .. ............. .. ......... ....... ... Binarno stablo T je konaˇcan skup podataka istog tipa koje zovemo ˇ cvorovi. ...... .......... ........ .. . ..... ... tada moˇzemo u ´celiju polja SPACE[] dodati i kursor na roditelja... .... ...... tada nije svejedno da li je to lijevo ili desno dijete. 3. ... . . ... . . . .. .. .. .. .......... .. ...2 Binarno stablo Umjesto stabala (koja se ˇcesto razmatraju u matematici) u raˇcunarstvu se joˇs ˇceˇs´ce pojavljuju binarna stabla.... . .ako ˇcvor u binarnom stablu ima samo jedno dijete. ...... . . . . . .. ...... 0 1 2 3 4 ....... ........ ..... ... . .. .... . . .... ..... ... . ...... .... . . . . .... .... . . .. ... . . Ostala terminologija je ista kao kod stabla. .. ...... ... ........... .. .. .... ....... .. ... .. ... . .. . .. 0 1 2 3 4 Slika 3............. . ... ..... ... ...... ..... ..... . ........ .. ... .. ..... .. ...... .... . . ... .. . ... .. . . ... .. . ............ .. .. ...... ...... . .. . . ... .... .... . ... . ..

. .. . .. . Tada se postupak dekodiranja moˇze prikazati binarnim stablom: znak a b c d e kod 000 001 010 011 100 .............. .... ...... ......... .... .... .. .. .............. .. ..... .. .. .... . .... . . . ... . ..... ... ... . ... .... .. . . . . .. ... .. . . ........ .. .1) ...... .... .. 0 0 1 1 0 0 1 0 1 0 a b c d e Slika 3. .......... ... . . .. ........... . .. .. . . . .... ... .. . ...... . .. ... .. .. ..... . .... .... . . . no tada bi to bilo jedno te isto stablo.Bilo koje uredeno stablo moˇze se interpretirati kao binarno stablo.. .. .. . ........ . . .. ......... ..... . . . . ... . . . . .... .. ....... ..Znakovi su kodirani nizovima bitova..... . .. .. .. ..... ........... .... . .. ... .. .. ... ... . na osnovu veza ˇcvor → prvo dijete i ˇcvor → idu´ci brat. .. .. .......... ..... . . . .... .. BINARNO STABLO 27 Na dijagramima se vide dva razliˇcita binarna stabla.... .. . . ..... . . ... ... ..... . ... .......... .... .. ... .: 0l l l l l l l l 1 2 3 . . .. . ... ... .. .. ... .. ...... ... ... ..... . . .. .... ..... ...... Isti dijagrami bi se mogli shvatiti i kao uredena stabla. . . . ... ............ .. .. ... .. . . . . . . . .... ............ .. .. ... .3. ......... . .. . .... .... .. ...13 Prikaz binarnog koda pomo´cu binarnog stabla. . .. .. .... ... .. . .... ... . . ....... .. ..... ... ..... .. .. . .... . .. ...2. .. ...... .... ..... .. . ..... ... . ... . . .. . . . ..... ...... .... .. ... .... ... .. . ....... ..... . ..... . . . .... .... ..... .... .. .. . ..... ... .. .. ..... . .... ... .. ... ...... .. .. ..... . . . .... ..... .. ... .. .. . ... ................... Slijede primjeri binarnih stabala: . .... ..... ... . . ... .... Npr. ......... .. . .. .. . ... . ... .. ... . .. . .. . ... . . ... ....... . . .... ....... .. . ..... . ..... ... ... . ........ .. . .. .... . . ......... .... . . ..... . . .. .Ako je aritmetiˇcki izraz sasavljen od binarnih operacija tada se njegova grada moˇze prikazati binarnim stablom (vidi primjer iz poglavlja 3.. .

L  S .

L  S .

L  S l l l l l 4 5 6 7 8 9l 0l .. . 1l 2l 3l .......

% .

% .

14 Interpretacija stabla kao binarnog stabla..Daljnji vaˇzni primjeri slijede u poglavlju 4.. Binarno stablo se moˇze upotrijebiti za prikaz skupova. .... .   1l @ @ l 4 2l AA  AA 5l 6l 3l  l 7 AA 8l AA 9l Slika 3. . Zapravo se radilo o implementaciji binarnog stabla. % 4l 5l 6l 7l 8l 9l 0l .. Ovu pretvorbu smo ve´c nehotice koristili u drugoj implementaciji stabla..

bilo koji tip (imena ˇcvorova). .2.i. U skupu node uoˇcavamo jedan poseban element LAMBDA (koji sluˇzi kao ime nepostoje´ceg ˇcvora). Nije definirana ako i ne pripada T ili ako i ve´c ima dotiˇcno dijete.&T) . . RIGHT SUBTREE(T. Imamo definicije: typedef struct cell tag { labeltype label. typedef celltype *BTREE. ROOT(T) . Ako je i korijen. . PARENT(i. . funkcija mijenja oznaku ˇcvora i u stablu T.1 Implementacija binarnog stabla pomo´ cu pointera Svakom ˇcvoru eksplicitno zapiˇsemo njegovo lijevo i desno dijete. . . Neke od njih se mogu izvesti pomo´cu drugih. funkcija u binarno stablo T ubacuje novi ˇcvor s oznakom l. . MAKE NULL(&T) . Nije definirana ako i ne pripada T. Nije definirana ako i ne pripada T. EMPTY(T) . Osim operacija koje rade na nivou ˇcvorova. tako da ta oznaka postane l. . Apstraktni tip podataka BTREE node . funkcija vra´ca korijen binarnog stabla T. Korijen od T dobiva oznaku l.T) .&TR) . funkcija vra´ca “istinu” ako i samo ako je T prazno binarno stablo. funkcija vra´ca roditelja ˇcvora i u binarnom stablu T. . . CHANGE LABEL(l. CREATE(l. funkcija stvara novo binarno stablo T. Varijanta pomo´cu kursora bi bila gotovo identiˇcna implementaciji opisanoj na kraju poglavla 3. .TL.&T) . Nije definirana ako i ne pripada T ili ako i ima djece. kojem je lijevo podstablo TL.i. struct cell tag *leftchild. lijepo se mogu definirati i operacije na nivou pod-stabala. typedef celltype *node.i. . . Veza se moˇze zapisati pomo´cu kursora ili pomo´cu pointera. no ipak ih navodimo zbog spretnijeg rada.&T) .28 3. RIGHT CHILD(i. tako da on bude lijevo odnosno desno dijete ˇcvora i. vra´ca LAMBDA.T) . . Funkcija vra´ca novi ˇcvor. . .&TL). tada vra´ca LAMBDA.1. struct cell tag *rightchild. funkcija pretvara binarno stablo T u prazno binarno stablo. LABEL(i.&T) . labeltype . Ako je T prazno. Nije definirana ako je T prazno. . . . Zato promatramo varijantu pomo´cu pointera. funkcija vra´ca lijevo odnosno desno dijete ˇcvora i u binarnom stablu T. DELETE(i. 3. . STABLA Binarno stablo se na razne naˇcine moˇze definirati kao apstraktni tip podataka. .&T). Ako i nema dotiˇcno dijete. . INSERT RIGHT CHILD(l.TR. a desno pod-stablo TR (TL i TR moraju biti disjunktni). Nije definirana ako i ne pripada T. . . . bilo koji tip (oznake ˇcvorova). Nije definirana ako i ne pripada T. INSERT LEFT CHILD(l. LEFT SUBTREE(T.T). . vra´ca LAMBDA. . Izloˇzit ´cemo priliˇcno opˇsirni popis operacija. } celltype. Svakom ˇcvoru je kao oznaka pridruˇzen podatak tipa labeltype. LEFT CHILD(i. BTREE . funkcija izbacuje list i iz binarnog stabla T. . podatak tipa BTREE je binarno stablo ˇciji ˇcvorovi su podaci tipa node (medusobno razliˇciti i razliˇciti od LAMBDA).T) . funkcija vra´ca oznaku ˇcvora i u binarnom stablu T. funkcija preko parametra TL odnosno TR vra´ca lijevo odnosno desno pod-stablo binarnog stabla T. .

............ .. ... ..... . ...... .. B C D E F T ..... . G . BINARNO STABLO 29 ˇ Svaki ˇcvor prikazujemo jednom ´celijom.. . ..... ... ........... ........ ... ..... ......2.... ..... ... Npr. . . . .. . . ... tako da vrijeme izvrˇsavanja bude O(1).... .....3... ....... . C .. .. Ukoliko koristimo funkciju PARENT(). F ... ...2 Implementacija potpunog binarnog stabla pomo´ cu polja Potpuno binarno stablo je gradeno od n ˇcvorova. ... G . . .. ... ............ .... .. .. E .... .. .. . ... ....... . ...... .... . .. .. .. .. . .. .... ... ....... ... . .... ... . .... ...... . .... . .. .. . .. Prazno stablo je prikazano pointerom NULL... . . ......... ..... .... B ... .........t. .. .. ...... . ..... . . (*Tptr)->rightchild = TR. .desno dijete ˇcvora i je i ˇcvor 2i + 2 (ako je 2i + 2 > n − 1 tada i nema desno dijete)... ..... . } 3....... .. . ....... . ... ... ... ....... . ... .... .. ..... ...........15 Implementacija binarnog stabla pomo´cu pointera............... ......... .. . ..... . .... ..... ... . .. .... . ... Npr... . ..... .. .. . .. .... . . . ...... . ...... ....... .. ......... . . ...... tada je zgodno u ´celiju dodati joˇs jedan pointer. 2... ... .. .. . . . . ...... ... .... .. ...p.. ... . . . .... .. ...... .. ... ..... ..... ... .2. .. .............. .... .... . . ... potpuno binarno stablo s n = 12 ˇcvorova izgleda kao na slici.... ..... ... ... . .. . .......... .. . ... ... ........ . Sve operacije iz a........ .. ...... . . ...... ... ...... .. .. . .. ... ........ BTREE TR. ...lijevo dijete ˇcvora i je ˇcvor 2i + 1 (ako je 2i + 1 > n − 1 tada ˇcvor i nema lijevo dijete)...... .. . .... ... ... .. .... .. ...... ... ... ............: void CREATE (labeltype l... ...... .... .... BTREE se mogu efikasno implementirati......... ..... .. . ... .. A . BTREE *Tptr) { *Tptr = (celltype*)malloc(sizeof(celltype))... .. . ... .......... . ....... .. ...... ... s imenima 0. ...... ......... . . ...... .. .. .. . .. . . . . ... .... . . ... ..... . .. ... D .... .... . ... .. .... Cvor je zato jednoznaˇcno odreden pointerom na tu ´celiju... ..... . . Binarno stablo poistovje´cujemo s pointerom na korijen. ..... ......... ..... .. .. 1...... . (*Tptr)->label = l... . . n − 1...... ... .. . (*Tptr)->leftchild = TL.... ....... ... ... ........... ... ........ ..... BTREE TL. ...... ... . .. . . . .. .... . . .. ... . ...... ... ....... . ... ... . . . Slika 3.......... A .. .... Binarno stablo se gradi kao struktura ´celija povezanih pointerima..... . ..... .. .. . . .... .. .. ..... .. . Pritom vrijedi: ..... . ... ........ .. .. ...... ..... . ..... .. ......... . .. ....

30

3. STABLA
..................
...
..
....
..
....
.....
.. .
.... ................. ........
.
.
.
.
....
...
.
.....
.
.
.
..
.....
.....
....
.....
.....
....
....
.
.
.
.....
....
.
.
.....
.
...
.
....
.
.
.....
....
.
.
.
.....
....
.
....
.
.
...
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
...................
...
.
...
..
..
....
....
...
..
.
...
.
..
...
.
..... ......
...... .......
.
.
.
.
.
.
.
.
.
.
.
.
... . ......
.... .. ......
.
.
.
.
....
....
..
..
....
....
...
...
...
...
....
....
...
...
....
....
...
....
....
...
.
.
.
.
....
.
....
..
.
.
.
.
.
....
...
..
...
.
.
....
.
.
.
....
.
.
.
.
.
.
....
.
.
...
.
..
.
.
.
.
.
.
.
.
.. .
....
.. ..
......
...... ........
...... ........
...... ........
...... ........
.
.
.
.
..
..
..
..
.
.
.
....
.
.
.
..
..
..
.
..
..
.
...
...
.
.
.
.
.
...
...
...
..... .....
..... .....
...................
..................
...............
...............
...
. ..
. ..
.
.
.
.
..
..
..
..
..
..
..
..
..
..
...
...
..
..
...
..
..
..
..
..
..
..
..
..
...
.
.
..
..
.
..
..
...
...
..
..
..
..
..
..
..
..
..
..
..
..
...
........
........
.........
........
.
.
.
.
.
.
.
.
...........
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
...
.
....
...
...
..
.
.
.
.
...
..
..
..
...
..
...
...
...
...
..
..
.
....
...
...
...
...
..
..
.
..
.
.
.
.
.
...
..
.
.
.
.
.
.
.
.
.
....
..... ....
..... ....
.... ......
..................
...............
...........
..........
..........

0

1

2

3

7

4

8

5

9

10

6

11

Slika 3.16 Potpuno binarno stablo.
ˇ
Na svim nivoima osim zadnjeg postoje svi mogu´ci ˇcvorovi. Cvorovi
na zadnjem nivou su “gurnuti” na
lijevu stranu. Numeriranje ide s nivoa 0 na nivo 1, nivo 2, itd., s lijeva na desno.
Potpuno binarno stablo treba zamiˇsljati kao objekt sa statiˇckom gradom. Na njega se ne namjeravaju primjenjivati operacije poput CREATE(), LEFT SUBTREE(), RIGHT SUBTREE(), jer rezultat viˇse ne
bi bio potpuno binarno stablo. Umjesto toga potrebno je “manevrirati” po ve´c zadanom stablu, te
ˇcitati ili mijenjati oznake ˇcvorova. Eventualno se dopuˇsta ubacivanje/izbacivanje ˇcvorova na desnom
kraju zadnjeg nivoa.
labels

last

0

l0

1

l1

2

l2

.
.
.
.
.
.

.
.
.
.
.
.

....
..
....

n ..− 1

MAXNODE-1

ln−1
.
.
.
.
.
.
.

.....
..
..
.

..
...
..
..
....
.....
.
.....
...
...
....
.
..
..
..
..
.
.
.
. ...
..
.
..
...
....
.....
...
....
...
...
.
..
.
.
....

puno

prazno

Slika 3.17 Implementacija potpunog binarnog stabla pomo´cu polja.
Potpuno binarno stablo se moˇze elegantno prikazati na raˇcunalu pomo´cu polja. i-ta ´celija polja
sadrˇzi oznaku ˇcvora i. Takoder imamo kursor koji pokazuje zadnji ˇcvor n − 1. Dakle imamo definicije:
#define MAXNODE .../* dovoljno velika konstanta */
typedef int node;
typedef struct {
int last;
labeltype labels[MAXNODE];
} BTREE;
Manevriranje po stablu se obavlja na oˇcigledni naˇcin. Korijen je predstavljen 0-tom ´celijom. Lijevo
i desno dijete ˇcvora iz i-te ´celije nalaze se u (2i + 1)-oj i (2i + 2)-oj ´celiji (ako postoje). Roditelj ˇcvora
iz i-te ´celije je u b(i − 1)/2c-toj ´celiji.

4

SKUPOVI
4.1

(Op´
ceniti) skup

U mnogim algoritmima kao matematiˇcki model pojavljuje se skup. Znaˇci, pohranjuje se kolekcija
podataka istog tipa koje zovemo elementi. U jednoj kolekciji ne mogu postojati dva podatka s istom
vrijednoˇs´cu. Unutar kolekcije se ne zadaje nikakav eksplicitni linearni ili hijerarhijski uredaj medu
podacima, niti bilo kakav drugi oblik veza medu podacima. Ipak, uzimamo da za same vrijednosti
elemenata postoji neka implicitna (prirodna) relacija totalnog uredaja. Dakle, moˇzemo govoriti o tome
koji je element ve´ci, a koji je manji.
Slijedi primjer koriˇstenja skupova. Pretraˇzivanjem baze podataka dobivamo skupove imena osoba,
A = {osobe s barem 10 godina staˇza}, B = {osobe s viˇsom struˇcnom spremom}. Tada osobe s barem
deset godina staˇza ili VSS raˇcunamo kao A ∪ B, a osobe s barem 10 godina staˇza i VSS kao A ∩ B.
Sliˇcno, B \ A ˇcine osobe s VSS koje joˇs nemaju 10 godina staˇza.
Skup ´cemo definirati kao apstraktni tip podataka, s operacijama koje su uobiˇcajene u matematici.
Apstraktni tip podataka SET
elementtype . . . bilo koji tip s totalnim uredajem <=.
SET . . . podatak tipa SET je konaˇcni skup ˇciji elementi su (medusobno razliˇciti) podaci tipa elementtype.
MAKE NULL(&A) . . . funkcija pretvara skup A u prazan skup.
INSERT(x,&A) . . . funkcija ubacuje element x u skup A, tj. mijenja A u A ∪ {x}. Znaˇci, ako x ve´c jeste
element od A, tada INSERT( ) ne mijenja A.
DELETE(x,&A) . . . funkcija izbacuje element x iz skupa A, tj. mijenja A u A \ {x}. Znaˇci, ako x nije
element od A, tada DELETE( ) ne mijenja A.
MEMBER(x,A) . . . funkcija vra´ca “istinu” ako je x ∈ A, odnosno “laˇz” ako x 6∈ A.
MIN(A), MAX(A) . . . funkcija vra´ca najmanji odnosno najve´ci element skupa A, u smislu uredaja <=.
Nije definirana ako je A prazan skup.
SUBSET(A,B) . . . funkcija vra´ca “istinu” ako je A ⊆ B, inaˇce vra´ca “laˇz”.
UNION(A,B,&C) . . . funkcija pretvara skup C u uniju skupova A i B. Dakle, C mijenja u A ∪ B.
INTERSECTION(A,B,&C) . . . funkcija pretvara skup C u presjek skupova A i B. Dakle, C mijenja u A ∩ B.
DIFFERENCE(A,B,&C) . . . funkcija pretvara skup C u razliku skupova A i B. Dakle, C mijenja u A \ B.
Ovako zadani apstraktni tip podataka SET dosta je teˇsko implementirati. Ako postignemo efikasno
obavljanje jednih operacija, sporo ´ce se obavljati neke druge operacije. U ovom potpoglavlju gledamo
implementacije napravljene sa ciljem da se spretno obavljaju operacije s viˇse skupova: UNION( ),
INTERSECTION( ), DIFFERENCE( ), SUBSET( ). Implementacije koje pogoduju ostalim operacijama
obraduju se u poglavljima 4.2. i 4.3.
31

32

4.1.1

4. SKUPOVI

Implementacija skupa pomo´
cu bit-vektora

Uzimamo bez velikog gubitka op´cenitosti da je elementtype = {0, 1, 2, . . ., N − 1}, gdje je N dovoljno
velika int konstanta. Skup prikazujemo poljem bitova (ili byte-ova tj. char-ova). Bit s indeksom i je
1 (odnosno 0) ako i samo ako i-ti element pripada (odnosno ne pripada ) skupu. Dakle:
#define N ... /* dovoljno velika konstanta */
typedef char *SET; /* poˇ
cetna adresa char polja duljine N */
Pojedinu varijablu tipa SET inicijaliziramo dinamiˇckim alociranjem memorije za polje, ili tako da je
poistovijetimo s poˇcetnom adresom ve´c deklariranog polja. Dakle:
SET A;
A = (char*) malloc(N);
ili:
. . .
char bv[N];
SET A = bv;

A b

- 0
1
2
.
.
.
.
.
.
N-1

0
1
0
.
.
.
.
.
.
1

Slika 4.1 Implementacija skupa pomo´cu bit-vektora.
Operacije iz apstraktnog tipa podataka SET se mogu isprogramirati na oˇcigledni naˇcin. INSERT( ),
DELETE( ) i MEMBER( ) zahtijevaju konstantno vrijeme, budu´ci da se svode na direktan pristup i-tom
bitu. UNION( ), INTERSECTION( ), DIFFERENCE( ), SUBSET( ) zahtijevaju vrijeme proporcionalno N.
Ispisujemo UNION( ), a ostale funkcije su sliˇcne:
void UNION (SET A, SET B, SET *C ptr) {
int i;
for (i=0; i<N; i++)
(*C ptr)[i] = (A[i]==1) || (B[i]==1);
}
Ova implementacija postaje neupotrebljiva ako je N velik.

4.1.2

Implementacija skupa pomo´
cu sortirane vezane liste

Prikazujemo skup kao listu. Od dviju razmatranih implementacija liste, bolja je ona pomo´cu pointera. Naime, veliˇcina skupova dobivenih operacijama ∪, ∩, \ moˇze jako varirati. Da bi se operacije
efikasnije obavljale, dobro je da lista bude sortirana u skladu s <=. Pretpostavimo da su definirani
tipovi celltype, LIST iz poglavlja 2.1. Dalje ispisujemo INTERSECTION( ). Pretpostavljamo sljede´cu
definiciju tipa SET.
typedef celltype *SET;
void INTERSECTION (SET ah, SET bh, SET *chp) {
/* Raˇ
cuna presjek skupova A i B, prikazanih sortiranim vezanim listama
cije headere pokazuju pointeri ah i bh. Rezultat je skup C, prikazan
ˇ
sortiranom vezanom listom ˇ
ciji pointer na header pokazuje chp */

ˇ
4.2. RJECNIK

33

celltype *ac, *bc, *cc;
/* teku´
ce ´
celije u listi za A i B, te zadnja ´
celija u listi za C */
*chp = (celltype*)malloc(sizeof(celltype));
/* stvori header liste za C */
ac = ah->next;
bc = bh->next;
cc = *chp;
while ((ac!=NULL) && (bc!=NULL)) {
/* usporedi teku´
ce elemente liste A i B */
if ( (ac->element) == (bc->element) ) {
/* dodaj element u presjek C */
cc->next = (celltype*)malloc(sizeof(celltype));
cc = cc->next;
cc->element = ac->element;
ac = ac->next;
bc = bc->next;
}
else if ((ac->element)<(bc->element))
/* elementi su razliˇ
citi, onaj iz A je manji */
ac = ac->next;
else
/* elementi su razliˇ
citi, onaj iz B je manji */
bc = bc->next;
}
cc->next = NULL;
}
Funkcije UNION( ), DIFFERENCE( ) i SUBSET( ) su vrlo sliˇcne. Vrijeme izvrˇsavanja je proporcionalno duljini jedne od listi.

4.2

Rjeˇ
cnik

ˇ
Cesto
nije potrebno obavljati sloˇzene operacije kao ˇsto su ∪, ∩, \, ⊆. Umjesto toga, pamti se jedan skup,
te se obavljaju povremena ubacivanja i izbacivanja elemenata. Takoder, povremeno treba ustanoviti
nalazi li se zadani element u skupu ili ne. Takav skup nazivamo rjeˇ
cnik (dictionary). Apstraktni
tip podataka DICTIONARY definiramo sliˇcno kao apstraktni tip podataka SET, s time da se popis
operacija reducira na MAKE NULL( ), INSERT( ), DELETE( ) i MEMBER( ). Slijede primjeri:
- Pravopis je popis ispravno napisanih rijeˇci nekog jezika. Da bismo ustanovili da li je neka rijeˇc
ispravno zapisana, gledamo postoji li ona u pravopisu. Povremeno u pravopis ubacujemo nove
izraze ili izbacujemo zastarjele.
- Neki tekst procesori imaju u sebi tzv. spelling checker, dakle popis ispravno napisanih engleskih
rijeˇci i program koji usporeduje naˇs tekst s popisom.
- Viˇsekorisniˇcko raˇcunalo prepoznaje korisnike na osnovu njihovih imena. Kod prijavljivanja, korisnik upisuje ime, a stroj provjerava postoji li ime na popisu. Ovlaˇstena osoba ubacuje imena
novih korisnika, ili briˇse imena odsutnih.

4.2.1

Implementacija rjeˇ
cnika pomo´
cu bit-vektora

Sasvim isto kao u poglavlju 4.1. Operacije INSERT( ), DELETE( ) i MEMBER( ) se obavljaju u vremenu
O(1). Implementacija postaje neupotrebljiva ako je elementtype velik.

4.2.2

Implementacija rjeˇ
cnika pomo´
cu liste

Skup shvatimo kao listu, koja moˇze biti sortirana (u skladu s <=) ili nesortirana, te prikazana pomo´cu
polja ili pointera (vidi potpoglavlje 2.1). Od ˇcetiri mogu´ce varijante detaljnije promatramo sortiranu

.... else /* A..last. ... DELETE( ) zahtijeva O(n) prepisivanja.34 4. imamo: int MEMBER (elementtype x... . } elements f . . SKUPOVI listu prikazanu kao polje... else if (A. . l . ˇsto zahtjeva u najgorem sluˇcaju O(n) prepisivanja elemenata.. /* indeks prvog i zadnjeg elementa razmatrane pod-liste */ int m..1. } return 0. Uz pretpostavku da je tip LIST definiran kao u potpoglavlju 2.. a rjede MEMBER( ). Ta varijanta je pogodna za “statiˇcne” skupove. Funkcija MEMBER( ) obavlja se u vremenu O(log2 n).... a rjede INSERT( ) ili DELETE( ). . Sliˇcno. l... tada su pogodnije ostale tri varijante implementacije pomo´cu liste... Slika 4.... SET A) { int f... dakle one za koje se ˇcesto obavlja funkcija MEMBER( ). . last . .elements[m] > x */ l = m-1. INSERT( ) mora ubaciti novi element na “pravo” mjesto.....elements[m] < x) f = m+1.. te uz typedef LIST SET..elements[m] == x) return 1. Da bi se ˇcuvala sortiranost. /* indeks srednjeg elementa razmatrane pod-liste */ f = 0... Kod sve tri varijante moˇze se izbje´ci prepisivanje ... if (A. m . . Ako se za naˇs rjeˇcnik ˇcesto obavljaju INSERT( ) i DELETE( ). l = A. gdje je n duljina liste... while (f <= l) { m = (f+l)/2.2 Implementacija rjeˇcnika pomo´cu liste.. Sluˇzimo se algoritmom binarnog traˇ zenja..

. 0 1 x .. One se razlikuju po gradi pretinca tablice.. .. ... ....... jer zauzima prevelik komad memorije od kojeg se najve´ci dio uop´ce ne koristi.. svakoj mogu´coj vrijednosti tipa elementtype pridruˇzuje se njen zasebni bit memorije. Kompromisno rjeˇsenje je umjesto bijekcije promatrati surjekciju na manji komad memorije.. Hash funkcija h( ) je potprogram koji surjektivno preslikava skup elementtype na skup cijelih brojeva izmedu 0 i B − 1. . return sum % B. Na taj naˇcin...3 Hash funkcija i hash tablica. . .... .. Npr...2.. i++) sum += x[i].. Tada se doduˇse viˇse razliˇcitih vrijednosti moˇze preslikati na istu adresu.. . Kasnije ga u istom pretincu i traˇzimo...2. . B-1 .. . tada bismo mogli definirati ovakav h( ): int h (elementtype x) { int i.. ....  P P.1.. sum=0... .. .1. a aa.... . ... i<10. ........ Indeksi pretinaca su 0... . Naime... .. tada se i-ta vezana lista produlji joˇs jednim zapisom. Implementacija rjeˇcnika pomo´cu hash tablice bazira se na tome da element x spremimo u pretinac s indeksom h(x)... ..B-1. ........ . .. Pretinac je graden kao vezana lista......... vrijeme za INSERT( )...... } Postoje razne varijante implementacije pomo´cu hash tablice. h(x) . Kad god treba novi element x ubaciti u i-ti pretinac... .. ....... kapacitet jednog pretinca je neograniˇcen i promjenjiv....3 Implementacija rjeˇ cnika pomo´ cu rasute (hash) tablice Implementaciju pomo´cu bit-vektora moˇzemo gledati kao bijekciju oblika: elementtype → memorija..... ...... Otvoreno “haˇ siranje”. ta implementacija je obiˇcno neupotrebljiva. ..B-1..2. DELETE( ) i MEMBER( ) je u najgorem sluˇcaju O(n) (zbog traˇzenja elemenata odnosno njegovog mjesta u listi).. gdje je B cjelobrojna konstanta.. .... . . .  . Hash tablica je polje od B ´celija koje zovemo pretinci. . . .   XX . .. Slika 4. for (i=0.. MEMBER( ) izvrˇsavaju u vremenu O(1). Ipak.. . . ako uzmemo da je elementtype skup svih nizova znakova duljine 10... Za funkcioniranje ove ideje vaˇzno je da h( ) jednoliko rasporeduje vrijednosti iz skupa elementtype na pretince 0.. 4. DELETE( ). ...... RJECNIK 35 elemenata prilikom ubacivanja i izbacivanja. S druge strane... 2 .ˇ 4.. .2. Takva implementacija je u jednu ruku idealna.... jer se funkcije INSERT( ).....

. oldheader = (*Ap)[bucket]..4 Organizacija podataka u otvorenom haˇsiranju... ... chh . ... current = A[h(x)]... .... (*Ap)[bucket]->next = oldheader. /* poˇ cetna adresa polja headera */ void MAKE NULL (DICTIONARY *Ap) { int i. . Potrebne definicije u C-u su: #define B . /* pogodna konstanta */ typedef struct cell tag { elementtype element.. ....... struct cell tag *next......... hhh h . celltype *oldheader.. c .. else current = current->next. (*Ap)[bucket]->element = x. } int MEMBER (elementtype x.... Slika 4..... .... /* header x-ovog pretinca */ while (current != NULL) if (current->element == x) return 1... /* x nije naden */ } void INSERT (elementtype x... .... . } celltype.. . typedef celltype **DICTIONARY. c ..... SKUPOVI A c - 0 1 B-1 c . . ... c . for (i=0. ..... ....... c . .*Ap) == 0) { bucket = h(x).... ... return 0............ ... ..... ..... DICTONARY A) { celltype *current.. if (MEMBER(x. lista elemenata u svakom pretincu c ..36 4. c . i++) (*Ap)[i] = NULL.. (*Ap)[bucket] = (celltype*)malloc(sizeof(celltype)). } } .. .. c headeri za pretince . DICTONARY *Ap) { int bucket. i<B.. ......

. } else /* x joˇ s nije naden */ current = current->next... . Najˇceˇs´ce se hh(i. current->next = current->next->next. Element poniˇstavamo tako da umjesto njega u dotiˇcni pretinac upiˇsemo DELETED. 6 7 Slika 4.x). Ako trebamo ubaciti element x. Ovaj postupak traˇzenja je ispravan samo ako nema izbacivanja elemenata.. Traˇzenje elementa x u tablici provodi se tako da gledamo pretince h(x).x) zadaje kao hh(i. (*Ap)[bucket] = (*Ap)[bucket]->next. b. Radi se o linearnom haˇsiranju..2.. hash tablica je polje ´celija tipa elementtype... sve dok ne nademo jednu praznu. tada pogledamo na alternativne lokacije: hh(1.ˇ 4. a ´celija h(x) je ve´c puna. } else { /* x. if ( (*Ap)[bucket] != NULL) { if ( (*Ap)[bucket]->element == x) { /* x je u prvoj ´ celiji */ temp = (*Ap)[bucket]. . bucket = h(x). Prazne pretince prepoznajemo po tome ˇsto sadrˇze posebnu rezerviranu vrijednost EMPTY. . c. Da bismo ipak u nekom smislu mogli izbacivati.. DICTIONARY *Ap) { celltype *current. A c - 0 b 1 2 3 a 4 c 5 d . Na slici je nacrtana situacija kada je B jednak 8. return.. free(temp). } } } Zatvoreno “haˇ siranje”. free(temp). /* current pokazuje prethodnu ´ celiju */ while (current->next != NULL) if (current->next->element == x) { temp = current->next. hh(1.x) = (h(x)+i) % B.. kao da je prazna. *temp. . 0. koja je razliˇcita od bilo kojeg elementa kojeg bi htjeli ubaciti.... . int bucket.. 4 odnosno 3.. to se onda zove “linearno” haˇsiranje...... . pri ˇcemu hash funkcija h( ) redom daje vrijednosti 3. hh(2... rjeˇcnik se gradi ubacivanjem elemenata a.x). ukoliko postoji.. ... hh(2.x). Pretinac ima fiksni kapacitet. sve dok ne nademo x ili EMPTY.. d (u tom redoslijedu).x).5 Djelomiˇcno popunjena hash tablica kod zatvorenog haˇsiranja.. . Zbog jednostavnosti uzimamo da u jedan pretinac stane jedan element... Slijede definicije u C-u. RJECNIK 37 void DELETE (elementtype x. Ta ´celija se kasnije moˇze upotrijebiti kod novog ubacivanja.. Dakle. uvodimo joˇs jednu rezerviranu vrijednost: DELETED. ... nije u prvoj ´ celiji */ current = (*Ap)[bucket]. ..

Funkcija vra´ ca indeks pretinca na kojem je stala iz bilo kojeg od ovih razloga */ int initial. } Kod obje varijante hash tablice vaˇzno je da tablica bude dobro dimenzionirana u odnosu na rjeˇcnik koji se pohranjuje. DICTONARY *Ap) { int bucket.. if ( (*Ap)[bucket] == x) (*Ap)[bucket] = DELETED.*Ap)) return. Ako se tablica previˇse napuni. sve dok ne nade x ili prazni pretinac... DICTIONARY A) { if ( A[locate(x. bucket = locate(x. ili dok se ne vrati na mjesto polaska. int MEMBER (elementtype x.. i++) (*Ap)[i] = EMPTY. i broji pretince koje smo proˇ sli */ initial = h(x). while ((i<B) && (A[(initial+i)%B]!=x) && (A[(initial+i)%B]!=EMPTY)) i++. if ( ((*Ap)[bucket]==EMPTY) || ((*Ap)[bucket]==DELETED) ) (*Ap)[bucket] = x. for (i=0. #define DELETED .9 · B. else error("table is full"). return ((initial+i)%B). if (MEMBER(x. 4. else return 0.*Ap). DICTIONARY A) { /* prolazi tablicom od pretinca h(x) nadalje. /* x je ve´ c u A */ bucket = locate1(x.A)] == x ) return 1. #define B . MEMBER( ) zahtijeva svega nekoliko ˇcitanja iz tablice. Neka je n broj elemenata u rjeˇcniku. a kod zatvorenog haˇsiranja n ≤ 0. /* initial ˇ cuva h(x). } void DELETE (elementtype x. i<B. } void INSERT (elementtype x. DICTIONARY A) { /* sliˇ cno kao locate samo takoder stane i onda kad naide na DELETED */ . typedef elementtype *DICTONARY. SKUPOVI #define EMPTY .. tada moˇzemo oˇcekivati da bilo koja od operacija INSERT( ). } int locate (elementtype x..*Ap). treba je prepisati u novu.4 Implementacija rjeˇ cnika pomo´ cu binarnog stabla traˇ zenja Binarno stablo T je binarno stablo traˇ zenja ako su ispunjeni sljede´ci uvjeti: . /* poˇ cetna adresa polja elementtype */ void MAKE NULL (DICTIONARY *Ap) { int i. i. i = 0. Preporuˇcuje se da kod otvorenog haˇsiranja bude n ≤ 2 · B. DELETE( ). Ako je to ispunjeno..2.38 4. DICTIONARY *Ap) { int bucket.. ve´cu. } int locate1 (elementtype x.

10. Prikaz nije jedinstven. RJECNIK 39 . Ideja implementacije je sljede´ca: rjeˇcnik prikazujemo binarnim stablom traˇzenja. . Na slici se vidi prikaz skupa A = {5.2. 12.     J  J  J    J 5 14 10 15  . 15. 18} pomo´cu binarnog stabla traˇzenja. Primjetimo da ´ce svi ˇcvorovi naˇseg stabla imati razliˇcite oznake. 14.ˇcvorovi od T su oznaˇceni podacima nekog tipa na kojem je definiran totalni uredaj. 7. oznake svih ˇcvorova u desnom pod-stablu od i su ve´ce ili jednake od oznake od i.ˇ 4.kaˇzemo da je element “spremljen” u tom ˇcvoru. Svakom elementu rjeˇcnika odgovara toˇcno jedan ˇcvor stabla i obratno. Obilaskom binarnog stabla algoritmom INORDER( ) dobivamo elemente skupa u sortiranom redoslijedu. Takoder. Tada su oznake svih ˇcvorova u lijevom pod-stablu od i manje od oznake od i. Element rjeˇcnika sluˇzi kao oznaka odgovaraju´ceg ˇcvora stabla .Neka je i bilo koji ˇcvor od T . makar se to ne zahtjeva u definiciji binarnog stabla traˇzenja.

.

.

 .

  .

L A .

A L .

A L    .

L A 7  .

L L .

L .

  L .

14  .

12 .

.

 .

18  A A A  A 18 5  15  .

L .

L .

L .

struct cell tag *rightchild. 10.A->rightchild)). struct cell tag *leftchild. /* pointer na korijen */ Operacija MAKE NULL( ) je trivijalna. /* ˇ cvor binarnog stabla */ } celltype. 7. Operacija MEMBER( ) lako se implementira zahvaljuju´ci svojstvima binarnog stabla traˇzenja: int MEMBER (elementtype x. else if (x == A->element) return 1.A->leftchild)). 15. 12.2). Samo binarno stablo moˇze se prikazati pomo´cu pointera (vidi potpoglavlje 3. svodi se na pridruˇzivanje vrijednosti NULL pointeru. Tada su nam potrebne sljede´ce definicije: typedef struct cell tag { elementtype element.   L 10 7  12 Slika 4. else if (x < A->element) return(MEMBER(x.6 Prikazi skupa A = {5. } . 14. typedef celltype *DICTIONARY. else /* x > A->element */ return(MEMBER(x. 18} pomo´cu binarnog stabla traˇzenja. DICTIONARY A) { if (A == NULL) return 0.

.. .x je u ˇcvoru koji ima samo jedno dijete.. .. . ... Tada nademo najmanji element y u desnom pod-stablu ˇcvora od x........ .. SKUPOVI Operacija INSERT( ) radi sliˇcno. . ..... . ... .. .. .... .... . .. ........... .. . . ..... . .. ....... .. Nadomjestimo ˇcvor od x s njegovim djetetom... ..... . .. . a umjesto njega ˇcvor od 5 postaje lijevo dijete ˇcvora od 15)... ... .. . ..... (Npr.. .. ..... .. ... . .. .. .. ... . ... ... . . ....... .... . te ubacuje novi ˇcvor na to mjesto... 15 5 18 10 7 12 Slika 4....7 Brisanje ˇcvora s oznakom 14 iz drugog stabla sa slike 4..... . ...... ....... Izbacimo ˇcvor od y (jedan od dva prethodna sluˇcaja). .. .. .6... ... .... .. ... . . ...... .. Cvor koji pohranjuje 14 se izbaci.... .. ........ /* ako je x == (*Ap)->element. za x jednak 10 u prvom binarnom stablu sa slike 4.. else if (x > (*Ap)->element) INSERT(x... izlazi da je y jednak 12. ....... ..... ............. Izbacimo ˇcvor od 12..... ..... . .. .... .... void INSERT (elementtype x.... ..... . . . . . . ..&A). za ˇ x jednak 14 u drugom binarnom stablu sa slike 4. .... ..6.. (*Ap)->leftchild = (*Ap)->rightchild = NULL.... . za x jednak 15 u prvom binarnom stablu sa slike 4. . .. .. .. .... ne radi niˇ sta jer je x ve´ c u rjeˇ cniku */ } Neˇsto je sloˇzenija operacija DELETE(x...&((*Ap)->rightchild))....... ... . . .. . . ..... ....... ....... ....... (*Ap)->element = x..x je u ˇcvoru koji ima oba djeteta.. U ˇcvor od x spremimo y umjesto x.. . .. ...... .. .... Imamo tri sluˇcaja: .. . U ˇcvor koji sadrˇzi 10 upiˇsemo 12 i time izbriˇsemo 10). } else if (x < (*Ap)->element) INSERT(x. ... . ...6....40 4... .. . . .... .... . ... ..... ...... ...6).. . .. .. ...... ..... .......&((*Ap)->leftchild)).. .. .. .. ... . ... . .. DICTIONARY *Ap) { if (*Ap == NULL) { *Ap = (celltype*) malloc (sizeof(celltype)).. (npr... .. . ... . .... .. Ona poput MEMBER( ) traˇzi mjesto u binarnom stablu gdje bi morao biti novi element.. ... tada jednostavno izbacimo list iz stabla. (npr.... ... . .x je u listu. . .... . . .

&((*Ap)->rightchild) ). . . .... .... . } else /* postoje oba djeteta */ (*Ap)->element = DELETE MIN ( &((*Ap)->rightchild) ).... } else if ( (*Ap)->rightchild == NULL ) { /* nadomjestimo ˇ cvor od x s njegovim lijevim djetetom */ temp = *Ap........... . . ......... ... .. ... . ... . .... . .. ..... &((*Ap)->leftchild) )........ . ... . tada je x u ˇ cvoru kojeg pokazuje *Ap */ else if ( ((*Ap)->leftchild==NULL) && ((*Ap)->rightchild==NULL) ) { /* izbaci list koji ˇ cuva x */ free(*Ap)..... .. . . . ...8 Brisanje ˇcvora s oznakom 10 iz prvog stabla sa slike 4..... .. . .... .. . . .. ... .. ...... . . ... . .. ..... ...6.. . .... free(temp)...... .. .2. . . . ... ... .. ...... . elementtype DELETE MIN (DICTIONARY *Ap) { celltype *temp.... . . .... ..... . . . .. . ... . temp = (*Ap)..... ...... *Ap = (*Ap)->rightchild...... . if ( (*Ap)->leftchild)==NULL ) { /* (*Ap) pokazuje najmanji element */ minel = (*Ap)->element... te vra´ca taj najmanji element.. elementtype minel. . ... .... . .... ....... free(temp). . .... . . ... ... . ........ RJECNIK 41 . . ... ... ....... . ..... . . . } else if ( (*Ap)->leftchild == NULL ) { /* nadomjestimo ˇ cvor od x s njegovim desnim djetetom */ temp = *Ap. .. } else /* ˇ cvor kojeg pokazuje (*Ap) ima lijevo dijete */ minel = DELETE MIN( &((*Ap)->leftchild) ).... . ...... free(temp)... . . . /* ako dodemo ovamo. . DICTIONARY *Ap) { celltype *temp. ... .. ... .. .. ........ Ta funkcija iz nepraznog binarnog stabla A izbacuje ˇcvor s najmanjim elementom.. ....... . . .. ..... . ... Sve se ovo spretno moˇze zapisati ako uvedemo pomo´cnu funkciju DELETE MIN(&A). .. ... } void DELETE (elementtype x. . ... . ... ............. ...ˇ 4. return minel. .. if ( *Ap != NULL ) if ( x < (*Ap)->element ) DELETE( x. .. ... ... . . ... . ... ... ..... ... } . .. .. else if ( x > (*Ap)->element ) DELETE( x... . .... *Ap = (*Ap)->leftchild... .. . . 12 5 14 7 8 15 Slika 4.. .. ...... ... .. ..... .... *Ap = NULL... .. ...... (*Ap) = (*Ap)->rightchild. ..... . ..... . .. . .............. .. . .. ....

. . ..... ... ......... Operacije su: ubacivanje novog elementa. . . .... .. . . Slika 4...... .... . . ....... ... .. ....... Takav skup nazivamo prioritetni red.. . .... . . ... .... .. .... .. ...... ..... ..... .. ... .. .. ...... ...... .... . Tada oˇcekivano vrijeme izvrˇsavanja za operaciju INSERT( ).... .. ..... . .. ... . . ... . ....lanac.... ... ....... . .. .... .... ..... ............... . ...... .......42 4. .. . . .. .. .. .... . .. . . ... . ... . .... ... ... . svojstvo da je njegova visina O(log n). . ... . . . . .... .. ...... Visina stabla tada varira izmedu dlog2(n + 1)e − 1 i n − 1. . .......... ........ ................ .... .... . . . . .... .... . . .... .. .... . ......... .... .. ... . .................. ... . . . .......... Naime....... ... . ... . .. ... .. .......... .. Poznate su joˇs i implementacije pomo´cu AVL-stabla.. ... Pritom je bilo koji redoslijed ubacivanja elemenata jednako vjerojatan. .. ... ... . . . . vrijeme izvrˇsavanja operacije varira izmedu O(log n) i O(n). .. ....... ... .. .... .. ..... ... ... .. ..Pacijenti ulaze u ˇcekaonicu... .. ve´c onaj ˇcije je stanje najteˇze. ...... . ... . .... .... .. .. . ............ .. . .... B-stabla. .. . ..... .. .. ..... . ...... ....... . .... Neka rijeˇcnik ima n elemenata. DELETE( ) ili MEMBER( ) iznosi O(log n).... .. .... ...... ...... . ... ...9 Ekstremni sluˇcajevi visine binarnog stabla: potpuno i ispruˇzeno binarno stablo. . .. . .. . .. Ekstremni sluˇcajevi su potpuno binarno stablo i “ispruˇzeno” stablo ... .. .. . .... Kod spomenute tri implementacije automatski se ˇcuva “balansiranost” stabla. . .. ....... . .... . Dakle.. .... . ... .. ... .. SKUPOVI Svaka od funkcija MEMBER( )... ... .. . . . . . .... 2-3-stabla.... . ... .. ... ... Doduˇse. .. .... . ... . . ....... .... . .. ... te iz nje odlaze lijeˇcniku na pregled. . .... ....... ..... . ......... Prvi na redu za lijeˇcnika nije onaj koji je prvi uˇsao. .. . .. .......... . .. ......... .prioriteti.......... od korijena binarnog stabla do nekog ˇcvora. ........ ...... . .... . . Znaˇci... . . . . . INSERT( ) i DELETE( ) su znatno kompliciranije nego kod nas. . ... . . imamo jake razloge da oˇcekujemo vrijeme izvrˇsavanja oblika O(log n).... ...... . DELETE( ) prolazi jednim putom.. .. . . ... .... ... ... .... .... . .. .. Zato je vrijeme izvrˇsavanja svih operacija ograniˇceno visinom stabla. .... . . . .......... ...... ... .. ...... . ...... . ... .. te operacije preuzimaju zadatak “pregradnje” stabla kad god se ono suviˇse “iskrivi”. .... .... ... .. ..... . .... .. .. . ... ... .. . . .. . .... ..... .... . . .. .... . .... . .. .... ..... gdje se rjeˇcnik prikazuje pomo´cu neke “stablaste” strukture. te “izbacivanje” elementa s najmanjim prioritetom..... . tj. ..... . Pitamo se koja ocjena je vjerodostojnija? Moˇze se dokazati da vrijedi sljede´ci teorem: Neka je binarno stablo traˇzenja od n ˇcvorova stvoreno od praznog stabla n-strukom primjenom operacije INSERT( ). .... . ... . ....... . .... . . . .... . . ....... .. . ...... .. ....... .... ....patoloˇski sluˇcajevi su i dalje mogu´ci. Opisana implementacija je samo jedna iz porodice sliˇcnih. .... .. .. ..... .. ...... ... .. . ... .. . ....... . INSERT( )..... .. .. ... .. ... .. .. .. . ....... .. .. ................ . .... . .. ... . . .. . .. .. . . Time se garantira efikasno obavljanje osnovnih operacija... ... . .. .. .. .. ... .. .. .. . . . .............. ... . . .. . . ........ .... .. .... .. . . ......... . .. . .. .. .... . .... . .. .. .... . .. .. .. . . . .. .. . ... ..... ...... ... .. . .... nemamo ˇcvrste garancije za to .. . .. ... .. .. . ... . .. .. ... .... Slijede primjeri...... 4.. .... ...... .. ... ..... .3 Prioritetni red U nekim algoritmima pojavljuje se skup ˇcijim elementima su pridruˇzeni cijeli ili realni brojevi ...... .. ........ .. .. ... ...

p. funkcija pretvara skup A u prazni skup. Svakom programu je pridruˇzen prioritet. 5.t. podatak ovog tipa je konaˇcni skup ˇciji elementi su (medusobno razliˇciti) podaci tipa elementtype. Spomenute probleme svodimo na jednostavniji problem ubacivanja elemenata u skup. 13. umjesto originalnih elemenata x.10 vidi se prikaz prioritetnog reda: A = {3. Ova dosjetka opravdava sljede´cu definiciju apstraktnog tipa podataka. 6. x1) je manji-ilijednak od (prioritet(x2 ). te izbacivanja najmanjeg elementa. 11. SET. . x2) ako je ( prioritet(x1 ) manji od prioritet(x2 ) ) ili ( prioritet(x1 ) jednak prioritet(x2 ) i x1 manji-ili-jednak od x2 ). Od raznih varijanti najbolja se ˇcini sortirana vezana lista. 9. Naime funkcija DELETE MIN( ) zapravo je kombinacija od MIN( ) i DELETE( ). funkcija ubacuje element x u skup A. Na Slici 4. Svakom elementu reda odgovara toˇcno jedan ˇcvor hrpe i obratno. 14. promatramo uredene parove (prioritet(x). Zato INSERT( ) ima vrijeme O(n). . . PRIORITY QUEUE moˇze smatrati restrikcijom a.3. DELETE MIN(&A) . mijenja A u A ∪ {x}. gdje je n broj elemenata u redu. . Element reda sluˇzi kao oznaka odgovaraju´ceg ˇcvora hrpe . ako su ispunjeni sljede´ci uvjeti: . 8.3. bilo koji tip s totalnim uredajem <=. 4. Mogu se upotrijebiti isti potprogrami INSERT( ).3.3. Nije definirana ako je A prazan skup. te ga izvodi.U raˇcunalu se formira prioritetni red programa (procesa) koji ˇcekaju na izvodenje. . . PRIORITETNI RED 43 .ˇcvorovi od T su oznaˇceni podacima nekog tipa na kojem je definiran totalni uredaj. PRIORITY QUEUE . Primjetimo da se a. . .p. Primjetimo da ´ce svi ˇcvorovi naˇse hrpe imati razliˇcite oznake. funkcija iz skupa A izbacuje najmanji element. . Apstraktni tip podataka PRIORITY QUEUE elementtype . MAKE NULL( ). 17} pomo´cu hrpe. EMPTY(A) . . Tada je oznaka od i manja ili jednaka od oznake bilo kojeg djeteta od i.kaˇzemo da je element “spremljen” u tom ˇcvoru. Naime. x). 4. Funkcija EMPTY( ) je trivijalna.&A) . pa ima vrijeme O(1). DELETE MIN( ). 12. Ideja implementacije je sljede´ca: prioritetni red prikazujemo hrpom. ˇsto znaˇci da mora proˇcitati u prosjeku pola liste. funkcija vra´ca “istinu” ako je A prazan skup. . makar se to ne zahtijeva u definiciji hrpe. 4.1 Implementacija prioritetnog reda pomo´ cu sortirane vezane liste Prikazujemo red kao listu. .2).t. inaˇce vra´ca “laˇz”. 10. MAKE NULL(&A) . te vra´ca taj izbaˇceni element. Iz svojstava hrpe slijedi da je najmanji element u korijenu. 15. Za uredene parove definiramo leksikografski uredaj: (prioritet(x1 ).2 Implementacija prioritetnog reda pomo´ cu binarnog stabla traˇ zenja Sasvim isto kao za rjeˇcnik (vidi potpoglavlje 4. Prikaz nije jedinstven. tj.3 Implementacija prioritetnog reda pomo´ cu hrpe Potpuno binarno stablo T je hrpa (heap). . .Neka je i bilo koji ˇcvor od T . INSERT(x. INSERT( ) mora ubaciti novi element na “pravo mjesto”.4. Procesor uzima iz reda program s najmanjim prioritetom. DELETE MIN( ) pronalazi i izbacuje prvi element u listi.

... . ... .... .... .... ........ . .. .. ....... ..... .. . ... .. . .. ..... ............ ... ..... .. .... . . . . ... .. Time se sigurno pokvarilo svojstvo hrpe.... . .... .... . . ..... . . .. .. ... ... .. . .. .. . . ...... ........ . .. . ... . . ...... .. .. .. ... ... izbacujemo zadnji ˇcvor na zadnjem nivou... ...... . . .. .. .. . .... . . . . ... .. .... ..... .. . . . . ... . . .. .. .... ... . .. . . .. ... ...... . . ........ . . ... .. ......... .. .... .. . .. .. . . ...... . .. . .. . ......... . .... . . ... ..... .. ... .. . vra´camo element iz korijena. ..... . .... .... ..... .... . ... . . . .... ... . . . ... . ..... ....... .. . .. .. . .. .... ... .... ............. .. . . .. ... . .... ... .....11. ...... ...... . .. . . . ........ . .. .. ...... ... . ... .... . ........ . .. .. . ... .. . ...... . .... ........ ... .... ... ... . . ...... ... .. . . Budu´ci da korijen ne moˇzemo samo tako izbaciti (stablo bi se raspalo). . . .. .. ..... ... .... ............ .... ......... .... . . . .. ... . .... ....... . .. . . . . . .. .......... ..... . . ..... .. .. .. .. . . .. ....... ... . . . .. .. . ....... ...... .... . . . . . . ... . . . ... ....... .. . .. . ... ... . .. .. ..... . ... ... ......... . .. . ..... ....... ... ... ....... .... .... .... . .... .. . . .. .. ... . .......... .... . Uˇcinak DELETE MIN( ) na hrpu sa slike 4...... . . . . .... .. .. .... . ... . .. ...... ....... .. ..... . . .. ..... .. ............. . . .. .. .. ... . .. . .. . .. .... .. .... .... . ... .. . . . .. Popravak se obavlja ovako: zamijenimo element u korijenu i manji element u korijenovom djetetu. .... . ... .. . .. .. . . .. ... ... .. ..... .. .. . ..... ... ..... .. ......... . . .. ..... ..10 Prikaz prioritetnog reda pomo´cu hrpe. ... .... ... . ........ . ... ......... ...... ... ...... .. .... . ....... .. . ... .... .. . . .. . . ... . .... . ... .. . .. . .. .. .. .. . ..... ..... ... . .. .. . ........... . . ........ . . . .......... ... . . . .. . ....... a njegov element stavimo u korijen...... ..... .. .. .. ........... .... .. .. . . . ... .... ... . .............. .. ... . . .. ......... . ... ...... . . ... .... . . . .... .. . . .... .... . .... . ... .......... ....... ... .... ....... . ....... ..... .. Niz zamjena ide najdalje do nekog lista....... . .... . ... .......... . ...... ... .. .... . . . . . .. ... .. . ..... ..... ................ . ... . ... .. ... ......... . ... . . 15 . . . .... .. . .... . . .... .. ....... .. .. .. .. ... .. . . .. . ..... .... .. .. .......... .. . . .... . . .. . ...... .. . ... . . ... . . . . .. ...... .. ....... . .. . .... . ... ... ... . .. .... .. .. .... . .... .... .. . ... . .. . ..... . ... Da bismo obavili operaciju DELETE MIN( )... . . .. .. . .. .... ... .. ....... .. ..... .. . .... . ......... .. .. ......... .............. ..... . . . . ..... itd........ . .......... ... . ..... .. SKUPOVI .. .... ...... 14 5 6 17 9 8 13 10 12 15 11 .. ... ....... .. ... . . . . . . .. . .. .. .... . . . .... . . ... .. .. ........ . . . . . . ..... . .. . . .... .... .. .. . .. .. .. . .... . . ..... ..... .. . . . .. . ..... .. . . .... ... . .... .. . .... .. . . .... . . . .... . .... .... . ... ... . ... 3 9 5 6 8 17 13 10 12 11 15 14 Slika 4... . .. . ........ .... .. ..... ... . .... . . . .. . . ..... ............ . .. .. .... . . ... . . . .. .. . .... 5 6 13 17 9 8 14 10 12 11 Slika 4. .... . . ........ .... . .. .. .... ..... . . .... .. ... .. . ..... . . .. . ... . ........... ...... ... . ...... .. .. .. ..... . .. . ... .. ... . . . ....... .. . . . . . .. . .... ... . ...... .. . . .. .. .. ......... ... ....... ... ... . .. ...... . . .. . ..... ... .... . .. .... . .. .. .. . .. ... .. ... .. .. .. .. ... .. .. . . ....... . .. . ... . .... .. . . ... .. ... ... .... .. zatim zamijenimo element u djetetu i manji element u djetetovom djetetu...... .... ... . . ... ... ... . . .. . . . . . .. .... .. . .. . ....... . ...... ....... ... .. ... .. ....... ..... ... . . ....... .. .... .. . .. ...... ..... ..... ......... . ... . . .. ... .. .. ...... . .... . . . . .... .... .. ... .. .... . ...... .. .... ..... ........ . . . .. ....... ... ... .... .. . . ... . ..... . . . ....... . . ... . . .. ..... . ..... . ..11 Prikaz operacije DELETE MIN( ). .. ...... .. .. . ....10 vidi se na slici 4.... ..44 4.... . ... .... . dok je potrebno.. .. .. ... ... ...... .... .. . .. .. .. ... ..... .. .. . .. .. ... ..... . .. ......... .. . .. .... ....... ..... ..... ...... . ... ....... . ....... ....... .. ... . . ........... .. ....... . ..... . . . .. .... . ...... .. ....... . . ...... .... .. ... . . .. .. . .

..... ... .. S obzirom da je hrpa potpuno binarno stablo. . . ... potrebne su nam sljede´ce definicije: # define MAXSIZE .. .. .. ....... ... ........ . . ... .. .. . ... . . . . . .4. . . ... . ... . ... ..... .. .. .. .......... .. ..... .. . . ..... ............ . .. . .. .10 vidi se na slici 4. . ... .. ............. .... . . .. .. .... . .. .......... . . .... .... ... ... . . . ..... ..... . ... ... ... ........ . . ....... . . . ........ ..... .. . . .. ..... . ... .. ......... ... . ......... .. . . . .. . .. ... .. . . .... .. . ... . .... .... ... . . .3. ... } PRIORITY QUEUE. . . . . ... ... . ...... ..... ... .. . ... ....... ... . . . .... .. . ..... ... .. .. .... . .. .... . . ..... ... ...... ...... .. . .. . ... .... Uˇcinak ubacivanja elementa 4 u hrpu sa slike 4....... potrebno je odabrati strukturu podataka za prikaz hrpe.. ....... ..... ...... .... . .... .. . .. . ....... .. .. ... . .. ...... .......... ...... ... . . ....... .... .. ..... .. .... . ..... .. .... Funkcije INSERT( ) i DELETE MIN( ) tada izgledaju ovako: ..... ....... .... .. .... ......... . . . . .. . ... .. ... . ... .... . ......... ..... . . .. . . .. .. ......... . ............ ........ .. . .. . .... . . . .. . .. .... ..... .... PRIORITETNI RED 45 Da bismo obavili operaciju INSERT( ).. .. . . .. . .... ... .. . . . . . ..... .. .... ... . ............. ..... . .. .. . . ... .. ...... . .. . .12 Prikaz operacije INSERT( )..... .. ... ...... .. .. ...... .. ...... .. ... . .. .... .. . ....... .... . .... ... ....... . ....... .... ... ... . .. . ........ . . .... ... ...... .... . ...... .. ............... ..... ... ... . ..... . ..... ..... . ... ... ... . ........ .. . . .... .. ........ .. . . ... . .. . . . .... .... . . . .. . .. .. .. . .. . . .. . . int last.... . ... ....... .. .. .. .... . ..... ... te stavljamo novi element u taj novi ˇcvor. ... .. .. ... . ... ... ... stvaramo novi ˇcvor na prvom slobodnom mjestu zadnjeg nivoa... ..... .... .... . . .. .. ... .. .... .. ... .. . .. . . . .. .. .... ..... .... . ... .. .... . . ..... ... ...12. ...... . .. .. ..... zatim zamijenimo element u roditelju i element u roditeljevom roditelju..... .... ... . . ........ moˇzemo koristiti prikaz pomo´cu polja (vidi potpoglavlje 3..... ........ ......... . ... . ... . ..... . . ... ... ... ...... . ..... . ... .... ... . .. . ... .. . ........ ..... .. . .. .. .. . . . . . . ... .. .... . .... . .. ... . . . .....2). . . . ...... .. . ..... . ....... Da bismo implementaciju razradili do kraja. .. . ...... ..... ... .. . ..... . .. ..... ........ . .... .. .. . .... ... .. ...... . .. .. . . ... .. . . .. .. ... ..... . Niz zamjena ide najdalje do korijena.. . . ... . Time se moˇzda pokvarilo svojstvo hrpe..... ... . . . .. .... . .... ... .... .. . . .. .. . .. . .. ...... . .......... . .. . .. .. . ..... . . Popravak se obavlja ovako: zamijenimo element u novom ˇcvoru i element u roditelju novog ˇcvora... . ... . ...... ... . ...... .... . . ...... /* dovoljno velika konstanta */ typedef struct { elementtype elements[MAXSIZE].. .. . .... ..... . . ............. 3 5 6 17 4 8 13 10 9 11 14 15 12 Slika 4... ..... . . ....... .... . ..... ...... ....... ... .... .... .. . . .... ... .. . . . ... .. ........ ...... ... Dakle. . .. . . ... .... ....... ..... .. .. . ... . .. ...... . . .. . ... ....... ... . .... .......... .......... . ... .. .. . . ............ ... . . . ....... .. ....... . . .. .. itd.. ...... .. . .. .. .... .... .. .. . . .... .. . .. . . .. .. ..... . . ..... . . . ... .. .. ... ... .... ... . ... . . .. . . ... . .. ... ... . .. .... ...... ... .... ... ... ...... . . .... ... . .... ... .. . .. . .. ... . .. .... . . ... .... dok je potrebno. . ..... .. . ... ... . . ... .. .. . .. ... .......... ...... . .... . .. . . ...... 3 5 6 17 9 8 13 10 12 11 14 15 4 . .. .. ... ....... .. .. ........... ...... . .. . .. . ... ... .. . .. . . .. . . .. ....... . ...... . .... .... . .... .. . .. ... ....... ....... ...... . . .. . ........... . ... . ... ..... ... . .... . . ...... ..... ...... . ....... . ........ ........ . . . .. ......... . .. .. . . . .. ... . .. .. . ... ..... . .. .. .. .. . . ...... .. . .. . .. ... . .... .

. .. . else { (Ap->last)++. } } } . ...... /* ne treba dalje pomicati */ } return(minel).. Ap->elements[Ap->last] = x.. elementtype DELETE MIN (PRIORITY QUEUE *Ap) { int i. ... temp.. . .... SKUPOVI void INSERT (elementtype x..... .....13 Dijagram za INSERT( )... ......... Ap->elements[(i-1)/2] = temp.... Ap->elements[i] = Ap->elements[(i-1)/2]. . /* j je dijete od i koje sadrˇ zi manji element */ if ( Ap->elements[i] > Ap->elements[j] ) { /* zamijeni elemente iz ˇ cvorova i. /* novi ˇ cvor s elementom x */ i = Ap->last... .. . .. . Ap->elements[i] = Ap->elements[j].......... . . . ...... ..... ..... .... ......... . .. /* izbacujemo zadnji ˇ cvor */ i = 0....... ... . ...... . .. . if ( Ap->last < 0 ) error ("priority queue is empty").... .... ... . .. . /* i je indeks ˇ cvora u kojemu se nalazi element iz izbaˇ cenog ˇ cvora */ while ( i <= (Ap->last+1)/2-1 ) { /* miˇ cemo element u ˇ cvoru i prema dolje */ if ( (2*i+1 == Ap->last) || (Ap->elements[2*i+1] < Ap->elements[2*i+2]) ) j = 2*i+1. ...... . /* i je indeks ˇ cvora u kojem je x */ while ( (i>0) && (Ap->elements[i] < Ap->elements[(i-1)/2]) ) { /* operator && u jeziku C je kondicionalan! */ temp = Ap->elements[i]... ... .. . . . ..... else { minel = Ap->elements[0].... . ..46 4.. . j. PRIORITY QUEUE *Ap) { int i.....j */ temp = Ap->elements[i]. else j = 2*i+2.. elementtype minel.. .... if ( Ap->last >= MAXSIZE-1 ) error("priority queue is full"). .... /* najmanji element je u korijenu */ Ap->elements[0] = Ap->elements[Ap->last]. . Ap->elements[j] = temp...... . /* pomicanje je doˇ slo sve do lista */ } } ... . . ..... . ..... .... ... ..... y (i-1)/2 i x Slika 4.... . ........... . . .... . . ... . elementtype temp. .... . .... } else return(minel)... . .... i = (i-1)/2.. ... i = j. . .. . . ...... /* zadnji ˇ cvor ide u korijen */ (Ap->last)--....

... ... n}.. ... ..... ... . . takvo koje nije nigdje definirano... .. . r).. Naˇsa definicija ´ce biti malo op´cenitija nego ˇsto je uobiˇcajeno u matematici. ... ..... .... u M postoji najviˇse jedan par (d.. MAX( ). funkcija pretvara preslikavanje M u nul-preslikavanje. . Zato ova manjkavost naˇse funkcije obiˇcno ne smeta. Sliˇcni primjeri: matrica. .... . .. 4... Potprogrami INSERT( ) i DELETE MIN( ) obilaze jedan put u potpunom binarnom stablu. . a brojevi se mogu mijenjati........ ... DELETE( ). .. . .. .. ... ... .. . bilo koji tip (kodomena).... . range . .. .. .. gdje su svi d-ovi podaci jednog tipa. ... . . ..... . ........ . . .. r). . .. .4 Preslikavanje i relacija ˇ Cesto je potrebno pamtiti pridruˇzivanja medu podacima. Prednost binarnog stabla traˇzenja pred hrpom je: mogu´cnost efikasnog implementiranja dodatnih operacija: MEMBER( ). . . ...Matematiˇcki pojam “vektor duljine n” moˇze se interpretirati kao preslikavanje ˇcija domena je skup {1... .. datuma rodenja... .. . . . .. gdje je n broj ˇcvorova stabla (odnosno broj elemenata u redu). .) skup realnih brojeva.. . a kodomenu telefonski brojevi.. .... .. . .. . . . . Prvi tip nazivamo domena ili podruˇcje definicije (domain)...... . . r). . r). Rijeˇc je o preslikavanju ˇciju domenu ˇcine matiˇcni brojevi.. ... Zakljuˇcujemo da je implementacija prioritetnog reda pomo´cu hrpe bolja od implementacije prioritetnog reda pomo´cu binarnog stabla traˇzenja. . . .. .. .. Imena se mogu ubacivati i izbacivati. . .. ... Ako za zadani d preslikavanje M sadrˇzi par (d. ..... Primjetimo da funkcija INSERT( ) ima jednu manjkavost: ona stvara novi ˇcvor s elementom x ˇcak i onda kad x ve´c jeste u prioritetnom redu A... . U primjenama obiˇcno ubacujemo samo one elemente za koje smo sigurni da se ne nalaze u prioritetnom redu. . .... indeks pojmova. Funkcije MAKE NULL( ) i EMPTY( ) su trivijalne........ tada taj jedinstveni r oznaˇcavamo s r = M (d) i kaˇzemo da je M (d) definirano.... ... a svi r-ovi podaci drugog tipa... . . . ... .... .. .4. ......Svaki suradnik neke tvrtke opisan je zapisom u kojem se nalaze podaci poput imena i prezimena. Apstraktni tip podataka MAPPING domain ........ . .. ..... . tj.... ...4.... ...14 Dijagram za DELETE MIN( )... . a drugi tip zovemo kodomena ili podruˇcje vrijednosti (range). .... pa ih ne´cemo pisati... .... Zapisi (suradnici) se razlikuju na osnovu matiˇcnog broja suradnika. ... Ako za zadani d preslikavanje M ne sadrˇzi par (d. MAKE NULL(&M) .. 2.. Sliˇcni primjeri: rjeˇcnik stranih rijeˇci... koja se mogu opisati matematiˇckim pojmom “funkcije” (“preslikavanja”). Ovo je bolja ocjena nego za implementaciju pomo´cu binarnog stabla traˇzenja (gdje smo imali logaritamsko vrijeme samo u prosjeˇcnom sluˇcaju)..... kaˇzemo da M (d) nije definirano..... Preslikavanje M je skup uredenih parova oblika (d.. .. .. a kodomenu podaci tipa range. .. a kodomenu ostali podaci o suradniku. zanimanja i sl...Telefonski imenik je preslikavanje ˇciju domenu ˇcine imena ljudi. . . .. .. .. .. Zato je njihovo vrijeme izvrˇsavanja u najgorem sluˇcaju O(log n).... ........ .. ... ..... Slijede primjeri.... MAPPING . .. a zatim definicija apstraktnog tipa koji odgovara preslikavanju. MIN( ).. podatak tipa MAPPING je preslikavanje ˇciju domenu ˇcine podaci tipa domain. bilo koji tip (domena)... .. .. . .. . sadrˇzaj knjige.. polje.. a kodomena (npr... x y 2*i+1 i 2*i+2 Slika 4. ... ..... .. ...... . Pritom...... . .. PRESLIKAVANJE I RELACIJA 47 .. . za zadani d. . .

31 4. . M (d)). .. 1.. SKUPOVI ASSIGN(&M. funkcija definira M(d) tako da bude M(d) jednako r.. .28 15 9. To omogu´cuje da kasnije pronademo par (d. Uredeni par (d. inaˇce funkcija vra´ca “laˇz”...12). 6 7 Slika 4.. tj.48 4. h(x) = x % 8. . DICTIONARY. 0 8 1. Ove ideje ´cemo ilustrirati sljede´cim primjerima. M (d)) na osnovu zadanog d. .. hash tablica. Taj skup shva´camo kao rjeˇcnik i prikazujemo ga na naˇcine opisane u poglavlju 4.1 Implementacija preslikavanja pomo´ cu hash tablice ili binarnog stabla Promatramo preslikavanje M ˇcija domena je tip int. 6.12 8.4. Za cijele brojeve d koji se ne pojavljuju u tablici M (d) nije definirano. binarno stablo traˇzenja. (25. . uzimamo B = 8. U svaki pretinac stane jedan uredeni par oblika (d.. Hash funkcija h( ) preslikava podruˇcje definicije od M na skup {0.d.&r) . .. d 3 8 12 15 19 25 M (d) 2. . U skladu s definicijom. preslikavanje M pohranjujemo kao skup uredenih parova oblika (d. tada funkcija vra´ca “istinu” i pridruˇzuje varijabli r vrijednost M(d).18). te se traˇzi u istom pretincu. Pritom se mjesto uredenog para (d. M (d)) u strukturi odreduje samo na osnovu d. Za implementaciju preslikavanja koriste se iste strukture podataka kao za rjeˇcnik. MAPPING implementiraju se analogno kao MAKE NULL( ). .. COMPUTE( ) iz a. .12 1 25 6. 4..26 5 19 4. . Konkretno. ako je M(d) definirano. . funkcija uzrokuje da M(d) postane nedefinirano. Npr. 2.d) .. lista. DEASSIGN( ).. . . DEASSIGN(&M. M tada shva´camo kao skup M = {(3.r) .64 3 3 2..64)}. MEMBER( ) iz a. . bez obzira da li je M(d) bilo prije definirano ili nije. . dakle: polje.. 2.16 Preslikavanje M prikazano pomo´cu zatvorene hash tablice.t. B − 1}.. COMPUTE(M.18 1.26 9... ...18 4 12 8.. DELETE( ). bez obzira da li je M(d) prije bilo definirano ili nije. INSERT( ). M (d)). Operacije MAKE NULL( )... M (d)) sprema se u pretinac h(d). gdje d prolazi svim podacima za koje je M (d) definirano. onako kao kad bi se pohranjivao sam d. U sluˇcaju kolizije primjenjujemo linearno haˇsiranje.15 Primjer za preslikavanje M .64 Slika 4.d..... moˇzemo koristiti prikaz pomo´cu zatvorene hash tablice s B pretinaca.2. 1..28 6.31 2 .p.t. .p. ASSIGN( ). M je zadano sljede´com tablicom. a kodomena tip float. (8. .

M (d1)) manje-ili-jednako (d2. ..... ... . podatak tipa RELATION je binarna relacija ˇciju prvu domenu ˇcine podaci tipa domain1. .. .... .Studenti upisuju izborne kolegije. bilo koji tip (prva domena)... UNRELATE(&R. . .....17 Preslikavanje M prikazano pomo´cu binarnog stabla traˇzenja. . . (3. . .. .. .. . .. ... . .. .. . funkcija postavlja da je d1 R d2.. ... .. ..... . .... 1.. .. . .. . ... . .. Evo nekoliko primjera. ...... a drugu domenu podaci tipa domain2. ...... .. .. .... te koji sve studenti su upisali zadani kolegij.... . bilo koji tip (druga domena).. ... . . leˇzajeva. .. set2 .. ... tada kaˇzemo da je d1 u relaciji R s d2 i piˇsemo d1 R d2. .. ). . . .. . set1 . .. .. .... .. ... Tada govorimo o relaciji.12) (15. M moˇzemo prikazati pomo´cu binarnog stabla traˇzenja...... Apstraktni tip podataka RELATION domain1 ... Time se uspostavlja relacija ˇcije domene su skup studenata i skup kolegija. ..... .. U protivnom kaˇzemo da d1 nije u relaciji R s d2 i piˇsemo d1 R 6 d2. .. .. .. .. ...d2) ..d2) .. Ova dva tipa nazivamo prva odnosno druga domena (domains).. .. ... .d1.. podatak tipa set2 je konaˇcni skup podataka tipa domain2. . . ..... ..... . Ako relacija R za zadani d1 i d2 sadrˇzi uredeni par (d1 . . .. .. . takvu u kojoj ni jedan podatak nije ni s jednim u relaciji....... Binarna relacija R je skup uredenih parova oblika (d1 .. . .. ..... ... 6. .. .. .. . ... . .. . .. RELATE(&R. . .. .. d2).64) (8. domain2 .. .. . M (d)) smjeˇstaju se u ˇcvorove stabla. . .. te u kojim sve proizvodima se pojavljuje zadani dio..... . . . .. ... ... . .. .... . 4. .. ... d2).. . .. .. vrijedi uredaj za oznake ˇcvorova: (d1..Proizvodi se sastavljaju od dijelova (vijaka. 9. .. 2.. ........ . cocktaili sastavljeni od pi´ca.. . .26) . .....4. . .... .. no grananje u stablu se provodi samo na osnovu d.. . . ...d1. bez obzira da li je to ve´c bilo postavljeno ili nije.. . Moˇzemo se pitati koje sve kolegije je upisao zadani student. . ... .. .. a kao d2 podaci drugog tipa...... .... . . .. gdje se kao d1 pojavljuju podaci jednog tipa. filmovi i kina. bez obzira da li je to ve´c bilo postavljeno ili nije. ... ..... .. . . . . . Pitamo se koji su sve dijelovi potrebni za zadani proizvod.... .. . funkcija pretvara relaciju R u nul-relaciju.. . MAKE NULL(&R) .. .......... .... .. RELATION .. .. . . odrediˇsta i avionske kompanije... .. .. . . .... podatak tipa set1 je konaˇcan skup podataka tipa domain1.. ..... ..... .. Sliˇcni primjeri: ljudi i ˇcasopisi...... (12. . Sliˇcni primjeri: programi sastavljeni od potprograma.. te odgovaraju´ca definicija apstraktnog tipa.18) (19.. ... .... ....31) Slika 4.... .. . . .. ˇ Cesto je potrebno pamtiti pridruˇzivanja medu podacima koja su op´cenitija od onih obuhva´cenih pojmom “preslikavanje”... Dakle.. PRESLIKAVANJE I RELACIJA 49 ˇ Dalje. .. . . ..... . .. ... Citavi uredeni parovi (d.28) (25... . . .. .. M (d2)) ako i samo ako je d1 manji ili jednak d2. . . ploˇca........ . . funkcija postavlja da d1 6R d2. . . . . . . tj..4... ... 8.. . . . .... .. ... ..

.. .vezanu listu prve vrste: povezuje sve zapise s istim d1. Operacije COMPUTE2(R.&S2) odnosno COMPUTE1(R. UNRELATE( ) iz a. . COMPUTE2( ). imamo mnogo malih listi koje odgovaraju rezultatima operacija COMPUTE2( ). . Za implementaciju relacije koriste se iste strukture podataka kao za rjeˇcnik. 2 0 1 . /* dovoljno velike konstante */ typedef char[N2] *RELATION. . . Umjesto jedne vezane liste sa svim uredenim parovima (d1 . . . 1. Pokazat ´cemo dva primjera za takve modificirane strukture. 1. COMPUTE1( ). Uzimamo da je domain1 = {0. Jednodimenzionalno polje (vektor) presloˇzimo u dvodimenzionalno (matricu). a domain2 = {0. . RELATE( ).t. relaciju R pohranjujemo kao skup uredenih parova oblika (d1. struct cell tag *next1. . Jedan zapis je istovremeno ukljuˇcen u: .j) svode se na ˇcitanje i-tog retka odnosno j-tog stupca polja. d2). } celltype. d2) prikazan je zapisom tipa: typedef struct cell tag { domain1 element1.vezanu listu druge vrste: povezuje sve zapise s istim d2. N2 − 1}.2 Implementacija relacije pomo´ cu bit-matrice Nastaje na osnovu implementacije skupa pomo´cu bit-vektora (vidi poglavlje 4. ..3 Implementacija relacije pomo´ cu multi-liste Podsije´ca na implementaciju skupa pomo´cu vezane liste (vidi poglavlje 4. Jedan uredeni par (d1 . . RELATION implementiraju se analogno kao MAKE NULL( ). potrebne su male modifikacije i nadopune strukture.p. .p. SKUPOVI COMPUTE2(R. za zadani d2 funkcija skupu S1 pridruˇzuje kao vrijednost {d1 | d1 R d2}. 4. Da bi se mogle efikasno obavljati i operacije COMPUTE1( ). # define N2 .&S1. Operacije MAKE NULL( ). . .1). Za povezivanje listi prve odnosno druge vrste sluˇzi pointer next1 odnosno next2. Liste mogu biti sortirane i nesortirane. gdje su N1 i N2 dovoljno velike int konstante. R c 0 - 1 .4. DICTIONARY. /* poˇ cetna adresa char polja veliˇ cine N1 x N2 */ (i. INSERT( ) odnosno DELETE( ) iz a.. .d1. .t. U skladu s naˇsom definicijom. N1 − 1}. d2) takvih da je d1 R d2. j)-ti bit je 1 (odnosno 0) ako i samo ako je i-ti podatak u relaciji s j-tim podatkom.&S1.18 Implementacija relacije pomo´cu bit-matrice.. .4. .i. .&S2) . domain2 element2. N2-1 1 1 1 N1-1 Slika 4.50 4. 4. . za zadani d1 funkcija skupu S2 pridruˇzuje kao vrijednost {d2 | d1 R d2}. struct cell tag *next2.1). .. Relaciju prikazujemo dvodimenzionalnim poljem bitova ili char-ova sljede´ceg oblika: # define N1 . COMPUTE1(R..d2) .

...... ........ ..... ......... ...... . ....... . ......... . .. .. ...... .. . ...... (1...... .. . ...c ...... ...... 1 . . c . ... ........... Ova dva preslikavanja mogu se implementirati na razne naˇcine.. .. .......... .. 1 0 .... . Slika 4. .. .. ................. .. (2.... .. ...... ... . ...... .... ...c.. ........ ..... pronalaˇzenje pointera za zadani d1 (odnosno d2 ) te na prolazak odgovaraju´com vezanom listom prve (odnosno druge) vrste....... . 0 c 0 1 2 c c .. . .. .... poˇceci za liste prve vrste 0 2 .. .. (1.......4.. ... ... .... 3 3 c .. ... 1). . ........2. . ... ... . . .... 1 c . .... .c ....... . ........ ..19 Implementacija relacije pomo´cu multi-liste.......... . .............. ... .... ..... 3).. .. 2 4 ... ........... ........... ...... .... . tj........ .............. ........ ... .. . . ........ ... . (0............ ..... ... .. ... .. .. ......... ..... ................. ........ c c . c ... . Operacija COMPUTE2( ) (odnosno COMPUTE1( )) svodi se na primjenu preslikavanja......... . . 2 1 ... . Na slici je prikazana relacija R = {(0... ... 2)...c .. . .... ....4........ .1 i 4.. .... ....c ..... .... . . . .... .. ...... .. ... . 3)..c ....... 3). .. .... 3 c c 4 .... ....... ..... . .. .... c c .c ... ... ... . . .... ... ...... . .. .... .... ... . (2. . . . .. ... 1 2 ... 4)}. .. . . Dva preslikavanja prikazana su kao polja pointera.. 2 . PRESLIKAVANJE I RELACIJA 51 Pointer na poˇcetak liste prve (odnosno druge) vrste zadaje se preslikavanjem ˇcija domena je domain1 (odnosno domain2) a kodomena pointeri na celltype.c . ................................. ....... (2. ... ...... .. ... ... ... ... .......... .... poˇceci za liste druge vrste .......... 3 c ......... ........ ... ..... .... kao ˇsto je opisano u poglavljima 4. . . ....... ....... 1)..

SKUPOVI .52 4.

te da je implementirana poljem duljine barem n. umjesto o sortiranju liste (a1 . U ovom potpoglavlju bavimo se najjednostavnijim algoritmima za sortiranje koji se svode na zamjene elemenata. . . na primjer s vezanom listom. te analizirati njihovu vremensku sloˇzenost. Oba algoritma sa zamjenom elemenata imaju sliˇcnu (kvadratiˇcnu) vremensku sloˇzenost i sporiji su od ve´cine onih koji ´ce biti opisani u idu´cim potpoglavljima. zapisati ih u jeziku C. odnosno sortiranje zamjenom susjednih elemenata (bubble sort). . Treba permutirati vrijednosti elemenata tako da nakon permutiranja bude a1 ≤ a2 ≤ . Algoritam za sortiranje je bilo koji algoritam koji rjeˇsava problem sortiranja. svi algoritmi mogu se umjesto na cijele brojeve primijeniti na podatke nekog drugog tipa. Ovakva pojednostavnjenja ne predstavljaju bitno ograniˇcenje op´cenitosti. pod uvjetom da za te podatke imamo odgovaraju´cu operaciju usporedivanja ≤. a2. . Slika 5. Vrijednosti elemenata liste mogu se usporedivati totalnim uredajem ≤. . . mnogi od algoritama koje ´cemo izloˇziti mogu se prepraviti tako da umjesto s poljem rade s nekom drugom implementacijom liste. a2.1 Sortiranje izborom najmanjeg elementa (selection sort) Algoritam radi na sljede´ci naˇcin. pokazati primjere njihovog rada. . . Na kraju. Takoder. Prode se poljem i pronade se najmanji element. Toˇcnije. an) zapravo ˇcemo govoriti o sortiranju polja a[ ] koje se sastoji od elemenata a[0]. . 5. 53 . Dakle. . Zbog jednostavnosti. . svaki od algoritama za uzlazno sortiranje moˇze se na trivijalni naˇcin pretvoriti u silazno sortiranje: dovoljno je uredaj ≤ zamijeniti s ≥.5 ALGORITMI ZA SORTIRANJE 5. obradit ´cemo dva takva jednostavna postupka: sortiranje izborom najmanjeg elementa (selection sort). . Naime. Dalje se promatra ostatak polja (bez poˇcetnog elementa) i ponavlja isti postupak. . U ovom i u idu´ca tri potpoglavlja opisat ´cemo nekoliko algoritama za sortiranje. a[1]. Zadana je lista (a1 .1. an) duljine n. ≤ an . u svim navedenim potpoglavljima pretpostavljat ´cemo da se naˇsa lista sastoji od cijelih brojeva.1 Primjer sortiranja algoritmom izbora najmanjeg elementa. Da bi se cijelo polje sortiralo potrebno je n − 1 prolazaka. . a[n-1] tipa int. Zatim se najmanji element zamijeni s poˇcetnim.1 Sortiranje zamjenom elemenata Problem (uzlaznog) sortiranja glasi ovako.

U prvom prolasku imamo n − 1 usporedbi. .Algoritam obavlja isti posao bez obzira na poˇcetno stanje polja. . Pomo´cna funkcija swap() sluˇzi za zamjenu vrijednosti dviju cjelobrojnih varijabli sa zadanim adresama. Ta funkcija prima kao argumente cjelobrojno polje a[ ] i njegovu duljinu n. } Analiza vremenske sloˇzenosti salgoritma sortiranja izborom najmanjeg elemenata (selection sort) izgleda ovako. int n) { int i. j++) if (a[j] < a[min]) min = j. zamijenimo im vrijednosti. . Algoritam sortiranja izborom najmanjeg elementa (selection sort) moˇze se u jeziku C realizirati sljede´com funkcijom selectionSort(). &a[min]).U svakom prolasku postoji joˇs jedna zamjena. j. i < n. *y = aux. . Sesti prolaz sluˇzi zato da se ustanovi da viˇse nema parova susjednih elemenata koje bi trebalo zamijeniti. . pa imamo joˇs 3(n − 1) operacija pridruˇzivanja. *x = *y. for (i = 0. U svakom prolasku pronadeni najmanji element oznaˇcen je sjenˇcanjem. Kad na taj naˇcin dodemo do kraja polja.2 Sortiranje zamjenom susjednih elemenata (bubble sort) Opis algoritma ide ovako. ˇcak i ako je polje veˇc na pocetku bilo sortirano.1. Promatrani ˇ dio polja nalazi se s lijeve strane dvostruke okomite crte.2.1. a u svakom iduˇcem prolasku broj usporedbi se smanji za 1.54 5. ALGORITMI ZA SORTIRANJE Primjer sortiranja izborom najmanjeg elemenata (selection sort) vidi se na slici 5. najve´ca vrijednost do´ci ´ce na posljednje mjesto.Dakle ukupni broj operacija je : n(n − 1)/2 + 3(n − 1) = O(n2). int *y) { int aux. U svakom koraku dva susjedna elementa koji trebaju zamijeniti vrijednosti oznaˇceni su sjenˇcanjem. Sedmi prolazak nije potreban jer je nakon ˇsestog prolaska preostali dio polja duljine 1. min. Ako je neki element ve´ci od sljede´ceg elementa. Promatrani dio polja nalazi se s desne strane dvostruke okomite crte. void selectionSort (int a[]. 5. j < n. Prolazimo poljem od poˇcetka prema kraju i usporedujemo susjedne elemente. Funkcija mijenja polje a[ ] tako da ono postane sortirano. aux = *x. Primjer sortiranja zamjenom susjednih elemenata (bubble sort) vidi se na slici 5. swap(&a[i]. Nakon toga ponavljamo postupak na skra´cenom polju (bez zadnjeg elementa). Algoritam se smije zaustaviti ˇcim on u nekom prolazu ustanovi da nema parova elemenata koje bi trebalo zamijeniti. Dakle ukupni broj usporedbi iznosi: (n − 1) + (n − 2) + (n − 3) + · · · + 2 + 1 = n(n − 1)/2. for (j = i+1. i++) { min = i. } } void swap (int *x.

void bubbleSort (int a[]. j++) if (a[j+1] < a[j]) swap(&a[j].5. int n) { int i. i++) { chg = 0. SORTIRANJE ZAMJENOM ELEMENATA 55 Slika 5. j++) if (a[j+1] < a[j]) { swap(&a[j]. chg = 1. int n) { int i. &a[j+1]). Poboljˇsana verzija funkcije bubbleSort() izgleda ovako. j < n-1-i.2 Primjer sortiranja algoritmom zamjene susjednih elemenata. j. chg = 1. Funkcija opet prima kao argumente cjelobrojno polje a[ ] i njegovu duljinu n. void bubbleSort1 (int a[]. chg. . &a[j+1]). j. Sljede´ca funkcija bubbleSort() implementira algoritam sortiranja zamjenom susjednih elemenata (bubble sort) u jeziku C. for (i = 0. i < n-1. for (i = 0. j < n-1-i. } Implementacija se moˇze poboljˇsati tako da se postupak zaustavi ˇcim se ustanovi da u nekom prolazu nije bilo ni jedne zamjene susjednih elemenata. te mijenja polje a[ ] tako da ono postane sortirano.1. } } } U nastavku slijedi analiza vremenske sloˇzenosti opisanog algoritma sortiranja zamjenom susjednih elemenata (bubble sort). i++) for (j = 0. chg. Koristi se ista pomo´cna funkcija swap() za zamjenu vrijednosti dviju cjelobrojnih varijabli kao i prije. for (j = 0.

a duljina nesortiranog dijela se smanji za 1. poˇcetni komad polja je ve´c sortiran.U prvom prolazu imamo u najgorem sluˇcaju n − 1 usporedbi i n − 1 zamjena elemenata. jednim prolaskom duljina poˇcetnog sortiranog dijela se pove´ca za 1. . te ga umetne na “pravo mjesto” (u smislu sortiranog redoslijeda) u sortirani dio. Najprije promatramo jednostavnu verziju takvog algoritma (insertion sort) gdje se osnovni korak umetanja iterira dovoljni broj puta. a nesortirani s desne strane.1 Jednostavno sortiranje umetanjem (insertion sort) Za vrijeme rada algoritma.56 5.. .. U svakom prolasku. . U jednom prolasku algoritam uzima prvi element iz nesortiranog dijela. vrijeme izvodenja je O(n2 ). 5.3. .3 Primjer jednostavnog sortiranja umetanjem.Dakle ukupan broj operacija u najgorem sluˇcaju iznosi: 4(n − 1) + 4(n − 2) + · · · + 4 · 1 = 4n(n − 1)/2 = 2n(n − 1).2 Sortiranje umetanjem U ovom potpoglavlju razmatramo algoritme za sortiranje koji se svode na umetanje novog elementa u ve´c sortirani niz elemenata. Sortirani dio polja nalazi se s lijeve strane dvostruke okomite crte. pri ˇcemu dolazi do pomicanja nekih elemenata za jedno mjesto dalje. Dalje promatramo sloˇ zeniju no brˇ zu verziju algoritma (Shell sort) koja se dobiva viˇsestrukom primjenom jednostavne verzije.U svakom sluˇcaju.Ocijenjeni broj operacija zaista se dobiva kad su elementi poˇcetnog polja sortirani silazno. Implementacija jednostavnog sortiranja umetanjem (insertion sort) u jeziku C svodi se na sljede´cu funkciju insertionSort().Za bilo koje drugo uredenje poˇcetnog polja broj operacija je izmedu (n − 1) i 2n(n − 1).. ako je poˇcetno polje ve´c sortirano uzlazno.U drugom prolazu imamo u najgorem sluˇcaju n − 2 usporedbi i n − 2 zamjena elemenata. . .U (n − 1)-vom prolazu imamo u najgorem sluˇcaju 1 usporedbu i 1 zamjenu elemenata.. obavit ´ce se samo jedan prolaz s n − 1 usporedivanja i 0 zamjena..S druge strane.. a ostatak polja nije sortiran. . . te njegovu duljinu n. Dakle.2. element iz nesortiranog dijela polja koji se ume´ce u sortirani dio oznaˇcen je sjenˇcanjem. . Primjer rada jednostavnog algoritma za sortiranje umetanjem (insertion sort-a) vidi se na slici 5. Funkcija opet kao argument prima cjelobrojno polje a[ ] kojeg treba sortirati.. ALGORITMI ZA SORTIRANJE . 5. Mjesto umetanja oznaˇceno je strelicom. Slika 5.

. . 5. j--) a[j] = a[j-1]. for (j = i. . Preciznije. a[j] = aux. Proces k-struke primjene jednostavnog sortiranja umetanjem (insertion sort-a) u svrhu zasebnog sortiranja svakog od ovih k pod-polja zove se k–subsort. a[2k + 1]. i++) { aux = a[i].. Pk−1 : a[k − 1]. } } Slijedi analiza vremenske sloˇzenosti jednostavnog algoritma za sortiranje umetanjem (insertion sort). Slika 5. na kraju km -subsort.Dakle ukupni broj operacija u najgorem sluˇcaju je otprilike 2 · 1 + 2 · 2 + · · · + 2(n − 1) = n(n − 1). j. Zateˇcene elemente pomiˇcemo za jedno mjesto dalje dok god su oni ve´ci od elementa kojeg ˇzelimo umetnuti na “pravo mjesto”.. To u najgorem sluˇcaju daje k usporedbi i otprilike isto toliko pridruˇzivanja. a[2k]. int aux.. a[k].U k-tom prolasku natraˇske prolazimo sortiranim dijelom polja duljine k. zatim k2 –subsort. .. .. for (i = 1. Unatoˇc takvoj asimptotskoj ocjeni. .. a[2k − 1]. P1 : a[1].2 Viˇ sestruko sortiranje umetanjem (Shell sort) Za zadani k promatra se k razliˇcitih pod-polja sastavljenih od elemenata originalnog polja medusobno udaljenih za toˇcno k mjesta.4 Primjer viˇsestrukog sortiranja umetanjem. j >= 1 && a[j-1] > aux. . Promijetimo da zadnji km -subsort (ustvari 1–subsort) izvodi obiˇcni insertion sort na cijelom originalnom polju.. i < n.2. za zadani k promatraju se pod-polja: P0 : a[0]. a[k + 1].2.. a[3k − 1]... . . ovaj algoritam se u praksi ipak pokazuje brˇzim od prije opisanih algoritama sa zamjenom elemenata.5.Red veliˇcine za vrijeme izvodenja je opet O(n2 ). . . Algoritam viˇsestrukog sortiranja umetanjem (shell sort) radi tako da za definirani padaju´ci niz k1 > k2 > · · · > km = 1 obavi k1–subsort. int n) { int i. . SORTIRANJE UMETANJEM 57 void insertionSort (int a[]. Zato korektnost algoritma nije upitna. Prethodni k-subsortovi sluˇze zato da (rade´ci nad kratkim pod-poljima) donekle urede cijelo polje tako da idu´ci k-subsortovi imaju sve manje posla. .

i < n. dakle bolja nego kod svih dosadaˇsnjih algoritama. . no ni jedna od tih ocjena ne pokriva sve sluˇcajeve za niz k-ova. za razliku od drugih algoritama. tada se moˇze pokazati da je sloˇzenost u najgorem sluaju O(n3/2 ). te u naˇcinu spajanja manjih polja u ve´ce. . km = 1. Implementacija viˇsestrukog sortiranja umetanjem (Shell sort-a) u jeziku C dobiva se nadogradnjom prije prikazane implementacije jednostavnog sortiranja umetanjem. Ta dva polja treba na ˇsto jednostavniji naˇcin prepisati u tre´ce polje c[ ] duljine n + m koje je opet uzlazno sortirano. k2 = n/4. u svakom sluˇcaju brˇzi nego ˇsto pokazuju raspoloˇzive ocjene sloˇzenosti. step > 0. } } } Algoritam viˇsestrukog sortiranja umetanjem (Shell sort) predstavlja nepoznanicu i tvrd orah za istraˇzivaˇce. ALGORITMI ZA SORTIRANJE Primjer rada algoritma viˇsestrukog sortiranja umetanjem (Shell sort-a) vidi se na slici 5.Prosjeˇcno vrijeme izvodenja je otvoreni problem. j >= step && a[j-step] > aux. Usporedujemo teku´ce elemente u a[ ] i b[ ]. dakle algoritme koji u svrhu sortiranja polja pozivaju sami sebe. Takoder ´cemo na poˇcetku potpoglavlja obraditi pomo´cni postupak saˇ zimanja sortiranih polja koji se pojavljuje kao osnovni korak u algoritmu sortiranja saˇzimanjem. . .Ako je padaju´ci niz k1 > k2 > · · · > km = 1 oblika 2l − 1 > 2l−1 − 1 > · · · > 7 > 3 > 1. Zadana su dva uzlazno sortirana polja: a[ ] duljine n i b[ ] duljine m. dva rekurzivna algoritma imaju drukˇcije osobine u pogledu vremenske sloˇzenosti. zatim rekurzivnim pozivima sortiraju ta dva manja polja. j -= step) a[j] = a[j-step]. .Eksperimentalna mjerenja pokazuju da je algoritam iznenaduju´ce brz. Postupak saˇzimanja (merge) ide ovako.1 Saˇ zimanje sortiranih polja (merge) Kao ˇsto smo najavili. . Razlika je u naˇcinu dijeljenja velikog polja na manja polja. . te istovremeno prepisujemo proˇcitane elemente u c[ ]. Dakle pamtimo kazaljku teku´ceg elementa u polju a[ ] odnosno b[ ].4. Zahvaljuju´ci tim razlikama.Postoje joˇs neki specijalni oblici niza k1 > k2 > · · · > km = 1 za koje su izvedene ocjene sloˇzenosti. int aux. . Naime. Promatramo rad algoritma s padaju´cim nizom k-ova: 4 > 2 > 1. Obradit ´cemo dva takva algoritma: sortiranje pomo´ cu saˇ zimanja (merge sort) i brzo sortiranje (quick sort). a[j] = aux. najprije rjeˇsavamo jedan pomo´cni problem koji je usko vezan s problemom sortiranja. Simultano ˇcitamo a[ ] i b[ ] od poˇcetka do kraja. 5. za taj algoritam joˇs uvijek ne postoje jasne i cjelovite ocjene vremenske sloˇzenosti. . Potrebno je dodati joˇs jednu petlju koja odgovara odabranom nizu k-subsortova.3. void ShellSort (int a[]. Sliˇcnost dvaju razmatranih rekurzivnih algoritama sortiranja je u tome ˇsto oba dijele zadano polje na dva manja polja. for (step = n/2. j.3 Rekurzivni algoritmi za sortiranje U ovom potpoglavlju razmatramo rekurzivne algoritme za sortiranje. step /= 2) { for (i = step. step. 5. Sljede´ca funkcija ShellSort( ) koristi niz k-ova oblika k1 = n/2. for (j = i. int n) { int i. te na kraju spajaju ta dva manja sortirana polja u jedno sortirano polje. i++) { aux = a[i]. te kazaljku na prvo slobodno mjesto u c[ ]. Unutar svakog retka ista boja oznaˇcava elemente koji u okviru dotiˇcnog k–subsorta ˇcine jedno pod-polje.58 5.

Primjer saˇzimanja (merge) sortiranih polja a[ ] i b[ ] u sortirano polje c[ ] prikazan je na slici 5. /* kazaljka za pisanje u veliko polje */ count = r-l+1. Polazni dijelovi polja p[ ] moraju biti sortirani. int r) { int i. i < count. koja pretpostavlja da su prije spomenuta polja a[ ]. for (i = 0. . Slika 5. oba prepiˇsemo u c[ ]. int aux[].Ako je jedan od tih teku´cih elemenata manji. . Strelice oznaˇcavaju kazaljke teku´cih elemenata u a[ ] i b[ ]. Postupak saˇzimanja (merge) mogu´ce je u jeziku C implementirati sljede´com funkcijom merge( ). } while (l <= k1) /* Kopiraj ostatak prvog malog polja */ aux[k2++] = p[l++]. void merge (int p[].Ako su teku´ci elementi jednaki. k1.Kad jedno od polja a[ ] i b[ ] proˇcitamo do kraja. odnosno kazaljku prvog slobodnog mjesta u c[ ]. else aux[k2++] = p[k++]. aux. Kao privremeni radni prostor. } . int k. funkcija koristi pomo´cno polje aux[ ]. b[ ] i c[ ] ustvari dijelovi nekog joˇs ve´ceg polja p[ ]. c[ ] ´ce zauzimati isti fiziˇcki prostor. i++. tada ga prepiˇsemo u c[ ] te pomaknemo odgovaraju´cu kazaljku u a[ ] odnosno b[ ]. Sjenˇcanje oznaˇcava elemente koji su u odredenom koraku odabrani za prepisivanje. /* indeks kraja prvog malog polja */ k2 = l.3. REKURZIVNI ALGORITMI ZA SORTIRANJE 59 . while (k <= r) /* Kopiraj ostatak drugog malog polja */ aux[k2++] = p[k++]. tada ostatak drugog polja izravno prepiˇsemo u c[ ].5 Primjer saˇzimanja sortiranih polja. /* broj elemenata u velikom polju */ while (l <= k1 && k <= r) { /* glavna petlja za sazimanje */ if (p[l] <= p[k]) aux[k2++] = p[l++]. count. int l. . Pritom a[ ] odgovara elementima od p[ ] s indeksima izmedu l i k-1. te pomaknemo obje kazaljke u a[ ] i u b[ ]. Nakon saˇzimanja.5. a b[ ] odgovara elementima od p[ ] s indeksima izmedu k i r.5.Kod svakog prepisivanja pomiˇcemo kazaljku u c[ ]. dakle dio od p[ ] s rasponom indeksa izmedu l i r. r--) /* Kopiraj veliko polje natrag */ p[r] = aux[r]. k1 = k-1.

aux. Dakle sloˇzenost iznosi O(n + m).3. mid+1. Slika 5. left. int right) { int mid. mid+1. Oˇcito je da je vrijeme izvrˇsavanja algoritma proporcionalno sa zbrojem duljina zadanih polja odnosno s duljinom rezultiraju´ceg polja. } } U nastavku provodimo analizu vremenske sloˇzenosti opisanog algortima sortiranja saˇzimanjem (merge sort). 0. n-1). mergeSort (a. .6 Primjer sortiranja saˇzimanjem. int left. 5.6. Primjer sortiranja saˇzimanjem (merge sort) vidi se na slici 5. int aux[]. glavni program mora najprije alocirati pomo´cno polje aux[ ] iste duljine. Algoritam sortiranja saˇzimanjem (merge sort) moˇze se implementirati u jeziku C kao sljede´ca funkcija mergeSort( ). mid). mergeSort (a.2 Sortiranje saˇ zimanjem (merge sort) Kao ˇsto smo najavili. void mergeSort (int a[]. right). aux. rijeˇc je o rekurzivnom algoritmu. aux. if (left < right) { mid = (left + right) / 2. Uglate zagrade oznaˇcavaju pojedina polja koja nastaju u postupku sortiranja. te zatim pozvati mergeSort( ) sa sljede´cim argumentima: mergeSort(a. aux. tada je ve´c sortirano. Inaˇce se zadano polje podijeli se na dva manja polja podjednakih duljina. Da bi sortirao polje a[ ] duljine n. right). Ta dva manja polja zasebno se sortiraju rekurzivnim pozivima istog algoritma. ALGORITMI ZA SORTIRANJE Analiza vremenske sloˇzenosti algoritma saˇzimanja (merge) glasi ovako. Ukoliko se zadano polje sastoji samo od 1 elementa. Zatim se mala sortirana polja saˇzimlju u jedno (sortirano) uz pomo´c prethodno opisanog postupka saˇzimanja (merge). Rijeˇc je o funkciji koja ostvaruje algoritam pozivaju´ci samu sebe i funkciju za saˇzimanje merge( ). Plave strelice oznaˇcavaju podjele ve´cih polja na manja.60 5. merge (a. left. Crvene strelice oznaˇcavaju saˇzimanje manjih sortiranih polja u ve´ca.

Odabere se jedan element u polju.5.uˇcinak razvrstavanja. ili na trivijalni naˇcin za pod-polje duljine 0 ili 1. primje´cujemo da oni rade s poljima ˇciji zbroj duljina je jednak duljini polaznog polja n.8 Brzo sortiranje .Budu´ci da nivoa ima log2 n + 1. Ta dva elementa na “krivim stranama” medusobno zamijenimo i zatim nastavimo s pomicanjem kazaljki. Svi ostali elementi razvrstaju se ispred (lijevo od) odnosno iza (desno od) stoˇzera ovisno o tome da li su ≤ ili ≥ od stoˇzera. Samo razvrstavanje elemenata lijevo odnosno desno od stoˇzera efikasno se obavlja u skladu sa slikom 5. Sortiranje pod-polja postiˇze se rekurzivnim pozivima istog algoritma. dovoljno je zasebno (neovisno) sortirati pod-polje lijevo odnosno desno od stoˇzera. Dakle zbrojeno vrijeme raˇcunanja za sve rekurzivne pozive na istom nivou je O(n).7.Prednost u odnosu na druge “brze” algoritme je mogu´cnost sortiranja velikih polja (datoteki) pohranjenih u vanjskoj memoriji raˇcunala. REKURZIVNI ALGORITMI ZA SORTIRANJE 61 . . . takozvani stoˇ zer. . 5. kao na slici 5. ukupna vremenska sloˇzenost algoritma u najgorem sluˇcaju je (log2 n + 1) · O(n) = O(n log n).Skup svih rekurzivnih poziva koji nastaju pri rjeˇsavanju polaznog problema moˇze se prikazati binarnim stablom. Razvrstavanje je zavrˇseno kad se kazaljke prekriˇze. sve dok su teku´ci elementi ≤ odnosno ≥ od stoˇzera. .detalji postupka razvrstavanja.Kad gledamo sve rekurzivne pozive na istom nivou stabla. Oˇcigledno. . nakon ovakvog razvrstavanja stoˇzer se nalazi na svom “konaˇcnom mjestu” u smislu traˇzenog sortiranog poretka.6.7 Brzo sortiranje .3. tako da pomiˇcemo kazaljku s lijevog odnosno desnog kraja polja. .3 Brzo sortiranje (quick sort) Opet je rijeˇc o rekurzivnom algoritmu za sortiranje. rijeˇc o jednom od najbrˇzih poznatih algoritama za sortiranje.Zahvaljuju´ci ovakvoj ocjeni u najgorem sluˇcaju. Slika 5.Mana u odnosu na druge “brze” algoritme je dodatni utroˇsak memorije potreban zbog prepisivanja polja u sklopu saˇzimanja. Slika 5.3. Da bi se polje sortiralo do kraja.Svaki rekurzivni poziv algoritma ima vrijeme raˇcunanja proporcionalno duljini rezultiraju´ceg (saˇzetog) polja kojeg ´ce on proizvesti.8. Kad se obje kazaljke zaustave. Ideja je ilustrirana slikom 5. naˇsli smo element slijeva koji je > od stoˇzera i element s desna koji je < od stoˇzera. .

void quickSort(int a[]. Opet se koristi pomo´cna funkcija swap() za zamjenu vrijednosti dviju cjelobrojnih varijabli (vidi odjeljak 5.primjer rada algoritma. 0. Sljede´ca rekurzivna funkcija quickSort( ) predstavlja najjednostavniju varijantu implementacije. j+1. r). Dvostruka okomita crta pokazuje da je stoˇzer izdvojen tijekom postupka rasvrstavanja.1. } else { /* stozer je negdje u sredini */ swap(&a[j].1). } } . quickSort(a. /* razvrstavanje elemenata s obzirom na stozer */ j = r. int l. if (l>=r) return. r-1). r). quickSort(a. &a[j]). Da bi sortirao polje a[ ] duljine n. glavni program mora pozvati quickSort( ) sa sljede´cim argumentima: quickSort(a. while ((a[j] > a[l]) && (j>l)) j--. ALGORITMI ZA SORTIRANJE Slika 5. gdje se u svakom rekurzivnom pozivu kao stoˇzer bira poˇcetni element pod-polja kojeg upravo treba sortirati. int r) { int i. l. while ((i <= j) && (i<=r) && (j>l)) { while ((a[i] < a[l]) && (i<=r)) i++. n-1). quickSort(a. l. Primjer rada algoritma brzog sortiranja (quick sort) prikazan je na slici 5. Nisu prikazani detalji unutar tih rekurzivnih poziva.9 Brzo sortiranje . } else if (j<=l) { /* stozer je najmanji u polju */ quickSort(a. Uglate zagrade zatvaraju pod-polja koja se sortiraju rekurzivnim pozivima istog algoritma.9.j. l+1.62 5. Simboli ↑L odnosno ↑D oznaˇcavaju poloˇzaj kazaljke s lijevog odnosno desnog kraja polja u raznim fazama razvrstavanja elemenata. &a[l]). j-1). Algoritam brzog sortiranja (quick sort) moˇze se implementirati u jeziku C na viˇse naˇcina s obzirom na razne mogu´cnosti izbora stoˇzera. } if (i>r) { /* stozer je najveci u polju */ swap(&a[r]. &a[l]). if (i<j) swap(&a[i]. i = l+1.

SORTIRANJE POMOCU 63 Slijedi popis najvaˇznijih rezultata koji su dobiveni analizom vremenske sloˇzenosti algoritma brzog sortiranja (quick sort). naime svaki od njih sortira polje tako da elemente polja najprije redom ubaci u binarno stablo. Nakon to su svi podaci ubaˇceni. 24. Uoˇceno svojstvo binarnog stabla traˇzenja i inorder-obilaska moˇze se iskoristiti za oblikovanje algoritma za sortiranje koji se zove tree-sort. 3. najbrˇzi od svih poznatih algoritama. 5. 17.2. 31. Cesto koriˇstene mogu´cnosti za izbor stoˇzera su: poˇcetni element (kao u naˇsem primjeru i funkciji).1 Sortiranje obilaskom binarnog stabla traˇ zenja (tree sort) Iz definicije binarnog stabla traˇzenja (vidi odjeljak 4. Razlika je u vrsti binarnog stabla koje se koristi: u prvom sluˇcaju to je binarno stablo traˇzenja.Praktiˇcna iskustva pokazuju da je algoritam u stvarnosti izuzetno brz. 11. dakle brˇzi nego ˇsto se to moˇze prepoznati iz teorijskih ocjena.4.´ BINARNIH STABALA 5. zatim korijen.Ponaˇsanje algoritma u priliˇcnoj mjeri ovisi o naˇcinu biranja stoˇzera. 31.10 Sortiranje obilaskom binarnog stabla traˇzenja. odnosno sortiranje pomo´ cu hrpe (heap sort). 5. .1) oˇcigledno je da inorder-obilazak posje´cuje ˇcvorove binarnog stabla traˇzenja u sortiranom redoslijedu s obzirom na njihove oznake. i to onim redom kako ih inorder posje´cuje. kraju odnosno sredini polja. Slika 5.dakle korijen se u nizu posje´cenih ˇcvorova nalazi na svom “pravom mjestu” u smislu sortiranog poretka po oznakama. ˇ .4) i inorder-obilaska (vidi odjeljak 3. sortirajmo polje sa sljede´cim sadrˇzajem: 17. Upisujemo oznake iz binarnog stabla natrag u polje. 43. 8. inorder-obilazak najprije posje´cuje sve ˇcvorove ˇcije oznake su manje od oznake korijena. . 43. a zatim ih izvadi iz tog stabla u sortiranom redoslijedu. . a u drugom sluˇcaju to je hrpa. Zaista.4. Dobivamo binarno stablo prikazano na slici 5.Postoji matematiˇcki dokaz da je prosjeˇcno vrijeme izvrˇsavanja O(n log n).4 Sortiranje pomo´ cu binarnih stabala U ovom potpoglavlju obradit ´cemo joˇs dva algoritma za sortiranje. Dva algoritma liˇce jedan na drugog. te na kraju ˇcvorove ˇcije oznake su ve´ce od oznake korijena . Najgori sluˇcaj nastupa kad je stoˇzer poˇcetni element i kad je polje ve´c sortirano. 24. Najprije sve podatke iz polja redom ubacujemo u binarno stablo traˇzenja. 11. To su: sortiranje obilaskom binarnog stabla traˇ zenja (tree sort).1. . Isto svojstvo vrijedi zbog rekurzije i za sve ostale ˇcvorove. Kad podatke iz tog binarnog stabla u inorder-redoslijedu prepiˇsemo natrag u polje dobivamo: 3. obilazimo binarno stablo postupkom indorder.10. Kao primjer rada algoritma za sortiranje obilaskom binarnog stabla traˇzenja (tree sort). pa je cijeli niz posje´cenih ˇcvorova ispravno sortiran.Moˇze se lako provjeriti da algoritam u najgorem sluˇcaju ima sloˇzenost O(n2 ). odnosno medijan izabran izmedu tri elementa koji se nalaze na poˇcetku. 8. Podaci iz polja koje treba sortirati redom se ubacuju u binarno stablo kao oznake ˇcvorova. Algoritam kre´ce od praznog binarnog stabla traˇzenja.

return node. node->element = x. } celltype *insert (int x. Funkcija writeInorder() obavlja inorder obilazak izgradenog binarnog stabla.4. te usputno prepisivanje podataka iz binarnog stabla natrag u polje u redoslijedu obilaska.2.2. next. writeInorder(node->rightchild. int *np) { if (node != NULL) { writeInorder(node->leftchild. a. } } . typedef struct cell tag { int element. writeInorder() i destroy().1. Funkcija destroy() razgraduje binarno stablo i dealocira memoriju. *np += 1. Pritom jedan poziv insert() ubacuje u binarno stablo jedan ˇcvor s elementom iz a[ ] na naˇcin sliˇcan kao u odjeljku 4. np). Sortiranje polja a[ ] duljine n obavlja se pozivom treeSort(a. tree). Rad funkcije treeSort() ostvaruje se pozivanjem triju pomo´cnih funkcija: insert().64 5. int n) { int i. tree = NULL. struct cell tag *rightchild.1. Uzastopni pozivi insert() dinamiˇcki alociraju memoriju i grade binarno stablo traˇzenja u kojem su prepisani svi podaci iz a[ ]. for (i=0. te funkcija za obilazak binarnih stabala nalik onima iz odjeljka 3. ALGORITMI ZA SORTIRANJE Algoritam sortiranja obilaskom binarnog stabla traˇzenja (tree sort) mogao bi se implementirati kombiniranjem funkcija za rad s binarnim stablima traˇzenja iz odjeljka 4. struct cell tag *leftchild. destroy(tree). Ipak. void treeSort (int a[]. celltype *tree. } void writeInorder (celltype *node. next=0. } else if (x < node->element) node->leftchild = insert(x. i++) tree = insert(a[i].4. node->leftchild = node->rightchild = NULL. a. Sve funkcije se oslanjaju na definiciju tipa celltype koji odgovara ˇcvoru binarnog stabla. int a[]. node->rightchild). else node->rightchild = insert(x. celltype *node) { if (node == NULL) { node = (celltype*) malloc(sizeof(celltype)). a. u nastavku ´cemo izloˇziti kompaktniju i donekle modificiranu verziju takvog programskog koda. np). node->leftchild). &next). i<n.n). a[*np] = node->element. s time da se sada dopuˇstaju i ˇcvorovi s jednakim podacima. writeInorder(tree. } celltype.

. 11. 17. ispada da cijeli algoritam sortiranja ima vrijeme O(n log n).Najgori sluˇcaj nastupa na primjer onda kad je niz podataka ve´c sortiran: binarno stablo traˇzenja tada se pretvara u “koso” binarno stablo s visinom n. free(node). Algoritam najprije dodaje podatke iz polja u hrpu. void heapSort (int a[]. . gradnja binarnog stabla zahtijeva vrijeme O(n log n). Zahvaljuju´ci svojstvima hrpe odnosno svojstvima operacije izbacivanja najmanjeg elementa. 3. Kao primjer koriˇstenja algoritma za sortiranje pomo´cu hrpe (heap sort) promatramo sortiranje polja koje ima sljede´ci sadrˇzaj: 17. pa ih tako dobiva natrag u sortiranom redoslijedu.Kad se to sve zbroji. te se vra´caju u polje. tada ´ce dobiveno binarno stablo traˇzenja biti dobro razgranato. Algoritam se obiˇcno implementira tako da se hrpa pohrani u polju. 11. Zatim se podaci redom skidaju s hrpe primjenom operacije izbacivanja najmanjeg elementa. 24. int n) { int i.Budu´ci da svaka operacija ubacivanja zahtijeva vrijeme proporcionalno visini binarnog stabla. ta ocjena vrijedi samo za vrijeme u prosjeˇcnom sluˇcaju. i hrpa (vidi odjeljak 4. 43. Koriste se pomo´cne funkcije buildHeap( ) i adjust( ) navedene ispod heapSort( ). te budu´ci da imamo n ubacivanja. } } Slijedi analiza sloˇzenosti opisanog algoritma sortiranja zasnovanog na obilasku binarnog stabla traˇzenja (tree sort). Rezultiraju´ci algoritam za sortiranje naziva se sortiranje pomo´cu hrpe (heap sort).3. destroy(node->rightchild).1. Postupak je prikazan slikom 5.3. 0. 8.Ipak. dakle od namanjeg prema najve´cem. i to od poˇcetka polja prema kraju.Inorder-obilazak oˇcito ima linearnu sloˇzenost O(n). . 43. Algoritam sortiranja pomo´cu hrpe (heap sort) mogao bi se implementirati kombiniranjem funkcija za rad s hrpom iz odjeljka 4. 8. adjust(a. SORTIRANJE POMOCU 65 void destroy (celltype *node) { if (node != NULL) { destroy(node->leftchild). . Sortiranje polja a[ ] duljine n obavlja se pozivom sljede´ce funkcije heapSort( ). te se u konaˇcnici svodi na manipuliranje s podacima u polju (sliˇcno kao i ostali prikazani algoritmi za sortiranje). U nastavku dajemo kompaktniju verziju sliˇcnog programskog koda.3) se moˇze primijeniti za sortiranje.11. dobiva se polje sa sadrˇzajem: 3.1. n). buildHeap (a. i >= 2.3.´ BINARNIH STABALA 5. Kad se podaci onim redom kako su bili izbaˇceni ponovo unesu u polje. tj njegova visina bit ´ce otprilike log2 n.Ako su podaci u polaznom polju dobro izmijeˇsani. i--) { swap(&a[0]. . 5.4. a zatim ih skida s hrpe. 31. } } . for (i = n.2 Sortiranje pomo´ cu hrpe (heap sort) Sliˇcno kao binarno stablo traˇzenja. 31. gdje je n broj podataka koje sortiramo. pa cijeli algoritam sortiranja zahtijeva O(n2 ) operacija. 24. i-1).4. te swap( ) iz odjeljka 5. &a[i-1]). podaci izlaze iz hrpe u sortiranom poretku. . Podaci iz polja koje ˇzelimo sortirati najprije se redom ubacuju u hrpu.

ALGORITMI ZA SORTIRANJE Slika 5. .11 Sortiranje pomo´cu hrpe.66 5.

a[(j-1)/2] = a[j]. onako kako je bilo opisano u odjeljku 4. Da bi skra´ceno polje opet postalo hrpa. Opisana implementacija je spretna zato ˇsto se podaci izbaˇceni iz hrpe redom slaˇzu u nekoriˇstenom dijelu polja.´ BINARNIH STABALA 5. i >= 0. a njime se obavlja cikliˇcka zamjena oznaki po putu od ˇcvora i prema nekom listu. . int n) { int j. . . x = a[i]. tada u priloˇzenom programskom kodu moramo invertirati uredajnu relaciju. if (x <= a[j]) break.Eksperimenti pokazuju da heap-sort zaista spada medu najbrˇze poznate algoritme za sortiranje i da uspjeˇsno sortira vrlo velika polja. Jedan poziv adjust( ) odnosi se na unutraˇsnji ˇcvor i potpunog binarnog stabla od n ˇcvorova. najmanja oznaka nalazi se u korijenu. } Polje a[ ] kojeg treba sortirati interpretira se kao prikaz potpunog binarnog stabla u skladu s odjeljkom 3. i. . slijedi da je vrijeme u najgorem sluˇcaju za cijelo sortiranje reda O(n log n). dakle tamo gdje bi se na kraju i trebali na´ci. j = 2*i+1.3. } a[(j-1)/2] = x. i--) adjust(a. odnosno izbacivanja najmanjeg elementa iz hrpe.4. Sam buildHeap( ) svodi se na niz poziva pomo´cne funkcije adjust( ). dakle sve uvjete ≤ moramo zamijeniti s ≥ i obratno. n). No pozivom pomo´cne funkcije buildHeap( ) oznake se premjeˇstaju tako da se zadovolji svojstvo hrpe.Budu´ci da jedno ubacivanje odnosno izbacivanje ima sloˇzenost O(log n). No primijetimo da ´cemo dobiti silazno sortirano polje umjesto uzlaznog. Slijedi analiza sloˇzenosti algoritma sortiranja pomo´cu hrpe (heap sort). int n) { int i. Izbacivanje najmanje oznake iz hrpe obavlja se tako da se poˇcetni element polja a[ ] zamijeni sa zadnjim. Nakon ˇsto je binarno stablo postalo hrpa. int x.2. Nizom ovakvih iteracija izbacit ´cemo iz hrpe sve oznake od najmanje prema najve´coj. Na poˇcetku to binarno stablo nije hrpa jer oznake ˇcvorova nisu rasporedene na propisani naˇcin. j = 2*j+1.2. Ako nam to smeta. int i. while (j <= n-1 ) { if ((j < n-1) && (a[j] > a[j+1])) j++.3. } void adjust(int a[].Algoritam se svodi na n-struku primjenu operacije ubacivanja elementa u hrpu. te da se duljina polja skrati za 1. SORTIRANJE POMOCU 67 void buildHeap (int a[]. for (i = n/2-1. potrebno ga je podesiti dodatnim pozivom adjust( ).

68 5. ALGORITMI ZA SORTIRANJE .

Takoder. dobiveni algoritam ne mora biti efikasan. 3.1 Metoda “podijeli pa vladaj” Na osnovu dugogodiˇsnjeg iskustva. backtracking i lokalno traˇzenje... to ju je teˇze sortirati. Na kraju.naime svaki od manjih problema se dalje rjeˇsava na isti naˇcin. 3.. . 7) Slika 6. 3.. tada je preporuˇcljivo poˇceti tako da se upitamo: “Kakvo rjeˇsenje bi dala metoda podijeli-pa-vladaj..velika sortirana lista se dobiva relativno jednostavnim postupkom saˇzimanja malih sortiranih listi.. spomenute metode su se pokazale uspjeˇsne u mnogim situacijama. . . 4) @ merge @ @ (1. Ona se sastoji u tome da zadani problem razbijemo u nekoliko manjih (istovrsnih) problema.1 Sortiranje saˇzimanjem.. (5.2) moˇze se ovako tumaˇciti: .. Zato ´cemo polaznu listu razbiti na dvije manje i svaku od tih manjih listi ´cemo sortirati zasebno ... . U ovom dijelu kolegija razmotrit ´cemo najvaˇznije tehnike: podijeli-pa-vladaj. 7.. U ostatku ovog potpoglavlja slijede tri primjera algoritama oblikovanih u skladu s metodom “podijeli pa vladaj”. smjernica) za oblikovanje algoritama.6 OBLIKOVANJE ALGORITAMA 6.. 3. Nema garancije da ´ce neka od ovih metoda zaista dati korektno rjeˇsenje naˇseg problema . 69 .”.. Mora postojati naˇcin da se problemi dovoljno male veliˇcine rijeˇse direktno (bez daljnjeg razbijanja). 1. Kad ˇzelimo sami oblikovati algoritam za rjeˇsavanje nekog novog problema... itd.. ve´c moˇze biti i pribliˇzno.. Ipak. razbije se u joˇs manje probleme.. 3) sort . (3. ˇsto bi nam dao pohlepni pristup. 7) (1. 3. pa je to dobar razlog da ih bar pokuˇsamo primijeniti.to tek treba provjeriti. divide (1. pohlepni pristup. Dobiveni algoritam je rekurzivan . 6. dinamiˇcko programiranje. ljudi su identificirali nekoliko op´cenitih “tehnika” (metoda. rjeˇsenje ne mora uvijek biti egzaktno.1. 5. tj. itd. 3) . tako da se rjeˇsenje polaznog problema moˇze relativno lako konstruirati iz rjeˇsenja manjih problema.... 4. 4. 4. ..1 Opet sortiranje saˇ zimanjem (merge sort) Algoritam merge sort za sortiranje liste (vidi odjeljak 5. (5.3.ˇsto je lista dulja.. 5. strategija. “Podijeli-pa-vladaj” je moˇzda najprimjenjivija strategija za oblikovanje algoritama.... 7) sort . ...

. 4.. 3.. 2... 6. 8. 4. Znaˇci.... 1.. . 1.. 4.. tada se gornji algoritam moˇze bitno pojednostaviti. 8) .... 2. 6) \ ne \ da \ \ . . ... 2...ako je polazna lista sortirana. konaˇcni odgovor se dobije tako da se parcijalni odgovori kombiniraju logiˇckom operacijom “ili”..70 6. . Podjelu na manje liste provodimo tako da srednja mala lista ima duljinu 1...traˇzena vrijednost se pojavljuje u velikoj listi ako i samo ako se pojavljuje u bar jednoj maloj listi.... 6.2 Traˇ zenje elementa u listi ˇ Zelimo utvrditi da li u zadanoj listi postoji element sa zadanom vrijednoˇs´cu. .. zato treba polaznu listu razbiti na npr.. 8) ? Slika 6.. . 6...1. 4) da Slika 6.. (1.3 Mnoˇ zenje dugaˇ ckih cijelih brojeva Promatramo problem mnoˇzenja dvaju n-bitnih cijelih brojeva X i Y .. dakle njegova sloˇzenost je O(n2) ukoliko . .. to ju je teˇze pretraˇzivati.... 3.. 4. da (3..jedna operacija usporedivanja (zadana vrijednost s elementom u sredini) omogu´cuje da se vrijednost odmah pronade ili da se dvije liste eliminiraju iz daljnjeg razmatranja... 4 ? . 4.... 8) (4... Dobivamo algoritam binarnog traˇzenja (vidi pogl. (3.. OBLIKOVANJE ALGORITAMA 6. 3) (3) \ ne \ ne \ \ .3 Traˇzenje elementa u sortiranoj listi.2 Traˇzenje elementa u listi. Klasiˇcni algoritam (srednja ˇskola) zahtijeva raˇcunanje n parcijalnih produkata veliˇcine n.2). 6..... (1..1.. tri manje. U svakoj maloj listi treba zasebno traˇziti zadanu vrijednost.. ? divide (4. 4 ? . a ostale dvije su podjednake duljine.. ... . .... 4) divide . Metoda “podijeli pa vladaj” sugerira sljede´ce rjeˇsenje: .... 2.. 3.ˇsto je lista dulja. (3.

Znaˇci. Doduˇse.6. m2. C D Y = C 2n/2 + D Slika 6. pove´cao se broj zbrajanja odnosno oduzimanja. poboljˇsanje se zaista osje´ca tek kod izuzetno velikih cijelih brojeva (n ≈ 500). te dva “ˇsifta” (mnoˇzenje s 2n n odnosno 2 2 ).59). Ta skica je zbog ograniˇcenja standardnog tipa int zapravo ispravna samo za male n-ove. Takoder bi sami morali implementirati aritmetiˇcke operacije s tako prikazanim cijelim brojevima. nova verzija algoritma “podijeli-pa-vladaj” je asimptotski brˇza od klasiˇcnog algoritma. Ipak. Pretpostavljamo da je n potencija od 2.. Prema gornjoj formuli. Broj mnoˇzenja n/2-bitnih brojeva se sada smanjio na tri. no to nije vaˇzno jer je rijeˇc o operacijama s manjom sloˇzenoˇs´cu.svaki od brojeva X odnosno Y treba podijeliti na dva dijela koji su duljine n/2 bitova (zbog jednostavnosti uzimamo da je n potencija od 2): X . Rjeˇsenje rekurzije je T (n) = O(nlog2 3 ) = O(n1. /* radimo kao da su X i Y pozitivni */ */ . BC i BD). Slijedi skica algoritma u jeziku C. int mult (int X. C. B. D. Rekurzija za T (n) sada glasi: T (1) = 1. treba napraviti: 4 mnoˇzenja n/2-bitnih brojeva (AC. Y = abs(Y). Znaˇci.. tri zbrajanja brojeva duljine najviˇse 2n bitova (tri znaka +). 4T (n/2) + cn (ovdje je c neka konstanta). /* tri "mala" produkta */ int A. /* lijeve i desne polovice od X i Y */ s = (X>=0?1:-1) * (Y>=0?1:-1). */ int s. moˇzemo pisati sljede´cu rekurziju za ukupan broj koraka T (n) koje implicira gornja formula: T (1) T (n) = = 1. duljine najviˇ se n bitova. Prava implementacija algoritma zahtijevala bi da razvijemo vlastiti naˇcin pohranjivanja cjelih brojeva: npr svaku cjelobrojnu varijablu mogli bi zamijeniti dugaˇckim poljem bitova. . naˇs algoritam dobiven metodom “podijeli-pavladaj” nije niˇsta bolji od klasiˇcnog. Pristup “podijeli pa vladaj” sugerira ovakav algoritam: .. Znaˇci.. /* predznak od X*Y */ int m1.1. int Y. /* Funkcija vra´ ca X*Y. A B X = A 2n/2 + B Y . AD. m3. X = abs(X). Budu´ci da i zbrajanja i ˇsiftovi zahtjevaju O(n) koraka. int n) { /* X i Y su cijeli brojevi s predznakom. Lako se vidi da je rjeˇsenje rekurzije T (n) = O(n2 ).produkt od X i Y se tada moˇze ovako izraziti: n XY = AC2n + (AD + BC)2 2 + BD. METODA “PODIJELI PA VLADAJ” 71 operacije sa 1 bitom smatramo osnovnima.4 Prikaz brojeva duljine n bitova. Doduˇse. poboljˇsanje se moˇze dobiti ukoliko gornju formulu preinaˇcimo tako da glasi: n XY = AC2n + [(A − B)(D − C) + AC + BD] 2 2 + BD. T (n) = 3T (n/2) + cn (ovdje je c konstanta ve´ca nego prije). jedno mnoˇzenje “velikih” n-bitnih brojeva reducirali smo na nekoliko mnoˇzenja “manjih” n/2bitnih brojeva.

. partije. Postupak dinamiˇckog programiranja koji put zahtijeva da rijeˇsimo i neke potprobleme koji nam na kraju ne´ce biti potrebni za rjeˇsenje zadanog problema.2 Dinamiˇ cko programiranje Metoda “podijeli pa vladaj” koji put rezultira neefikasnim algoritmom. D-C. j). za n = 4. U ovakvim situacijama preporuˇca se dinamiˇ cko programiranje. zatim rjeˇsenja za malo ve´ce probleme. j raˇcuna P (i. B = desnih n/2 bitova od X. j) = 0. . D.. Znaˇci. Rezultiraju´ce vrijeme sortiranja je O(n2 ). za i > 0. merge sort je takoder algoritam tipa “podijeli-pa-vladaj”. Npr. ali se polazna lista duljine n dijeli na dvije liste duljine ≈ n/2. m2 = mult(A-B. D = desnih n/2 bitova od Y. j) + 2 P (i. ako je A ve´c dobio 2 poena a B je dobio 1 poen. m1 = mult(A. OBLIKOVANJE ALGORITAMA if (n == 1) if ( (X==1) && (Y==1) ) return s. tako da svaki od njih ima 50% ˇsanse da dobije poen u bilo kojem dijelu igre. n/2). 6. return (s * (m1<<n +(m1+m2+m3)<<(n/2) + m3) ). . Igra je podijeljena u dijelove (setove. Naziv “dinamiˇcko programiranje” potjeˇce iz teorije upravljanja. else { A = lijevih n/2 bitova od X. Naime. C.2.1 Odredivanje ˇ sanse za pobjedu u sportskom nadmetanju Dva sportaˇsa (ili tima) A i B nadme´cu se u nekoj sportskoj igri (disciplini). za i > 0. Pritom ukupan broj razliˇcitih potproblema moˇzda i nije tako velik. Metoda zahtijeva da se svi potproblemi redom rijeˇse. j > 0. ). Vaˇzan je redoslijed ispunjavanja tabele. tada ga ne raˇcunamo ponovo ve´c ga samo proˇcitamo iz tabele. gdje se polazna lista duljine n (koju treba sortirati) podijeli na dvije nejednake liste duljina n−1 odnosno 1. /* ovdje je << operator za ˇ sift bitova ulijevo */ } } Primjetimo na kraju da je za algoritme tipa “podijeli-pa-vladaj” vaˇzno da potproblemi budu dobro izbalansirani (sliˇcnih veliˇcina) . runde. P (i.tada je taj igraˇc pobjednik. deˇsava se da broj potproblema koje treba rijeˇsiti raste eksponencijalno s veliˇcinom zadanog problema. Kad god nam treba neko rjeˇsenje. j) vjerojatnost da ´ce A biti konaˇcni pobjednik. Vidjet ´cemo da je P (2. Za razliku od algoritama tipa “podijeli pa vladaj” koji idu “s vrha prema dolje” (od ve´ceg problema prema manjima). sve dok se ne dosegne veliˇcina zadanog problema. Oznaˇcimo s P (i. algoritmi dinamiˇckog programiranja idu s “dna prema gore”(od manjih prema ve´cem). 6. n/2). prvo se u tabelu unose rjeˇsenja za probleme najmanje veliˇcine.  1. . U svakom dijelu igre toˇcno jedan igraˇc biljeˇzi 1 poen. To se joˇs uvijek viˇse isplati nego rjeˇsavanje istih potproblema mnogo puta. Vrijeme sortiranja za merge sort je O(n log n). tada je i = 2 i j = 3. C = lijevih n/2 bitova od Y. n/2). no jedan te isti potproblem se pojavljuje na mnogo mjesta u rekurziji (pa ga uvijek iznova rjeˇsavamo). Npr. S druge strane. 3) = 11/16.  1 1 2 P (i − 1. Igra traje sve dok jedan od igraˇca ne skupi n poena (n je unaprijed fiksiran) .to ´ce naime osigurati efikasnost. j − 1).72 6. Lako se vidi da vrijedi relacija:  za i = 0. j > 0. j = 0. m3 = mult(B. u situaciji kad A treba joˇs i poena za pobjedu a B treba joˇs j poena. Pretpostavljamo da su A i B podjednalo jaki. itd. insertion sort se moˇze smatrati algoritmom tipa “podijeli-pa-vladaj”. te da se rjeˇsenja spreme u odgovaraju´cu tabelu. Htjeli bi prona´ci algoritam koji za zadane i. else return 0. znaˇci A ima viˇse ˇsanse za pobjedu nego B.. i danas je izgubio svoj prvobitni smisao.

. Oi} uz kapacitet j. . j) inaˇce mu je ta vjerojatnost P (i.. DINAMICKO PROGRAMIRANJE 73 Prva dva reda su oˇcigledna. koji radi nad globalnim poljem P[][]. ˇsto znaˇci da ´ce se P (1. ako A dobije taj poen. .2. Donji red je ispunjen nulama.. . . Npr..0.. 3) i P (2. (i+j). j). P[s][0] = 0.ˇ 6. Kapacitet ranca je c teˇzinskih jedinica. Prethodna relacija moˇze se iskoristiti za rekurzivno raˇcunanje P (i. .. Prethodna rekurzivna formula kaˇze da se bilo koji od preostalih elemenata tabele moˇze dobiti kao aritmetiˇcka sredina elemenata ispod i elemenata udesno.. dobar naˇcin za popunjavanje tabele je da se ide po dijagonalama poˇcevˇsi od donjeg desnog ugla. O2. Bolji naˇcin za raˇcunanje P (i.. 3) i P (2.. u duhu metode “podijeli pa vladaj”.. . . k++) P[k][s-k] = ( P[k-1][s-k] + P[k][s-k-1] )/2. j 0 4 3 2 . Bolji algoritam dobiva se dinamiˇckim programiranjem. .. U uvjetima tre´ceg reda igra se bar joˇs jedan dio igre. pokazuje se da je vrijeme izvrˇsavanja takvog raˇcuna O(2i+j ). } Unutraˇsnja petlja u gornjem potprogramu traje se ponavlja za s = 1. . . 2). On} i izabrao onaj s najve´com vrijednoˇs´cu uz dopustivu teˇzinu. te da ukupna vrijednost bude maksimalna. Znaˇci. dalje P (1. } return P[i][j]. . j) { int s. Algoritam se moˇze zapisati sljede´com C funkcijom. . trebali bi nam P (1. 6. a desni stupac jedinicama.. 2) raˇcunati dvaput. No.. P O(s). k. a vanjska petlja  i+j 2 Dakle. Ovaj problem bi se mogao rijeˇsiti algoritmom tipa “podijeli pa vladaj” koji bi generirao sve mogu´ce podskupove skupa {O1. Oznaˇcimo s Mij maksimalnu vrijednost koja se moˇze dobiti izborom predmeta iz skupa {O1. Razlog za toliku sloˇzenost je taj ˇsto se iste vrijednosti pozivaju (raˇcunaju) mnogo puta.0. O2.5 Sanse za pobjedu u sportskom nadmetanju. . No. k<s. . 1/2 21/32 13/16 15/16 1 4 11/32 1/2 11/16 7/8 1 3 3/16 5/16 1/2 3/4 1 2 1/16 1/8 1/4 1/2 1 1 0 0 0 . ... .. . Uzimamo da su wi (i = 1. float odds(int i. 2. da bi izraˇcunali P (2. . . i 1 0 0 ˇ Slika 6. . s++) { /* raˇ cunaj dijagonalu elemenata sa zbrojem indeksa s */ P[0][s] = 1. . j − 1). 2) oba zahtijevaju P (1. tada mu je vjerojatnost konaˇcne pobjede P (i − 1. takav algoritam bi oˇcito imao sloˇzenost O(2n ). 2). j) je ispunjavanje tabele. u kojem A ima 50% ˇsanse da dobije poen. 2.2. 3).0. Predmet Oi ima teˇzinu wi i vrijednost (cijenu) pi . s<=(i+j).2 Rjeˇ savanje 0/1 problema ranca Zadano je n predmeta O1 . n) i c pozitivni cijeli brojevi. O2. j) sve skupa traje O s=1 s = O (i + j) . ... Prilikom postizavanja . for (s=1. Pitamo se: koje predmete treba staviti u ranac tako da ukupna teˇzina ne prijede c. On i ranac. raˇcunanje P (i.... for (k=1.

p2. dalje gledamo zastavicu uz Mn−1. 0 ≤ j ≤ c.j−wi + pi . Ukoliko je Oi stavljen. j<=c. 6. Algoritam se sastoji od ispunjavanja tabele s vrijednostima Mij . Mij = Mi−1. kovanice) od 50. i<=n.j . for (j=0. float zero one knapsack (int n. Koriste se globalna polja sljede´ceg oblika s oˇciglednim znaˇcenjem. 10. inaˇce.c (odnosno zastavicu uz Mn−1. mora biti dimenzije (m + 1) × (c + 1).74 6. Ukoliko Oi nije stavljen. Redoslijed raˇcunanja je redak-po-redak (j se brˇze mijenja nego i). 7. (p1 .  0. zadani ulazni podaci n = 3.j ili kao Mi−1. i++) M[i][0] = 0. maksimalna vrijednost koja se moˇze nositi u rancu je M3. Ukupna teˇzina je 2 + 4 = 6.0. float p[D1]. Algoritam ispunjavanja tabele zapisat ´cemo sljede´com funkcijom. . 3. (Mi−1. itd.3 “Pohlepni” pristup Zamislimo da radimo u du´canu i da muˇsteriji trebamo vratiti 62 kune. Ona se postiˇze izborom prvog i tre´ceg predmeta. (w1. w3) = (2.6 = 9. if ( j >= w[i] ) if ( (M[i-1][j-w[i]] + p[i]) > M[i-1][j] ) M[i][j] = M[i-1][j-w[i]] + p[i]. j++) M[0][j] = 0. O2.j . } Neka su npr. 4). algoritam trebamo malo usavrˇsiti tako da uz svaki element Mij ˇcuvamo i “zastavicu” (logiˇcku vrijednost) koja oznaˇcava da li je Mij dobiven kao Mi−1. tada je Mij = Mi−1. Zapisana verzija algoritma (tabele) zapravo daje samo maksimalnu vrijednost koja se moˇze ponijeti u rancu. i<=n. Znaˇci. int c) { int i.  max{Mi−1. za j < wi i i > 0. Znaˇci. Zastavica uz Mnc ´ce nam najprije re´ci da li je predmet On upotrebljen u optimalnom izboru.c−wn ) da bismo ustanovili da li je On−1 bio izabran. Na raspolaganju nam stoje apoeni (novˇcanice. OBLIKOVANJE ALGORITAMA Mij . Da bi mogli reproducirati i optimalni izbor.0. Funkcija vra´ca maksimalnu vrijednost koja se moˇze prenijeti u rancu kapaciteta c.j−wi + pi )}. float M[D1][D2].j . j++) { M[i][j] = M[i-1][j]. Vrijeme izvrˇsavanja algoritma je O(nc). tj. p3) = (1. i++) for (j=1. for (i=0. for (i=1. . } return M[n][c]. Oi−1} uz kapacitet j − wi. . tabela treba sadrˇzavati Mij za 0 ≤ i ≤ n. c = 6. w2. tada prije izabrani predmeti predstavljaju optimalni izbor iz skupa {O1. 5 i 1 kune. Ovisno o ne-izboru (odnosno izboru) On. 8). 20. a ne i optimalni izbor predmeta. predmet Oi je stavljen u ranac ili nije. j. Naˇs algoritam tada raˇcuna sljede´cu tabelu Zj iZ 0 1 2 3 0 0 0 0 0 1 0 0 0 0 2 0 1 1 1 3 0 1 7 7 4 0 1 7 8 5 0 1 8 8 6 0 1 8 9 Znaˇci. Mi ustvari traˇzimo Mnc . . int w[D1]. ako se ograniˇcimo na prvih n predmeta. Gotovo instinktivno postupit ´cemo tako da . vrijedi relacija:  za i = 0 ili j ≤ 0. j<=c.

. ....... .... . . Algoritam vra´canja ostatka je funkcionirao samo zahvaljuju´ci specijalnim svojstvima raspoloˇzivih apoena... ....... 6. . .. . “POHLEPNI” PRISTUP 75 vratimo 1 × 50..... .... . .. ....... pi (i = 1... ..3. tako da u svakom koraku saˇzmemo dvije odabrane liste u jednu (uobiˇcajenim algoritmom merge)....6 Optimalno saˇzimanje sortiranih listi...... ... ..... ....... Ne samo da smo vratili toˇcan iznos..... . .. . .... ...... ........ dodajemo ga na listu. ........ .. . Stroga formulacija problema glasi: Zadan je prirodni broj n i pozitivni realni brojevi c. ... .. stavljamo ga u listu za vra´canje.. tada bi pohlepni algoritam najprije izabrao 11 kuna.. .. .. .... . . .. . 6.. ... . .. .. Zanima nas optimalni plan saˇzimanja. . .. . . ako ne stane cijeli predmet tada moˇzemo staviti samo njegov dio. . .. a trebali bismo vratiti 15 kuna.. . .. tj. n). .2. ... .. . ..2)..... ... w2....3. .... ..... 0 ≤ x ≤ 1 (i = 1..... . Nadamo se da ´cemo tako do´ci do “globalno optimalnog” ukupnog rjeˇsenja. . .... .. Rjeˇsenje problema konstruiramo u nizu koraka (faza). ... Postoje problemi kod kojih pohlepni pristup daje korektni algoritam (to onda treba dokazati).. ... .. . 2... ......... . wn. . . ... .... .... . ..... . . . te vra´cenu vrijednost odbijemo od 62 tako da dobijemo 12.. 5 i 1 kuna. .. .. .. korak 2.. ..... No. No sada se predmeti koje stavljamo u ranac mogu “rezati”.... Zatim biramo najve´ci apoen koji ne prelazi 12 kuna (to je 10 kuna).. ... .. ... .. Ovaj problem je bio obraden na vjeˇzbama. Algoritam jednostavno kaˇze sljede´ce: u svakom koraku saˇzimanja treba odabrati dvije najkra´ce liste koje nam stoje na raspolaganju. .. ..... . moˇze se dokazati (metodom binarnih stabala) da ipak ho´cemo. . ... . n) takvi da cenja i i=1 pi xi → max. ... . ........ .. . .. . . ...... . . ... . ... ..... ... .. .... .. . ali predstavlja dobru heuristiku (to onda treba eksperimentalno provjeriti).. Ili drukˇcije reˇceno: svaki korak treba izvesti tako da imamo najmanje posla u tom koraku. . .. . .. . ........ .. ....... n)....... ........ . . . a zatim bi morao 4 puta uzeti po 1 kunu.. . .. .. . . .. . 6..... . ... tj. 2.. Pohlepni pristup ne mora uvijek dovesti do optimalnog rjeˇsenja.. .... .....3.. . . . ... .. .. 12 1. . .... . . .. korak 13 15 19 ... nego smo takoder izabrali najkra´cu mogu´cu listu novˇcanica (4 komada)... ........... takav izbor listi u pojedinom koraku koji ´ce dovesti do najmanjeg ukupnog broja operacija... .. Saˇzimljemo ih u jednu veliku sortiranu listu....2 Rjeˇ savanje kontinuiranog problema ranca Rijeˇc je o problemu koji je sliˇcan 0/1 rancu (vidi pogl... . ..6... .. .. Broj xi kaˇze koliki dio i-tog predmeta stavljamo u ranac... ....... Ovaj algoritam je primjer “pohlepnog” pristupa........ . ... ...... .. ..... .. ...... Algoritam koji smo nesvjesno koristili je bio da izaberemo najve´ci apoen koji ne prelazi 62 kune (to je 50 kuna). . . 1 × 10 i 2 × 1 kuna.1 Optimalni plan saˇ zimanja sortiranih listi Imamo n sortiranih listi s duljinama w1. ... korak 3.. . . .. 25 34 59 Slika 6. Pokazalo se da se optimalni plan moˇze konstruirati “pohlepnim” Huffmanovim algoritmom.. .. ˇsto bi dalo 5 novˇcanica. ... .... Nije sasvim oˇcigledno da ´cemo ovom strategijom zaista posti´ci najmanji ukupni broj operacija.. .... ... 2.. .. . . . . . . . Postoje takoder problemi kod kojih pohlepni algoritam nije sasvim korektan... . . .. ... . . .. .... .... .... U svakom koraku biramo mogu´cnost koja je “lokalno optimalna” u nekom smislu..... .... Saˇzimanje provodimo u n − 1 koraka. . S druge strane... .. . 3 × 5 kuna bi bila kra´ca lista.. . .... n). . .. .. ... ...... n Traˇ z e se realni brojevi x (i = 1.... i i=1 i i Interpretacija zadanih podataka je ista kao u potpoglavlju 6.. Ako bi apoeni bili 11. uz ograniˇ Pn w x ≤ c..... ....... ... . . ... . ... . . wi P (i = 1... ... . 2. . .. itd.

Zbog pretpostavke o P sortiranosti po profitabilnosti n slijedi da je xi = 1 za 1 ≤ i < j. x3) = (0. zbog i=1 wixi = c i yi = xi (1 ≤ i < j) slijedi da je ili yk < xk ili i=1 wiyi > c. } return. promatramo tri mogu´cnosti: Pn 1. #define MAXLENGTH . i<=n. Predmete sortiramo silazno po profitabilnosti. Takoder mora biti i=1 wP i xi = c. Za k < j izlazi da je xk = 1. 3/4). Neka je X = (x1 . . 7. 1.. y2 . yn ) koliko treba da ukupna teˇ Pznina ostane ista. No yk 6= xk pa mora biti yk < xk . Znaˇci. /* dovoljno velika konstanta */ float w[MAXLENGTH]. Znaˇci rjeˇsenje je (x1. a idu´ci po profitabilnosti je 3. void cont knapsack (int n. p2 /w2 = 7/3. . x2. for (i=1. p3 /w3 = 2. . (p1 . OBLIKOVANJE ALGORITAMA Pohlepni pristup rjeˇsavanja problema zahtijeva da za svaki predmet izraˇcunamo njegovu “profitabilnost” pi /wi (tj.. cu = c. a ostatak kapaciteta popunjava s 3/4 tre´ceg predmeta. x[MAXLENGTH]. Za k > j izlazi da je i=1 wi yi > c ˇsto je nemogu´ce. . Moˇzemo uzeti da je i=1 wi yi = c. Zato. zn ) sa svojstvima: zi = xi (1 ≤ i ≤ k). tada je vrijednost ranca oˇcito maksimalna. i<=n. . Zato algoritam smjeˇsta u ranac cijeli 2. Dobivamo funkciju u jeziku C koji radi nad sljede´cim globalnim poljima s oˇciglednim znaˇcenjem. Za k = j. xn) rjeˇsenje generirano naˇsim pohlepnim algoritmom. a maksimalna vrijednost ranca je 13. 8). xi = 0 za j < i ≤ n. w3) = (2. te ih u tom redoslijedu stavljamo u ranac dok god ima mjesta. . najprofitabilniji je 2. } x[i] = 1. Pj Pn 3. 2. predmet. Time dobivamo novo rjeˇsenje Z = (z1 . p[MAXLENGTH]. . . } Promatrajmo rad naˇseg pohlepnog algoritma na podacima iz potpoglavlja 6. Tada se moˇze na´ci najmanji indeks k takav da je xk 6= yk . Pretpostavljamo da su podaci u poljima w[] i p[] ve´c uredeni tako da je p[i]/w[i] >= p[i+1]/w[i+1]. predmet. . Dokaz: Moˇzemo uzeti da je wp11 ≥ wp22 ≥ · · · ≥ wpnn . a zatim da je yk < xk . Zato pretpostavimo da je X 6= Y . Da bi se u to uvjerili. z2 .0. senje jer vrijedi: i=k+1 wi (yi − zi ) = wk (zk − yk ). Ako je X = Y tada smo pokazali da je X optimalan. (w1 . Ako su svi xi jednaki 1. p3) = (1. return. te umanjimo vrijednosti (yk+1 . predmet. vrijednost po jedinici teˇzine). c = 6. x2. 4). Z takoder mora biti optimalno rjeˇ n X pi zi = n X = i=1 n X i=1 i=1 pi yi + (zk − yk )pk − n X (yi − zi )pi i=k+1 pi yi + (zk − yk )wk n X pk pi − (yi − zi )wi wk wi i=k+1 . i++) x[i] = 0. Tvrdnja: opisani pohlepni algoritam zaista daje korektno (optimalno) rjeˇsenje kontinuiranog problema ranca. 3.2. . w2. . Profitabilnosti predmeta su p1 /w1 = 1/2. n Neka je Y = (y1 . i++) { if (w[i] > cu) { x[i] = cu/w[i]. for (i=1. . dakle za n = 3. Tvrdimo najprije da je k ≤ j. . float c) { float cu: int i. Kod svakog stavljanja u ranac nastojimo spremiti ˇsto ve´ci dio predmeta. yn) jedno optimalno rjeˇsenje. cu -= w[i].76 6. p2.. . Uve´cajmo sada yk da postane jednak xk . neka je j najmanji indeks takav da je xj < 1.0. .

... .. .. . . .. .... .... ... ........... . ... ..... . no taj algoritam ne bi morao obavezno davati korektno (tj. . ... ... 2 3 . ...... .. ................... . ..... List stabla predstavlja jednu konkretnu n-torku....... ................. . .. .... 2 3 .... ..... 23.. .. x2 = 2 . 33...... . . ................... .... ...... 2 3 . pa bi (zbog nemogu´cnosti rezanja) mogli dodati joˇs samo 1... Promatrajmo opet primjer iz poglavlja 6.......... ..... ... .. Prostor rjeˇsenja treba zamiˇsljati kao uredeno stablo rjeˇ senja. ....... x2 = 1.. .. Jedan korak algoritma sastoji se od toga da se uzme ˇcvor s vrha stoga.......... .... .. 3}.... .. ........... ... dobili bi suboptimalno rjeˇsenje s vrijednoˇs´cu 8....... ...... ..6. ... ..... ........... . . .... .... .. .. .... .... ......... ..... .. ona mora zadovoljiti joˇs i neka dodatna ograniˇ cenja (ovisna o samom problemu)... .......... .... x2.. . .... ....... itd.... .... . .. ... Dijete korijena predstavlja sve n-torke gdje prva komponenta x1 ima neku odredenu vrijednost. .. .......... ....... ... 13...... .. 3 ...... 2 3 . .. ..... ....... ..... .. Ukoliko ˇcvor nije rjeˇsenje... . Metoda zahtijeva da se traˇzeno rjeˇsenje izrazi kao n-torka oblika (x1......... . . .. ..... .... ....... Kartezijev produkt S1 × S2 × ... Unuk korijena predstavlja sve n-torke gdje su prve dvije komponente x1 i x2 fiksirane na odredeni naˇcin........ predmet..... ... ... ..... 7. ........ ... . . ........... ........ ......... ....... ........... . . . ... ... . ..... . ........2. Npr.... ...... ....... x3=1............. .... . . 15.. .. .... 2 3... .... .. . Backtracking je u osnovi rekurzivni algoritam koji se sastoji od simultanog generiranja i ispitivanja ˇ ˇcvorova u stablu rjeˇsenja.. .. ... ... ...... ... S1 = {1. ...... . =4 ... .. . . ... .... .. ...... .. .... .... . .... ... x2 = 2 ....... .. . .. . ... naˇsli smo novo optimalno rjeˇsenje Z koje se “bolje poklapa” s X nego ˇsto se Y poklapa s X.... . .... ............. . Redoslijed obradivanja ˇcvorova (skidanja sa stoga) vidi se na prethodnoj slici....... . ..... . .................. ..... ... 18.. 4). 26... 3.......... x3=1...............4... ... . . ........... ... . .. . ............. ..... x3=1. ..... S3 = {1. S2 = {1.. . .. 4}.. .. Znaˇci.... ....... ... . ... 27....... ....... .. . .... .. ..... ... . ... x2 = 1. primijetimo da se i za 0/1 problem ranca takoder moˇze definirati sliˇcan pohlepni algoritam. ...... tada se pokuˇsaju generirati njegova djeca te se ona stavljaju na stog.. X je optimalan.... .. ... . .. . . .. tada se poduzme odgovaraju´ca akcija... Slika 6... .... .... x ..... . ......x ........... ..... . ....... . ............ . . . .. ........ . ..... .. ..29 .... ... . . ... . ... 2... ..... . . .......... ....... ......... . ..6..... . 32... .... .. . ..... i=1 Znaˇci... .. 8). . ... 31. x3=1.. .. .... 14... optimalno) rjeˇsenje.. . gdje je xi element nekog konaˇcnog skupa Si .... .. ..... Ukoliko ˇcvor predstavlja rjeˇsenje.... .. .................. x2 = 2 . .......... .... ...... . ....... . w1 w2 # " n n X X pk pi yi + (zk − yk )wk − (yi − zi )wi w k i=1 i=k+1 ≥ n X = n X pk pi yi + 0 · wk i=1 pi yi ............ .. . .. . ... predmet (idu´ci po profitabilnosti) viˇse ne bi stao... . . ... . ........ ... ..... ....... .. 24... . w2..... . . zbog svojstva ≥ ≥ . ... .... ... ....... . 2 3 . ...... . .. 2.. . Time je dokaz teorema zavrˇsen..... ..... . . . .. 2}......... ....... . .. ..5.. ..... .. 6... ..... .... . ..... U poglavlju 6.... . Znaˇci. .. ............. x2 = 1..... . w3) = (2. 7 12 16 21 25 30 ... .... .... ...... ..... x3=1.. ....... . .. . .......... x3=1.. ..... .. . ...... ...... .... ... . ......... ... .. ... .. ... ..20.. . ......7 Stablo rjeˇsenja.....2.. xn)... .............. ... 17.... . ... .... .. ........ .. .... ........ ... ....................... .. . predmet...... . ... . (w1 ..... . . . . .. . 35.. ...... . ... . . Korijen tog stabla predstavlja sve mogu´ce n-torke. . Algoritam poˇcinje tako da na stogu bude samo korijen stabla.... . . ..... .. ... .... .. .............. .......... ... ... ........ ....... . zavrˇsetak je onda kad nademo rjeˇsenje ili kad se isprazni stog...... Nakon toga 3.. . .. 19.. ........... . 3........ ....... 1 .. ........ ... .... ....... ..... .......... ... ....... ...... . . .. × Sn zove se prostor rjeˇ senja.. Cvorovi se stavljaju na stog. (p1. . . .. . . .... p3) = (1........... . ..2 smo pokazali da optimalno rjeˇsenje ima vrijednost 9.............. . . ........ 2 3 ... .... .. ................. ..... Da bi neka konkretna n-torka iz prostora rjeˇsenja zaista predstavljala rjeˇsenje. 36.. .... = 2 x = 3 ..... 8 . .. ....... ............. ..... ......... .. . 28......... ....... Na kraju.... ..... .. . x2 = 1......... .. .. .... .. ..... x3=1. .4. .... . .. . Pohlepni pristup bi zahtijevao da se u ranac najprije stavi “najprofitabilniji” 2. .. . ... .....1 . Iteriranjem ove konstrukcije prije ili kasnije ´cemo do´ci do optimalnog rjeˇsenja koje se u potpunosti poklapa s X. ...... .. .... 2 3 ...... te da se provjeri da li taj ˇcvor predstavlja rjeˇsenje problema................ 22.. .............. ...... ... .......... .... .. .. . 10.... . ..... . ..... .................... . .. . ... ........ . . . ..... .... .... . .... ............11.. ......... dakle c = 6.... 37... BACKTRACKING 77 = ≥ p1 p2 ... x3=1. . . ... ... p2............ ...... . .... ... ... . n = 3..... .... ... ... ..... ... .. .... . 9 .. 1 1 . .................4 Backtracking Backtracking je vrlo op´cenita metoda koja se primjenjuje za teˇske kombinatorne probleme.. .... .... .... .. ....... ..... ... . x1 = 1 ...34... . ....... x2 = 2 . za n = 3... ... ........... . ........ .... Rjeˇsenje problema se traˇzi sistematskim ispitivanjem svih mogu´cnosti za konstrukciju tog rjeˇsenja... . ....... ..... ..

.. xn) mora zadovoljiti da bi zaista bila rjeˇsenje... . . ..... . .... ..... . . .. . .. .. . . .... . .. .... .. . .. . ............. . . ...... . ...... Ograniˇcenja koja rjeˇsenje (x1. . ....... ... . . .. .... . . ...... . ... . ... ....... ...... .. . ..... . ..... . ....... .. .. ... . 1 .. .. . ...... . ....... .... .... ... ... .... .. . .......... . .. . .. .. . x2 = 2. . . .. . ... . . . . .. .. ..... . .. . . ..... ... ... .. ... .... . .. . . ... . ... . .. 2 . . . .. . .. ... . . ... . . .. . ... . .. . . . . .... . tada dotiˇcni ˇcvor ne treba generirati jer ni on ni njegova djeca ne´ce dati rjeˇsenje... . . ....... ...... .. . .. .... .. . ..... ... . ..... . . .. . . . . .. . ... . . ...... . .... .. .. . .. . .. .. . . . .. .. .. . .. .. ... . x2.. .. . .... .. xn) mora zadovoljiti izvode se iz zahtjeva da se nikoje dvije kraljice ne smiju na´ci u istom stupcu niti na istoj dijagonali.. . .. . ...... ... ..... ... ... .. ...... . x2.. . . tada “najljevija” generirana grana stabla postaje ona za x1 = 1. ... .. .... Rjeˇsenje problema se moˇze predoˇciti kao n-torka (x1 ... . 1 x =1 x =2 2 6 x =3 3 x =4 x =4 4 7 x =2 x =1 5 8 x =3 9 Slika 6. ..... . . . .... .. .. ..... ... ........ . ..... u samom postupku generiranja ˇcvorova provjeravaju se ˇ ograniˇcenja koja n-torka (x1 . ... ... .. ... . .... ..... . ... . . . ... .... .. ....8 Stablo rjeˇsenja za problem n kraljica.... ... .... ..... .... .. . ... . . .. . ......... ..... ............. . ... . . .. Rad je ovdje prekinut ˇcim je pronadeno prvo rjeˇsenje........ . . . ..... . ...... ... . . .... ... . . ... .. . .. . ...... ... .. .... .. ... .. . . .... . .. .. . .. ... .... ..... ........ . .. 4 . ... .. . 3.. . ..... ... ..... ... ... . .... . .. ... .... ...... ... .. ...... .. . . .. n} za sve i......... . ....... .. ..... .... .. .. Za n = 4 backtracking generira sljede´ce stablo. . ... .... . .. .... . x2.... . . .. ... . ..1 Rjeˇ savanje problema n kraljica Na ˇsahovsku ploˇcu dimenzije n × n treba postaviti n kraljica tako da se one medusobno ne napadaju.. . . .... ... . . ... .. .. 3 . . ...... 6.... .... ... ... . .. . .. ......... ... .... ... xi fiksirano na odredeni naˇcin... . .. . . . . ... ...... .. ....... ......... .. .. . . .. ... .... ... ..... ... .... ...... ........ ...... .... . . .... .. .... Znaˇci Si = {1. . . ...... ...... . .. .. ...... ...... ...... .... ... ... ..... .. . .. .... . .. . . . .. ...... .. .... .. . . ....... . . ako u kontekstu prethodne slike vrijedi ograniˇcenje da komponente x1.. .. . Sljede´ca slika ilustrira ove iste korake algoritma kao pomake figura na ˇsahovskoj ploˇci. ... .. .... .. .. ... ... Naime.. . ... . .... .. .. ..... .. .. .. .. ..... .... . .. . ..... . . . . . .. 1 . ... .. .. .. . .. ... ..... .. . ....... ... .. ... .. ........ . . ............. ... . . .. . . .. ... ..... ...... .. ......... . .. ...... .. ... . ....... .. ...... .. ... ... ...... . . .... . .. .. .... . ... .... . ... . . x3 = 3.. Zvjezdice oznaˇcavaju mjesta gdje je algoritam pokuˇsao smjestiti kraljicu.. ali je odmah odustao zbog napada druge kraljice... . . .. . .. ........ .. ... . . ... .. .. .. .. ... . . .. ....... .... . ... .. ... .. . . . . .. . ... ....... .. .. . . . . Crtkano su oznaˇceni ˇcvorovi koje je algoritam u postupku generiranja odmah poniˇstio (jer krˇse ograniˇcenja)... . ... . a ukupan broj generiranih ˇcvorova pada na 19. ... . ..... . .. . ... . . . . . .. Cvor na i-tom nivou predstavlja n-torke gdje je prvih i komponenti x1... ... . .... ...... ... . ..... . .. ..... . .... ... . . . 2 ..... ... .. . . . ....... . . .. .. ....... . Zbog toga dobar backtracking algoritam nikad ne generira cijelo stablo rjeˇsenja.. ... . . .. . .. .. .. .. . ....... .. . .... ... .. . Ukoliko se ve´c na osnovu vrijednosti tih i komponenti moˇze utvrditi da ograniˇcenja nisu zadovoljena... . ..... ..... .. . x3 moraju biti medusobno razliˇcite.... ....... . ...... x2..... ... .... .... .. . ... .4. .. .. .. . .. ....... .... . ... .. . . . . . . .. . . ....... .. .... .. .. . . .. ....... .......... . . .. Broj n-torki u prostoru rjeˇsenja je nn . . . . .. . ... ..... 2. . ... .. .. . ... .. .... ... . . .. ..... . . .. Zbog toga moˇzemo uzeti da je i-ta kraljica u i-tom retku... .... .. . . ... ... Npr.. . ... .. ... . .. . .. .. . . ... . . .. . ... . .... . .... . . . . . . . ... ... ... ... .. .. 2 .. .. .... . ... x2. ...... ... . ... . . . . . . . . . Oˇcito svaka kraljica mora biti u posebnom retku ploˇce. .. .. .. ....... ... . . ... .... .. . . . . . ..... .. ... . .... . ..... .. . . . . . . ... .. .. . .. . . .... ... . . .. . .... . . . .. . .. . ...... .. xn)... ........ .. .. . . . . . . .... .. . . ... ....... .. . .... ........ gdje je xi indeks stupca u kojem se nalazi i-ta kraljica. ....... .. . . . ve´c “reˇze” one grane (podstabla) za koje uspije utvrditi da ne vode do rjeˇsenja. ... .. .. . .... . . . .. ...... . ..... . .. ... ..78 6..... .. . ... .... .... ... . ... . . .. . ..... ..... ........ ... . . . . .... ... . . . ... .. .. ... ..... . . . .... .. .. .... .. .. . ... .... OBLIKOVANJE ALGORITAMA Veliˇcina prostora rjeˇsenja raste eksponencijalno s veliˇcinom problema n... .. . . .. . .. .... ... .......... . .. . ..

troˇsak.2. i++) if ( (x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k)) ) return 0.. .6. . Optimalnost se mjeri funkcijom cilja koju treba minimizirati odnosno maksimizirati. dobitak.. x2. else { /* promatraj sljede´ ci redak (kraljicu) */ k++.. /* vrati se u prethodni redak */ } } Backtracking se ˇcesto koristi za probleme optimizacije. . Takva varijanta backtracking algoritma obiˇcno se naziva branch-and-bound.. /* k je teku´ ci redak. k=1. Slijedi precizni zapis backtracking algoritma za problem n kraljica u jeziku C. ta funkcija cilja intepretira se kao cijena. itd. xn) oblika #define MAXLENGTH . x[1]=0. for (i=1. Ovisno o primjeni.9 Koraci algoritma za problem n kraljica. zarada. /* nadi stupac */ if (x[k] <= n) /* stupac za kraljicu je naden */ if (k == n) /* rjeˇ senje je kompletirano */ .. } void queens (int n) { int k. i<k. . Funkcija queens( ) ispisuje sva rjeˇsenja problema.. BACKTRACKING 79 1 1 1 * * 2 1 2 3 * * 2 2 * 1 1 * * * * 1 1 * * 3 * 2 2 3 * * * * 4 Slika 6. x[k] je teku´ ci stupac */ while (k > 0) { /* ponavljaj za sve retke (kraljice) */ x[k]++. Vidjeli smo da u stablu rjeˇsenja uvijek treba rezati one grane koje ne vode do rjeˇsenja. Dakle. int place (int k) { /* pretpostavljamo da elementi polja x s indeksima */ /* 1. . while ( (x[k]<=n) && (place(k)==0) ) x[k]++. /* 0-ti element polja se ne koristi! */ Najprije slijedi pomo´cna logiˇcka funkcija place( ) koja kaˇze da li se k-ta kraljica moˇze postaviti u k-ti redak i x[k]-ti stupac tako da je ve´c postavljene 1.. . Pretpostavljamo da postoji globalno polje za smjeˇstanje rjeˇsenja (x1...ispis. Kod problema optimizacije mogu se takoder rezati i one grane koje ne vode do boljeg rjeˇsenja (u odnosu na ono koje ve´c imamo).. od svih rjeˇsenja traˇzimo samo ono koje je optimalno u nekom smislu. } else k--..k ve´ c imaju zadane vrijednosti */ int i. ..4. x[k]=0.2. .(k-1)-va kraljica ne napadaju. /* dovoljno velika konstanta */ int x[MAXLENGTH]. return 1..

(c. Cijena puta je zbroj cijena odgovaraju´cih bridova. (b. c). Za uspjeh branch-and-bound algoritma takoder je vaˇzno da se ˇsto prije otkrije “dobro” rjeˇsenje. . y) uzrokovalo da x (ili y) ima viˇse od dva incidentna brida u konfiguraciji. 1} za sve i. (a. ˇsto znaˇci da svaki brid dobiva svoj redni broj izmedu 1 i m. e). ako je n broj vrhova a m broj bridova. tako da za svaki vrh grafa pribrojimo cijenu dvaju njemu incidentnih bridova iz ciklusa. (b. OBLIKOVANJE ALGORITAMA Uzmimo zbog konkretnosti da rjeˇsavamo problem minimizacije. tada je m = n(n − 1)/2. .4. Ukoliko ta donja ograda izade ve´ca od cijene najboljeg trenutno poznatog rjeˇsenja tada se dotiˇcno podstablo moˇze izbaciti iz razmatranja jer ono ne vodi do boljeg rjeˇsenja. dakle kao binarno. Stablo rjeˇsenja izgleda kao na slici 6. To opet daje sljede´ca pravila za provjeru prilikom generiranja ˇcvorova stabla: . tada (x. e). kao cijena koju ˇzelimo minimizirati. x2. d). y) mora biti ukljuˇcen.Ako bi ukljuˇcenje brida (x. e}. . (d. Time je svaki brid iz ciklusa . c). 6. e). npr. tada (x. y) mora biti iskljuˇcen. (a. d). . y) zatvorilo ne-Hamiltonov ciklus u konfiguraciji. Dakle. Potpuni graf je onaj u kojem postoji brid izmedu bilo koja dva vrha. 3  a  7 2  e  6  b  3 4 4 8 5  d  6  c  Slika 6. (b.. . Graf na slici zadaje jedan konkretan primjerak problema trgovaˇckog putnika za n = 5 i m = 10.80 6. Znaˇci Si = {0. b). (a. y) mora biti iskljuˇcen. Broj m-torki u prostoru rjeˇsenja je 2m . Uzmimo da su imena vrhova elementi nekog dobro uredenog skupa.Ako bi ukljuˇcenje brida (x. . Rjeˇsenje problema se moˇze predoˇciti kao m-torka (x1 .10 Primjerak problema trgovaˇckog putnika. Uobiˇcajena heuristika je da se pri obradi ˇcvorova-bra´ce prednost daje onom koji ima manju donju ogradu. Hamiltonov ciklus je kruˇzni put u grafu koji prolazi svakim vrhom grafa toˇcno jednom. . Primijetimo da cijenu zadanog Hamiltonovog ciklusa moˇzemo raˇcunati kao sumu. Treba prona´ci Hamiltonov ciklus s minimalnom cijenom. tada (x.11. Ograniˇcenja koja rjeˇsenje (x1. {a.2 Rjeˇ savanje problema trgovaˇ ckog putnika Zadan je potpuni neusmjereni graf ˇcijim bridovima su pridruˇzene “cijene”. x2. d. e). Bridove tada moˇzemo poredati leksikografski: (a. xm ) mora zadovoljiti svode se na to da dotiˇcna konfiguracija bridova mora predstavljati Hamiltonov ciklus. . Funkcija cilja tada se interpretira npr.Ako bi iskljuˇcenje brida (x. xm ) gdje je xi logiˇcka vrijednost koja kaˇze da li je i-ti brid ukljuˇcen ili nije. b. . c. d). Jedan ˇcvor u stablu rjeˇsenja predstavlja sve konfiguracije bridova gdje su neki odredeni bridovi “obavezni” a neki drugi odredeni bridovi su “zabranjeni”. (c. y) uˇcinilo nemogu´cim da x (odnosno y) ima bar dva incidentna brida u konfiguraciji. Za realizaciju branch-and-bound algoritma potreban nam je postupak odredivanja donje ograde za cijenu po svim rjeˇsenjima iz zadanog pod-stabla.

b) i s (a. Npr.6. za graf sa slike 6. pa rezultat dobivamo dijeljenjem ukupnog zbroja s 2. x1 =1 Svi Hamiltonovi ciklusi Q Q Q Q x1 =0 Q Q Q Q Hamiltonov ciklus s (a. cikl.za svaki vrh x nademo dva najjeftinija brida u grafu koji su incidentni s x te zbrojimo cijene tih bridova.5 → 18 (zbog cjelobrojnosti).10 donja ograda bi izaˇsla (5 + 6 + 8 + 7 + 9)/2 = 17. dobivene za pojedine vrhove.“male” sume. . b) % x2 =1 % % % % Hamilt.4. . BACKTRACKING 81 uraˇcunat dvaput.“veliku” sumu podijelimo s 2. zbrojimo zajedno u “veliku” sumu. c) . Na osnovu ove primjedbe dobivamo sljede´ci postupak raˇcunanja donje ograde za cijenu bilo kojeg Hamiltonovog ciklusa: . s (a.

C .

C .

C .

cikl. b) iskljuˇcen i (a. za podstablo gdje je (a. U svaki ˇcvor na slici 6. ostali upisani .10. bez (a. b) % x2 =1 % % % % Hamilt. bez (a.11 Stablo rjeˇsenja za problem trgovaˇckog putnika. te zahtjevi na ukljuˇcenost odnosno iskljuˇcenost nekih bridova. c) ukljuˇcen. y) iskljuˇcen. Na svakom nivou stabla uvodi se zapravo samo jedan novi zahtjev. . tada njegovu cijenu treba uraˇcunati u “male” sume vrhova x i y. b) no s (a. b) no bez (a. Na osnovu svih ovih ideja mogu´ce je konstruirati backtracking algoritam za rjeˇsavanje problema trgovaˇckog putnika. Pronalazi se optimalni Hamiltonov ciklus (a. tada njegovu cijenu ne smijemo uraˇcunati u “malu” sumu vrha x odnosno y. c. d.5 → 19. s (a. c)  C  C  C  C Hamiltonov ciklus bez (a.ako je brid (x. C S S x =0 S 2 S S Hamilt. cikl. c)  C  C  C  C e e x2 =0 e e e Hamilt. donja ograda bi izaˇsla (6 + 7 + 8 + 7 + 9)/2 = 18. tada postupamo sliˇcno kao gore. a) sa cijenom 19. Npr. Ukoliko ˇzelimo precizniju donju ogradu za cijenu Hamiltonovog ciklusa koji pripada odredenom podstablu iz stabla rjeˇsenja. e. cikl. Za konkretni graf sa slike 6. no uzimamo u obzir ve´c fiksiranu ukljuˇcenost odnosno iskljuˇcenost nekih bridova: . b. ˇstoviˇse njegovu branch-and-bound varijantu.12 upisano je njegovo ime (veliko slovo).12. Zahtjevi iz nadredenog ˇcvora se prenose i na sve podredene ˇcvorove. algoritam generira stablo prikazano slikom 6.ako je brid (x. pripadna donja ograda. c)  C  C  C  C Slika 6. y) ukljuˇcen. bez obzira da li je on jeftin ili nije. b) i bez (a.

no oni samo pribliˇzno rjeˇsavaju postavljeni problem optimizacije. Rjeˇsenje koje oni daju obiˇcno nije optimalno. Taj redoslijed je posljedica naˇse heuristike da se prije razgraduje onaj brat koji ima manju donju ogradu. d) (d. b) # T # T # T # # T 18.5 E (a. c) (a.5 Lokalno traˇ zenje Lokalno traˇzenje je strategija za rjeˇsavanje problema optimizacije. c) (c. d) (b. te se zbog toga moramo zadovoljiti pribliˇznim rjeˇsenjem. e) (b. e) moraju biti iskljuˇceni zbog pravila 2. d) Ham. abecda cijena: 21 Ham. OBLIKOVANJE ALGORITAMA zahtjevi su posljedica naˇsih pravila. to jest sve dok ne dobijemo teku´ce rjeˇsenje u ˇcijoj okolini nema boljeg rjeˇsenja. d) (d. Npr.5 (a. cikl. u smislu da se mogu dobiti nekom jednostavnom transformacijom teku´ceg. e) (b.82 6. Postupak se nastavlja dok god je mogu´ce. b) i (a. Lokalno traˇzenje primjenjuje se za teˇske kombinatoriˇcke probleme. d) (a. e) (b. dakle skup dopustivih rjeˇsenja koja su “blizu” teku´cem. e) (b. d) (a. c) (b. d) (a. e) H HH zaboravlja se zbog I H H HH H L 18. c) (a.12 Stablo generirano backtracking algoritmom za rjeˇsavanje problema trgovaˇckog putnika. . d) (a. Cvorovi su imenovani u redoslijedu njihovog nastajanja. e) (a. e) (a.5 17. d) (c. A B D 17.5 (bez zahtjeva) H  HH   H  H HH   H C 18. e) (c. e)  reˇze se nakon otkri´ca I     G F 18 18 (a. e) (c. ili bar rjeˇsenje koje je bolje od teku´ceg. ali je bolje od polaznog. acebda cijena: 23 ‘najbolje do sada’ ukupno najbolje Slika 6. u ˇcvoru D se originalno zahtijeva da bridovi (a. d) (c. e) (d. e) (d. d) (a. d) (b. d) i (a. Promatramo okolinu (susjedstvo) teku´ceg rjeˇsenja. acbeda cijena: 19 Ham. e) (c. b) S S S S 20. c) (a. c) 23 J (a. d) (a.5 M 23. e) (c. Ona zahtijeva da u svakom trenutku raspolaˇzemo jednim dopustivim rjeˇsenjem problema. Algoritmi dobiveni strategijom lokalnog traˇzenja relativno su su brzi. cikl. gdje raˇcunanje stvarno optimalnog rjeˇsenja iziskuje previˇse vremena. c) ˇ budu ukljuˇceni no onda nuˇzno (a. 6. Izabrano rjeˇsenje proglaˇsava se novim teku´cim.5 K 21 (a. d) (b. cikl. cikl. To teku´ce rjeˇsenje nastoji se poboljˇsati. c) (b. e) (a. Biramo najbolje rjeˇsenje iz okoline. e) (b.5 (a. e) aa H HH zaboravlja se zbog I aa reˇze se nakon otkri´ca I aa H H aa HH a H I H P N (b. c) (c. e) (b. abceda cijena: 23 Ham.

5.13. ponovo promatramo primjerak problema trgovaˇckog putnika sa slike 6. b. Broj iteracija i toˇcnost rjeˇsenja teˇsko je predvidjeti. LOKALNO TRAZENJE 6. e.ˇ 6. t t e1 t t t t e2 t t t t t t t f1 f2 t t t Slika 6.5. a) sa cijenom 3 + 4 + 5 + 6 + 7 = 25. Kao polazno rjeˇsenje promatramo Hamiltonov ciklus (a. 2-opt algoritam pamti bilo koji Hamiltonov ciklus kao teku´ce rjeˇsenje. Kao konkretni primjer rada 2-opt algoritma. . gdje je n broj vrhova u grafu.10. U 2-okolini pronalazi se ciklus s najmanjom cijenom. Primijetimo da u 2-okolini teku´ceg ciklusa postoji n(n − 1)/2 − n = n(n − 3)/2 ciklusa.1 83 2-opt algoritam za problem trgovaˇ ckog putnika Kao primjer algoritma zasnovanog na lokalnom traˇzenju promatramo takozvani 2-opt algoritam za rjeˇsavanje problema trgovaˇckog putnika. Cijenu puta u grafu raˇcunamo kao zbroj cijena pripadnih bridova. d. on postaje novi teku´ci i algoritam se nastavlja. c. Ako taj ciklus ima manju cijenu od teku´ceg. dva od n bridova duˇz ciklusa moˇzemo izabrati na n(n − 1)/2 naˇcina. Naime.14.vidi sliku 6.13 Generiranje 2-okoline teku´ceg Hamiltonovog ciklusa. Znaˇci opet promatramo potpuni neusmjereni graf ˇcijim bridovima su zadane cijene. Jedna iteracija 2-opt algoritma izvrˇsava se u vremenu O(n2 ). Promatra se takozvana 2okolina teku´ceg ciklusa: nju ˇcine svi Hamiltonovi ciklusi koji se dobivaju iz teku´ceg izbacivanjem dvaju ne-susjednih bridova i umetanjem odgovaraju´cih “unakrsnih” bridova . Inaˇce je algoritam zavrˇsen i on kao rjeˇsenje daje zadnji teku´ci ciklus (za njega kaˇzemo da je 2-optimalan). 2-okolina tog rjeˇsenja sadrˇzi n(n − 3)/2 = 5 ciklusa ˇciji izgled i cijene se vide na slici 6. Traˇzimo Hamiltonov ciklus s minimalnom cijenom. no n takvih izbora ne vrijedi jer su bridovi susjedni. no oˇcito je da obje stvari bitno ovise o izabranom polaznom rjeˇsenju.

a  7 .

e  4 .

d  cijena: 27 6 .

b  4 6 .

c  3 .

a  .

e  3 .

a  7 .

e  2 5 .

d  cijena: 21 3 4 5 .

d  cijena: 21 6 .

b  4 .

c  .

b  .

c  .

a  7 .

e  2 8 5 .

d  cijena: 29 .

a  .

e  3 3 8 .

d  cijena: 23 6 .

b  4 .

. b. c  Slika 6. a) za graf sa slike 6. c. e.14 2-okolina Hamiltonovog ciklusa (a. d.10.

b  6 .

c  .

3 . a) sa cijenom 21. c. e. OBLIKOVANJE ALGORITAMA Novo teku´ce rjeˇsenje je npr (a. d. U okolini novog teku´ceg ciklusa nalazi se optimalno rjeˇsenje (a. b. Algoritam kre´ce u drugu iteraciju.15. Zato ´cemo u drugoj iteraciji dobiti to optimalno rjeˇsenje kao tre´ce teku´ce. d. c. b. prikazano na slici 6.84 6. Algoritam ´ce zavrˇsiti rad nakon tre´ce iteracije. e. a) sa cijenom 19.

a  .

e  2 6 4 .

d  .

b  4 .

i. r-okolina se sastoji od svih Hamiltonovih ciklusa koji se u r od n bridova razlikuju od teku´ceg.u[(imax+1)%n]). Dakle preuredi polje u[] na odgovaraju´ ci naˇ cin . */ float d. } } if (dmax > 0) . 1.. jmax = j. e.u[0]). r-opt algoritam pretraˇzuje r-okolinu teku´ceg Hamiltonovog ciklusa. . */ /* Pronalazi se 2-optimalni Hamiltonov ciklus. pove´canjem r dobivamo sve toˇcniji no vremenski sve zahtjevniji algoritam. jmax. ..u[n-1]). */ /* ... int u[ ]) { /* Promatramo potpuni graf s vrhovima 0. j<=(i==0?n-2:n-1)... void twoOpt (float cost[ ][SIZE].u[(jmax+1)%n]) s bridovima (u[imax]]. c. b. j.u[1]).10. Op´cenito. (u[1]. (u[n-1]. d. Eksperimenti pokazuju da se 4-opt algoritam ve´c ne isplati: naime on je znatno zahtjevniji no ne bitno toˇcniji od 3-opt. j++) { d = cost[u[i]][u[(i+1)%n]] + cost[u[j]][u[(j+1)%n]] . te se on zapisuje */ /* kao niz vrhova u elemente u[0].. a) za graf sa slike 6. . . imax = i. } Algoritam 2-opt je najjednostavniji ˇclan porodice r-opt algoritama za r ≥ 2. i++) for (j=(i+2). Svi ovi u[i] su razliˇ citi. Jedna iteracija r-opt algoritma zahtijeva vrijeme O(nr ). } while (dmax > 0). j.cost[u[(i+1)%n]][u[(j+1)%n]]. */ /* Element cost[i][j] sadrˇ zi cijenu brida izmedu vrhova i. if (d > dmax ) { dmax = d.u[2]).u[(jmax+1)%n]]. dakle neki njeni dijelovi su opisani rijeˇcima. u[n-1]. i<=n-3. (u[(imax+1)%n].. (u[jmax]. Funkcija je samo skicirana.. int imax. U praksi se najˇceˇs´ce koriste: brzi 2-opt i precizniji 3-opt algoritam.cost[u[i]][u[j]] . n-1.. c  Slika 6. for (i=0. Znaˇci. /* Teku´ ci ciklus sastoji se od bridova (u[0]. te bi ih trebalo razraditi do kraja. dmax. . Polje u[] je */ /* inicijalizirano tako da prikazuje poˇ cetni Hamiltonov ciklus.15 Jedan ˇclan 2-okoline ciklusa (a. u teku´ cem ciklusu zamijeni bridove (u[imax]. Algoritam 2-opt se moˇze realizirati sljede´com C funkcijom. . gdje je SIZE pogodna globalna konstanta. */ do { dmax = 0. int n. u[1].u[jmax]).. (u[n-2].

s time da se ograniˇcavamo na jednostavne transformacije oblika 1. d) s teˇzinom 92 prikazan na sredini slike 6. Svakom bridu (u. Taj zadnji raspored je lokalno optimalan za skup transformacija oblika 1.16. v) koja se tumaˇci kao “broj P ˇzica” izmedu komponenti u i v. L(e) = 24. R(e) = 0. To je i sve ˇsto moramo raditi u jednoj iteraciji. Imamo L(d) = 13.vj )∈E |i − j| · w(vi . Izvadi komponentu vi i umetni je izmedu vj i vj+1 za neke i i j. Ako se ograniˇcimo na transformacije oblika 1. Ve´c izraˇcunate L(i) i R(i) treba aˇzurirati samo onda kad se vi zamijeni s vi−1 ili vi+1 .16 Tri dopustiva rjeˇsenja istog primjerka problema linearnog rasporeda. moˇzemo upotrijebiti rekurziju oblika L(1) = 0. Primjenjujemo algoritam lokalnog traˇzenja.2 85 Traˇ zenje optimalnog linearnog rasporeda Kao drugi primjer algoritma zasnovanog na lokalnom traˇzenju. e. d. te sliˇcnu rekurziju za R(i)-ove. U svrhu konkretnog primjera. vi+1) odnosno R(i + 1) + w(vi . a skup bridova s E. Zamijeni susjedne komponente vi i vi+1 . n) tako da ukupna duljina potrebnih ˇzica bude minimalna.5. Vrhovi iz V zovu se “komponente”. vj ). L(i) = L(i − 1) + w(vi−1. Htjeli bi prona´ci pogodnu numeraciju v1 . Dakle testiranje svih n − 1 transformacija te aˇzuriranje L(i)-ova i R(i)-ova za odabranu transformaciju zahtijeva vrijeme O(n). b. Naime. ˇciji skup vrhova je oznaˇcen s V . e) = −5. Zamijeni bilo koje dvije komponente vi i vj . c. Drugim rijeˇcima. 2. vj ).16 desno. . Mijenjamo d i e pa dobivamo bolji raspored (a. 1. vi+1). c. 2. to jest L(j) = k=1 w(vk . pretpostavimo da graf sa slike 6. b) ima teˇzinu 84. Zadan je neusmjereni graf G. e. 3. . Razmatramo zamjenu d i e. Analiziramo vremensku sloˇzenost jedne iteracije opisanog algoritma.5. .10. Aˇzuriranje je jednostavno: na primjer kod zamjene vi s vi+1 novi L(i) odnosno R(i) je L(i + 1) − w(vi . R(d) = 6. koji je prije predstavljao primjerak problema trgovaˇckog putnika. Dakle L(d)−R(d)+ R(e) − L(e) + 2 · w(d. Ipak. Inicijalizacija L(i)-ova i R(i)-ova na poˇcetku algoritma takoder se moˇze obaviti u vremenu O(n). b. Neka je L(j) zbroj teˇzina bridova koji idu nalijevo od Pj−1 Pn vj .ˇ 6. . . vj ) bude minimalna. . v) ∈ E pridruˇzena je teˇzina w(u. Taj raspored sa sredine slike moˇzemo joˇs poboljˇsati zamjenom c s e. e. 2 7 4 a 3 b 8 4 c 5 d 6 e 6 4 4 a 3 b 5 4 c 3 3 7 8 e 7 6 d a 3 b 6 3 e c 5 d 4 6 2 8 6 2 Slika 6.16 lijevo. d. on nije globalno optimalan jer raspored (a. d) s teˇzinom 91 prikazan na slici 6. b. htjeli bi prona´ci raspored komponenti u linearno organiziranom ormaru (sastavljenom od ladica 1. c. vi+1 ) negativno. izloˇzit ´cemo algoritam za traˇzenje optimalnog linearnog rasporeda. . sada predstavlja primjerak problema linearnog rasporeda. e) ima teˇzinu 97 i prikazan je na slici 6. ˇcime odobivamo raspored (a. LOKALNO TRAZENJE 6. tada postoji samo n − 1 transformacija koje treba razmotriti. vn vrhova takvu da (vi . . Zamjena susjednih komponenti donosi smanjenje teˇzine ukoliko je L(i) − R(i) + R(i + 1) − L(i + 1) + 2 · w(vi . Polazni raspored (a. Algoritam lokalnog traˇzenja za problem linearnog rasporeda kre´ce od proizvoljnog linearnog rasporeda kao od polaznog rjeˇsenja. Sliˇcno. v2 . c. Okolina teku´ceg rjeˇsenja istraˇzuje se tako da se na teku´ci raspored primjenjuju transformacije sljede´ceg oblika. neka je R(j) = k=j+1 w(vk . . vi ).

Manjkavost je ilustrirana slikom 6.86 6. a kao okolina te populacije promatraju se rjeˇsenja koja se mogu dobiti kombiniranjem ili mutiranjem rjeˇsenja iz populacije. primijetimo da je osnovna manjkavost lokalnog traˇzenja u tome ˇsto ono moˇze “zaglaviti” u lokalnom optimumu koji se po vrijednosti funkcije cilja jako razlikuje od pravog (globalnog) optimuma. poput tabu search ili simulated annealing.zaglavljivanje u lokalnom optimumu. Velik broj teku´cih rjeˇsenja kod evolucijskog algoritma smanjuje opasnost zaglavljivanja u lokalnom optimumu.17 Manjkavost lokalnog traˇzenja . Evolucijski (genetiˇ cki) algoritmi mogu se interpretirati kao multiplicirana varijanta lokalnog traˇzenja. . gdje se umjesto jednog rjeˇsenja pamti cijela “populacija” rjeˇsenja. 6funkcija cilja f(x) (traˇzimo minimum) j  H  s s lokalni optimum globalni optimum -x Slika 6. Novije varijante strategije lokalnog traˇzenja.17. OBLIKOVANJE ALGORITAMA Na kraju ovog poglavlja. sadrˇze dodatna pravila kojima se nastoji pobje´ci iz lokalnog optimuma.

1987. Thompson Course Technology... 2nd edition. Computer Algorithms / C++. Data Structures and Algorithms in C++. W.H. [5] Horowitz E. Prentice-Hall. Boston MA. 2004. and Applications in C++. 2000. 2006. Englewood Cliffs NJ. 2nd edition. Leung B.R. Mount D. Hopcroft J. 2nd edition... Tamassia R. Sahni S. AddisonWesley.R. 1996. Silicon Press. Data Structures and Algorithm Analysis in C++. New York. and Internet Examples..Foundations. 2006. Analysis. [6] Horowitz E. Data Structures and Program Design in C . [8] Hubbard J. 1986. 1992. Schaum’s Outline Series. Computer Science Press. New York. [12] Preiss B.T. Tondo... Data Structures. Silicon Press..L. Summit NJ.. Mastering Algorithms with C .P.D. Freeman & Co. [11] Loudon K. New York.. Data Structures and Algorithms. Reading MA.. Data Structures and Algorithms with Object-Oriented Design Patterns in C++.E. Reading MA. Fundamentals of Data Structures in C++. 1997. 3rd edition. 2nd edition. Data Structures. McGraw-Hill. 1999. New York. [3] Goodrich M. Schaum’s Outline of Data Structures with C++.Literatura [1] Aho A. Algorithm Design . John Wiley & Sons. Data Structures and Algorithms in C++. C. Tamassia R.. Anderson-Freed S. [13] Sahni S. John Wiley & Sons. [2] Drozdek A.. New York.. O’Reilly...... [10] Lipschutz S.. [7] Horowitz E.. New York. Fundamentals of Data Structures in C. Sahni S.. Rajasekaran S. 2002.V... Algorithms. [9] Kruse R.T. New York. 2004. Ulman J. Mehta D. McGraw-Hill. 3rd edition.. Summit NJ. John Wiley & Sons. Sahni S.A. Addison-Wesley.. 2004. Sebastopol CA. 1999. 87 . [4] Goodrich M.L.. [14] Weiss M..

Sign up to vote on this title
UsefulNot useful