Dijagnostika i održavanje raĊunala

autori:
Tomislav Hoško, dipl.ing.
dr.sc. Miroslav Slamić
urednik:
dr.sc. Miroslav Slamić
naslov:
Strukture podataka i algoritmi
stručni recezent:
dr.sc. Miroslav Slamić
lektorica:
Ankica Tomić
grafički urednik:
Krešimir Pletikosa, ACE
nakladnik:
Algebra d.o.o., 2009.
za nakladnika:
mr.sc. Mislav Balković
mjesto i godina izdavanja:
Zagreb, 2009
Sva prava pridržana. Niti jedan dio ove
knjige ne smije se reproducirati ili prenositi
u bilo kojem obliku, niti na koji način.
Zabranjeno je svako kopiranje, citiranje te
upotreba knjige u javnim i privatnim
edukacijskim organizacijama u svrhu
organiziranih školovanja, a bez pisanog
odobrenja nositelja autorskih prava.
Copyright © Algebra d.o.o.
CIP zapis dostupan u računalnom katalogu
Nacionalne i sveučilišne knjižnice u Zagrebu
pod brojem 710180
ISBN 978-953-7390-49-5
Sadržaj:
1. Poglavlje: ..... UVOD ..................................................................................................................................................................... 3
1.1
Uvod ................................................................................................................................................................................ 4
1.2
Temeljni pojmovi .............................................................................................................................................................. 4
1.3
GraĎevni elementi strukture podataka .............................................................................................................................. 5
2. Poglavlje: ..... ALGORITMI I SLOŽENOST ................................................................................................................................... 7
2.1
Algoritmi ........................................................................................................................................................................... 8
2.1.1
Povijest algoritma ........................................................................................................................................................ 8
2.1.2
Definicija...................................................................................................................................................................... 9
2.1.3
Primjeri algoritama ...................................................................................................................................................... 9
2.1.4
Zapisivanje algoritama u pseudokodu i C++ kodu ...................................................................................................... 10
2.1.5
NP - teški problemi .................................................................................................................................................... 12
2.1.6
Učinkovitost algoritma ............................................................................................................................................... 12
2.2
Sloţenost algoritama ...................................................................................................................................................... 13
2.2.1
Uvod.......................................................................................................................................................................... 13
2.2.2
Analiza algoritma ....................................................................................................................................................... 13
2.2.3
Veliko O .................................................................................................................................................................... 14
2.2.4
Veliko omega ............................................................................................................................................................ 18
2.2.5
Veliko theta ............................................................................................................................................................... 19
2.2.6
Zaključak ................................................................................................................................................................... 19
3. Poglavlje: ..... Rekurzija ............................................................................................................................................................. 20
3.1
Uvod .............................................................................................................................................................................. 21
3.2
Temeljna ideja rekurzije.................................................................................................................................................. 21
3.2.1
Glavne karakteristike i implementacija ....................................................................................................................... 22
3.2.2
Korištenje rekurzije .................................................................................................................................................... 23
3.2.3
Jednostavni primjer konstrukcije rekurzivnog algoritma ............................................................................................. 24
3.2.4
Sloţenost rekurzije .................................................................................................................................................... 24
3.2.5
Poznatiji rekurzivni algoritmi ...................................................................................................................................... 25
4. Poglavlje: ..... Jednostavne strukture podataka ....................................................................................................................... 29
4.1
Uvod .............................................................................................................................................................................. 30
4.2
Liste ............................................................................................................................................................................... 30
4.2.1
Lista kao apstraktni tip podataka ............................................................................................................................... 30
4.2.2
Implementacija liste pomoću polja ............................................................................................................................. 31
4.2.3
Implementacija liste pomoću pokazivača ................................................................................................................... 38
4.2.4
Dvostruko povezana lista........................................................................................................................................... 43
4.3
Stog ............................................................................................................................................................................... 46
4.3.1
Stog kao apstraktni tip podataka................................................................................................................................ 47
4.3.2
Implementacija stoga pomoću polja ........................................................................................................................... 47
4.3.3
Implementacija stoga pokazivačima .......................................................................................................................... 49
4.4
Red ................................................................................................................................................................................ 53
4.4.1
Red kao apstraktni tip podataka ................................................................................................................................ 54
4.4.2
Implementacija reda cirkularnim poljem ..................................................................................................................... 54
4.4.3
Implementacija reda pokazivačima ............................................................................................................................ 61
5. Poglavlje: ..... Složene strukture podataka ............................................................................................................................... 65
5.1
Stabla............................................................................................................................................................................. 66
5.1.1
Obilazak stabla .......................................................................................................................................................... 70
5.2
Binarno stablo ................................................................................................................................................................ 88
5.2.1
Binarno stablo kao apstraktni tip podataka ................................................................................................................ 90
5.2.2
Implementacija binarnog stabla pomoću polja ........................................................................................................... 90
5.2.3
Implementacija binarnog stabla pomoću pokazivača ................................................................................................. 95
5.3
Hrpa (heap) .................................................................................................................................................................... 98
5.3.1
Prioritetni red ............................................................................................................................................................. 98
5.3.2
Implementacija prioritetnog reda hrpom ................................................................................................................... 100
6. Poglavlje: ..... Algoritmi za pretraživanje ................................................................................................................................ 107
6.1
Uvod ............................................................................................................................................................................ 108
6.2
Linearno ili slijedno traţenje ......................................................................................................................................... 108
6.3
Binarno traţenje ........................................................................................................................................................... 109
7. Poglavlje: ..... Algoritmi za sortiranje ...................................................................................................................................... 113
7.1
Uvod ............................................................................................................................................................................ 114
7.2
Sortiranje izborom elementa (selection sort) ................................................................................................................. 115
7.3
Sortiranje zamjenom susjednih elemenata (bubble sort)............................................................................................... 117
7.4
Sortiranje umetanjem (insertion sort) ............................................................................................................................ 122
7.5
Sortiranje hrpom (heap sort) ......................................................................................................................................... 123
7.6
Shell sort ...................................................................................................................................................................... 125
7.7
Rekurzivni algoritmi ...................................................................................................................................................... 130
7.7.1
Merge sort ............................................................................................................................................................... 130
7.7.2
Quick sort ................................................................................................................................................................ 133
8. Poglavlje: ..... Tehnike adresiranja .......................................................................................................................................... 137
8.1
Uvod ............................................................................................................................................................................ 138
8.2
Tablice s direktnim adresiranjem .................................................................................................................................. 138
8.3
8.3.1
8.3.2
8.4
8.4.1
8.4.2
8.4.3
8.5
8.5.1
8.5.2
8.5.3
8.6
Hash tablice ................................................................................................................................................................. 139
Uklanjanje kolizija ulančavanjem ............................................................................................................................. 140
Uklanjanje kolizija korištenjem preljevnih područja................................................................................................... 141
Hash funkcije................................................................................................................................................................ 141
Metoda dijeljenja ..................................................................................................................................................... 142
Metoda mnoţenja .................................................................................................................................................... 142
Metoda univerzalnog hashiranja .............................................................................................................................. 143
Otvoreno adresiranje .................................................................................................................................................... 143
Linearno isprobavanje ............................................................................................................................................. 145
Kvadratno isprobavanje ........................................................................................................................................... 146
Dvostruko hashiranje ............................................................................................................................................... 147
Primjena hash funkcija u kriptografiji ............................................................................................................................ 148
8. Poglavlje: Tehnike adresiranja
U ovom poglavlju naučiti ćete:



Brzo pronalaţenje podataka po zadanom ključu
Kako se realiziraju hash tablice
OdreĎivanje adresa za zadane ulazne ključeve
Str.138§
8.1
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
Uvod
Puno je različitih aplikacija koje zahtijevaju dinamičke strukture koje podrţavaju samo tzv. rječničke
operacije, kao što su INSERT, SEARCH i DELETE. Na taj način, primjerice, prevoditelji za
programske jezike odrţavaju simboličke tablice u kojima su ključevi elemenata stringovi koji
odgovaraju ključnim riječima programskog jezika. Cijeli postupak adresiranja temelji se na tzv.
ključevima koji predstavljaju poziciju našeg elementa u tablici.
Jedna od učinkovitih struktura za implementaciju rječnika su hash (raspršene) tablice. Traţenje
elementa u hash tablici moţe zahtijevati najviše O(n) vremena koliko treba za traţenje elementa u
povezanoj listi. Po odreĎenim pretpostavkama moguće je ostvariti traţenje u hash tablici s
očekivanim vremenom O(1). Moţemo reći da je hash tablica generalizacija jednostavnog polja.
Direktno adresiranje unutar jednostavnog polja moţe nam osigurati učinkovito pronalaţenje
odgovarajuće pozicije u polju za O(1) vremena. Spomenuto direktno adresiranje posebno je
primjenjivo kada moţemo rezervirati toliki prostor za polje da za svaki ključ imamo jednu poziciju.
MeĎutim, kada je broj stvarno pohranjenih ključeva relativno manji od ukupnog broja mogućih
ključeva, hash tablice učinkovitija su alternativa za polja s direktnim adresiranjem, jer hash tablice
tipično koriste veličinu polja proporcionalnu broju stvarno spremljenih ključeva. Umjesto da se
ključevi kao indeksi polja koriste direktno, indeksi polja izračunavaju se iz ključa.
8.2
Tablice s direktnim adresiranjem
Direktno adresiranje predstavlja jednostavnu tehniku koja dobro radi kada je skup ključeva S
razumno malen. Uzmimo da aplikacija treba dinamički skup u kojem svaki element ima ključ koji je
nastao iz skupa S = {0,1,….,m-1}, gdje m nije prevelik. Osim toga, pretpostavlja se da dva
elementa nemaju isti ključ. Za prikaz takvog dinamičkog skupa koristimo polje ili tablicu s direktnim
adresiranjem T[0..m-1], u kojoj svaka pozicija ili pretinac odgovaraju ključu iz skupa S. Na slici je
ilustriran takav slučaj, ali podaci nisu direktno u tablici, već imamo tzv. satelitske podatke s
ključem. Ako u skupu nema elementa s ključem k, tada je T[k]= NIL = Ø .
T
S (skup svih ključeva)
. . .. . .
. .
. .
0
1
0
/
1
ključ
2
2
3
3
9
6
4
/
7
2
3
/
5
4
5
8
K (stvarni ključevi)
/
6
/
7
8
/
tel: 01 2222 182, e-mail: [email protected]
satelitski
podatak
5
8
9
§www.racunarstvo.hr§
Str.139§
§STRUKTURE PODATAKA I ALGORITMI
Tzv. rječničke operacije su trivijalne:
DIRECT-ADRESS-SEARCH(T,k)
return T[k]
DIRECT-ADRESS-INSERT(T,x)
T[krey[k]] ← x
DIRECT-ADRESS-DELETE(T,x)
T[krey[k]] ← NIL
Traţenje u tablici s direktnim adresiranjem
Ubacivanje u tablicu s direktnim adresiranjem
Brisanje iz tablice s direktnim adresiranjem
Svaka od ovih operacija je brza i zahtijeva samo O(1) vremena.
Za neke aplikacije elementi u dinamičkom skupu mogu biti pohranjeni u direktno adresiranoj tablici
direktno, a ne preko satelitskih podataka. To je bolje nego da pospremamo ključ elementa i
satelitski podatak s informacijom do kojeg pristupamo preko pokazivača. Na taj način moţemo
element pospremiti direktno u pretinac i tako uštedjeti na prostoru.
8.3
Hash tablice
U radu s direktnim adresiranjem mogu se javiti poteškoće, i to više njih. Primjerice, ako je skup S
mogućih ključeva velik, tada pospremanje tablice T veličine |S| moţe biti nepraktično ili čak
nemoguće zbog memorijskih ograničenja računala. Kako skup K ključeva koji su stvarno
pospremljeni moţe biti relativno malen u odnosu na skup svih ključeva S, tada imamo previše
neiskorištenog, a rezerviranog prostora unutar tablice T.
Kada je skup K pohranjenih ključeva u rječniku puno manji od skupa S svih mogućih ključeva, tada
hash ili raspršene tablice zahtijevaju puno manje prostora za pohranu od tablica s direktnim
adresiranjem. Posebno, zahtjevi za pohranu mogu se reducirati na red ϴ(|K|), iako traţenje
elementa u hash tablici i dalje zahtijeva samo O(1) vremena.
Kod direktnog adresiranja element s ključem k pospremljen je u pretinac k. Kod hash tablica taj
element je pospremljen u pretinac h(k), pri čemu se hash funkcija h koristi za računanje pretinca
iz ključa k. U ovom slučaju funkcija h mapira cjelokupni prostor S ključeva na skup pretinaca iz
hash tablice T[0 .. m-1], što se moţe zapisati i na sljedeći način:
h: S → {0, 1, …., m-1}
Tada kaţemo da se element s ključem k hashira na slot h(k) ili često da je h(k) hash vrijednost
ključa k. Osnovna ideja je prikazana na sljedećoj slici.
Zagreb – Ilica 242
§Visoka
škola za primijenjeno računarstvo
§
Str.140§
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
T
/
0
/
S (skup svih ključeva)
h(k1)
.. .
. .
k1
k4
h(k4)
k5
/
k3
k2
h(k2) = h(k5)
K (stvarni ključevi)
/
/
h(k3)
/
m-1
Jedini problem koji se pojavljuje kod ovako dobre ideje za realizaciju hash tablice mogućnost je da
dva ključa nakon primjene hash funkcije mogu zauzimati isti pretinac, tj. dolazi do kolizije. Sva
sreća, razvijene su jako dobre tehnike za rješavanje konflikata izazvanih kolizijama. Naravno,
idealno bi bilo izbjegavati kolizije. To moţemo pokušati postići izborom dobre hash funkcije h.
Jedna od ideja moţe biti da h bude “slučajna“, pa da ili izbjegnemo koliziju ili njihov broj bitno
smanjimo.
U nastavku ćemo objasniti nekoliko učinkovitih tehnika za rješavanje problema kolizija.
8.3.1
Uklanjanje kolizija ulančavanjem
Kod ulančavanja sve elemente koji se hashiraju na isti pretinac stavljamo u povezanu listu, kako
to prikazuje slika u nastavku. U tom slučaju pretinac j sadrţi pokazivač na glavu liste svih
pospremljenih elemenata koji se hashiraju na pretinac j. Ako takvih elementa nema, pretinac j
sadrţi NIL.
T
/
/
S (skup svih ključeva)
.. . .
.
. . .
k1
k4
k2
k6
k5
k7
k3
k4
k5
k2
/
k7
/
/
k8
K (stvarni ključevi)
k1
k3
/
/
/
k8
k6
/
/
tel: 01 2222 182, e-mail: [email protected]
§www.racunarstvo.hr§
Str.141§
§STRUKTURE PODATAKA I ALGORITMI
Operacije nad hash tablicom T, kod koje se kolizije rješavaju ulančavanjem, jednostavne su za
implementaciju i glase:
CHAINED – HASH - SEARCH(T,k)
Traţenje elementa s ključem k u listi T[h(k)]
Ubacivanje elementa x na početak liste
T[h(key[x])]
Brisanje elementa x iz liste T[h(key[x])]
CHAINED - HASH - INSERT(T,x)
CHAINED - HASH - DELETE(T,x)
Najgori slučaj za vrijeme ubacivanja je O(1). Za pretraţivanje, najgori slučaj vremena izvoĎenja
proporcionalan je duljini liste, tj. O(n) ako lista sadrţi n elemenata. Da bismo u praksi izbjegli da
nam liste budu predugačke, izborom hash funkcije moţemo ostvariti jednostavno uniformno
(jednoliko) hashiranje, tj. da svaki pretinac ima pribliţno isti broj elemenata u listi.
8.3.2
Uklanjanje kolizija korištenjem preljevnih područja
Jedan od načina rješavanja kolizija je korištenje preljevnog područja. Uz primarno područje hash
tablica sadrţi i dodatno preljevno područje koje je u pravilu znatno manje od primarnog. Naravno,
izbor tih dvaju područja mora biti što bliţi optimalnom, s jedne strane da moţemo riješiti sve
moguće kolizije i s druge strane da nam veličina ukupno rezerviranog prostora ne naraste previše.
Kada dodajemo novi element i on doĎe u koliziju zbog zauzetog pretinca, tada ključ spremamo u
prvo slobodno mjesto u preljevnom području (na slici vidimo primjer kada je ključ j u prvom
pokušaju došao u koliziju s ključem k, jer je h(k) = h(j), te je stoga ključ j pospremljen u prvi
slobodni pretinac u preljevnom području). Ako je pretinac u preljevnom području već zauzet, idemo
na sljedeći dok ne naĎemo slobodni pretinac. Moguća su i rješenja s višestrukim preljevnim
područjima ili uvoĎenjem potpuno drugog mehanizma za upravljanje preljevnim područjem, no to
izlazi iz okvira ove skripte.
k
0
h(k)
j
k
o
Primarno
područje
0
h(i)
i
o
0
i
j
0
8.4
o
Preljevno
područje
Hash funkcije
Razmotrit ćemo osnovna pitanja realizacije dobrih hash funkcija i prikazati tri načina njihova
kreiranja:
 hashiranje dijeljenjem
 hashiranje mnoţenjem
 univerzalno hashiranje
Zagreb – Ilica 242
§Visoka
škola za primijenjeno računarstvo
§
Str.142§
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
Dobra hash funkcija prije svega treba udovoljiti kriteriju jednostavnog uniformnog hashiranja. U tom
slučaju svaki ključ ima jednaku vjerojatnost da će se hashirati na bilo koji od m pretinaca.
Pretpostavimo da je svaki ključ proizašao nezavisno iz skupa S, sukladno nekoj funkciji
vjerojatnosti P, gdje je P(k) vjerojatnost pojave ključa k. Teorijski je ovaj problem teško riješiti jer
vrlo rijetko poznajemo funkciju distribucije P. Stoga češće pribjegavamo heurističkim tehnikama
kreiranja hash funkcija koje u statističkome smislu funkcioniraju dobro.
Druga vaţna stvar za kreiranje hash funkcija jest pretpostavka da je skup S ključeva iz skupa
N={0, 1, 2, …} prirodnih brojeva. Ako ključ nije prirodan broj, moramo pronaći način kako ga
interpretirati kao prirodni broj. Primjerice, ključ koji je string moţe se interpretirati kao cjelobrojni
broj. String AB je sastavljen od cjelobrojnih vrijednosti (65, 66) na temelju ASCII skupa znakova.
8.4.1
Metoda dijeljenja
Kod metode dijeljenja za kreiranje hash funkcije, mapiramo ključ k u jedan od m pretinaca
uzimanjem ostatka dijeljenja ključa k s m. U tom slučaju hash funkcija glasi:
h(k) = k mod m
Npr., ako hash tablica ima m=15 pretinaca i ključ je k=66, tada je h(k) = 6. Kako ova metoda
zahtijeva samo jednu operaciju dijeljenja, moţemo reći da je ona zaista brza.
Potrebno je posvetiti paţnju izboru broja m koji ne bi trebao biti potencija broja 2, jer ako je m=2p,
tada h(k) poprima samo p najniţih bitova ključa k. Naime, bolje je da hash funkcija ovisi o svim
bitovima ključa. TakoĎer, treba izbjegavati da m bude potencija broja 10 ako aplikacija radi s
decimalnim brojevima kao ključevima, jer se tada moţe dogoditi da hash funkcija ne ovisi o svim
decimalnim znamenkama ključa.
Najbolje je za vrijednost m birati prost ili prim broj koji nije preblizu stvarnoj potenciji broja 2. Na
primjer, pretpostavimo da ţelimo alocirati hash tablicu, kod koje se kolizija rješava ulančavanjem,
da bismo čuvali n = 2000 stringova znakova, pri čemu je jedan znak 8 bita (1 byte). Ako
pretpostavim da ne trebamo imati više od 3 ispitivanja kod neuspješnog traţenja, tada nam treba
hash tablica veličine m = 701. Ovaj broj je izabran kao prim broj najbliţi odnosu α = 2000/3, a
istodobno nije blizak nijednoj potenciji broja 2. U tom slučaju, ako svaki ključ smatramo
cjelobrojnim brojem, hash funkcija glasi H(k) = k mod 701.
8.4.2
Metoda množenja
Metoda mnoţenja za kreiranje hash funkcije radi u dva koraka. Prvo, pomnoţimo ključ k
konstantom A, izabranom iz području 0 < A< 1 i izdvojimo decimalni dio (frakcijski) od produkta
k*A. Tada pomnoţimo tu vrijednost s m i zaokruţimo rezultat. Jednostavno rečeno, hash funkcija
glasi:
h(k) = floor[ m(k*A mod 1) ]
gdje „ k*A mod 1“ znači decimalni dio od k*A, takav da je k*A – floor[k*A].
Prednost ove metode u tome je da izbor za m više nije kritičan. Premda ta metoda radi s bilo kojom
vrijednosti konstante A, za neke vrijednosti ipak radi bolje. Optimalan izbor ovisi o svojstvima
podataka koji se trebaju hashirati. Knuth je razmatrao taj problem izbora konstante A i pokazao da
sljedeća konstanta jako dobro radi:
A ≈ (sqrt (5) -1)/2 = 0.6180339887….
tel: 01 2222 182, e-mail: [email protected]
§www.racunarstvo.hr§
Str.143§
§STRUKTURE PODATAKA I ALGORITMI
Primjer:
Ako imamo ključ k= 123456 i zadan je m = 10000, a konstanta A je uzeta kako je prethodno
predloţeno, tada dobijemo:
h(k)
= floor(10000*(123456*0.61803…mod 1))
= floor(10000*(76300.0041151… mod 1))
= floor(10000*0.0041151..)
= floor(41.151…)
= 41
8.4.3
Metoda univerzalnog hashiranja
Ako zlonamjerni korisnik bira ključeve koji će se hashirati, tada moţe odabrati da se svih n ključeva
hashira u isti pretinac, zbog čega je srednje vrijeme dohvata ϴ(n). Gotovo svaka fiksna hash
funkcija ranjiva je na takav tip ponašanja. Jedini način za izbjegavanje takvih situacija izbor je hash
funkcije slučajno, tako da ona bude neovisna o ključevima koji će stvarno biti pospremljeni u
tablicu. Taj pristup se zove univerzalno hashiranje i u prosjeku ima dobre performanse, bez obzira
na to kakvi su ključevi odabrani. U najkraćim crtama, hash funkcija se bira slučajno u trenutku
izvršenja programa za hashiranje, iz paţljivo dizajnirane klase funkcija, no tom se metodom
nećemo detaljnije baviti.
8.5
Otvoreno adresiranje
Kod otvorenog adresiranja svi se elementi pospremaju u hash tablicu sami po sebi. U tom slučaju
svaki ulaz tablice sadrţi ili element iz dinamičkog skupa ili NIL. Kada traţimo element, mi sustavno
istraţujemo pretince tablice dok ne pronaĎemo element ili se ne uvjerimo da ga nema u tablici. U
ovom slučaju nemamo ni liste ni elemente pospremljene van tablice, kao kod ulančavanja. Kako
kod otvorenog adresiranja hash tablica moţe biti napunjena tako da više nijedno umetanje ne bude
moguće, faktor opterećenja α ne smije prijeći 1. Naravno, moglo bi se započeti s pospremanjem u
povezanu listu radi ulančavanja unutar hash tablice, ali prednost otvorenog adresiranja i u tome je
da se izbjegnu bilo kakvi pokazivači. Umjesto toga, izračunava se niz pretinaca koji će se ispitivati.
Za umetanje uporabom otvorenog adresiranja, uspješno ispitujemo ili isprobavamo hash tablicu
dok ne naĎemo prazan pretinac u koji umećemo ključ. Umjesto da imamo fiksni poredak od 0,
1,…,m-1 (što zahtijeva O(n) vremena traţenja), niz pozicija koje moraju biti isprobane ovisi o
ključevima koji su već umetnuti.
Realizacija umetanja uporabom otvorenog adresiranja ostvaruje se uzastopnim isprobavanjima
hash tablice dok se ne naĎe prazan pretinac u koji se umetne ključ. S otvorenim adresiranjem za
svaki ključ niz proba
(h(k,0), h(k,1), …,h(k,m - 1))
ostvaruje se permutiranjem od (0, 1, …, m - 1), tako da je svaka pozicija hash tablice moguć
pretinac za novi ključ kako se tablica puni. Sljedeći pseudokod ilustrira operaciju umetanja uz
pretpostavku da su elementi u hash tablici T ključevi bez satelitskih (dodatnih) informacija, tj. ključ
k je identičan elementu koji sadrţi ključ k. Svaki pretinac sadrţi ili ključ ili NIL (ako je pretinac
prazan).
Zagreb – Ilica 242
§Visoka
škola za primijenjeno računarstvo
§
Str.144§
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
HASH-INSERT (T,k)
1 i←0
2
repeat j ←h(k,i)
3
if T[j] = NIL
4
then T[j] = ← k
5
return j
6
else i ← i + 1
7
until i = m
8 error "hash tablica je puna"
Algoritam za traţenje ključa k izvodi probavanje istog niza pretinaca koji je algoritam za umetanje
realizirao kada je ključ k bio umetan. Zato algoritam traţenja moţe biti završen (neuspješno) kada
je pronaĎen bilo koji prazan pretinac jer je ključ k trebao biti umetnut baš ondje i nigdje drugdje u
nizu isprobavanja.
HASH-SEARCH (T,k)
1 i←0
2
repeat j ←h(k,i)
3
if T[j] = k
4
then return j
5
i←i+1
6
until T[j] = NIL or i = m
7 return NIL
Još treba naglasiti da je brisanje elementa u hash tablicama s otvorenim adresiranjem prilično
teško, jer ne moţemo pretinac i, u kojem ţelimo obrisati ključ, jednostavno postaviti na NIL jer tako
ne bismo mogli dohvatiti bilo koji ključ k za vrijeme čijeg umetanja smo isprobali pretinac i, te ga
našli zauzetog. Jedno od rješenja je da ga označimo vrijednošću DELETED umjesto NIL, no u tom
se slučaju moraju modificirati procedure HASH - SEARCH i HASH - INSERT.
Nadalje, pretpostavit ćemo tzv. uniformno (jednoliko) umetanje u hash tablicu, što znači da svaki
ključ ima jednaku vjerojatnost realizacije bilo koje od m! permutacija niza za isprobavanje {0, 1, …,
m – 1}. Treba naglasiti da se vrlo teško postiţe pravo uniformno adresiranje, pa se u praksi postiţe
uglavnom aproksimacija uniformnog umetanja u hash tablicu.
Od tehnika koje se koriste za izračunavanje niza za isprobavanje, potrebnog za otvoreno
adresiranje, poznate su tri metode:
 linearno isprobavanje
 kvadratno isprobavanje
 dvostruko hashiranje (isprobavanje)
Sve tri tehnike jamče da su (h(k,0), h(k,1), …,h(k,m - 1)) permutacije iz skupa (0, 1, …, m - 1) za
svaki ključ k. Dvostruko hashiranje moţe imati najviše isprobavanja, ali, što je očekivano, postiţe i
najbolji rezultat.
tel: 01 2222 182, e-mail: [email protected]
§www.racunarstvo.hr§
Str.145§
8.5.1
§STRUKTURE PODATAKA I ALGORITMI
Linearno isprobavanje
Za zadanu funkciju h': U → {0, 1, …, m – 1}, metoda linearnog isprobavanja koristi sljedeću hash
funkciju:
h(k, i) = (h' (k) + i ) mod m
za svaki i = 0, 1, …, m – 1. Za zadani ključ k prvi isprobani pretinac je T[h' (k)]. Sljedeći isprobavani
pretinac bio bi T[h' (k) + 1] i tako dalje do pretinca T[m - 1]. Nakon toga se prebacujemo na pretince
T[0], T[1], … dok konačno ne isprobamo pretinac T[h' (k) - 1]. Kako pozicija početne probe
odreĎuje cijeli niz isprobavanja, samo m različitih nizova isprobavanja koristi se kod linearnog
isprobavanja.
Linearno je isprobavanje jednostavno za realizaciju, ali se susreće s problemom poznatim kao
primarni klastering, tj. punjenjem tablice stvaraju se klasteri ili nakupine zauzetih adresa, pa se
povećava broj neuspješnih proba.
Primjer:
Potrebno je umetnuti niz ključeva 5, 22, 11, 3, 8, 27, 33, 45, 9, 28 u tablicu T[] s 12 pretinaca. Hash
funkcija za linearno isprobavanje glasi:
h(k, i) = (3*k + i ) mod m
gdje je m = 12, i = 0, 1, …, 11.
Nakon hashiranja dobije se sljedeća hash tablica:
0
1
2
3
4
5
6
7
8
9
10
11
T[]
8
28
5
33
45
22
9
11
3
27
Iz donje tablice vidimo koliko je za koji ključ bilo potrebno isprobavanja, pri čemu su tamnosivom
nijansom označene konačne adrese. Vidimo da su za tri ključa trebala 2 isprobavanja, za dva
ključa trebala su 3 isprobavanja, a za jedan ključ čak 5 isprobavanja.
ključevi
i - isprobavanje
plus 0
plus 1
plus 2
plus 3
plus 4
Zagreb – Ilica 242
5
22
11
3
6
9
3
8
adrese
9
0
10
27
33
45
9
28
9
10
11
3
4
3
4
5
3
4
5
6
7
0
1
§Visoka
škola za primijenjeno računarstvo
§
Str.146§
8.5.2
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
Kvadratno isprobavanje
Tehnika kvadratnog isprobavanja koristi hash funkciju sljedećeg oblika:
h(k, i) = (h' (k) + c1 i + c2i2 ) mod m
gdje je (kao i kod linearnog isprobavanja) h' pomoćna hash funkcija, c1 i c2 ≠ 0 su pomoćne
konstante, a i = 0, 1, …, m – 1. Početna isprobana pozicija je T[h' (k)], kasnije isprobavane pozicije
su odreĎene kvadratom broja i. Ova metoda radi puno bolje od linearnog isprobavanja, ali da bi se
ostvarila punua uporaba hash tablice, vrijednosti c1, c2 i m su ograničene. Ako dva ključa imaju
istu početnu poziciju isprobavanja, tada je njihov niz isprobavanja isti jer h(k 1, 0) = h(k2, 0) povlači
da je h(k1, i) = h(k2, i). To dovodi do takozvanog sekundarnog klasteringa, tj. takoĎer se
povećava broj neuspješnih proba.
Primjer:
Potrebno je umetnuti niz ključeva 77, 44, 26, 98, 7, 48, 34, 49, 29, 13 u tablicu T s 12 pretinaca.
Hash funkcija glasi:
h(k, i) = (2*k + 1*i2 ) mod m
gdje je m = 12, c1 = 0, c2 = 1, i = 0, 1, …, 11.
Nakon odreĎivanja adresa tehnikom kvadratnog isprobavanja dobije se sljedeća hash tablica:
0
1
2
3
4
5
6
7
8
9
10
11
T[]
48
7
49
44
26
13
98
34
77
29
Iz tablice u nastavku vidimo koliko je za koji ključ bilo isprobavanja, pri čemu su tamnosivom
nijansom označene konačne adrese. Vidimo da su za četiri ključa trebala 2 isprobavanja, a za dva
ključa 3 isprobavanja, što je bolji rezultat nego kod linearnog isprobavanja.
tel: 01 2222 182, e-mail: [email protected]
§www.racunarstvo.hr§
Str.147§
§STRUKTURE PODATAKA I ALGORITMI
ključevi
i - isprobavanje
0
1
2
3
4
8.5.3
77
44
26
10
4
4
5
98
7
Adrese
4
2
5
8
48
34
49
29
13
0
8
9
2
3
10
11
2
3
6
Dvostruko hashiranje
Dvostruko hashiranje je jedna od najboljih metoda dostupnih za otvoreno adresiranje. Permutacije
koje se generiraju imaju vrlo bliska svojstva tzv. slučajno izabranim permutacijama. Dvostruko
hashiranje koristi hash funkciju oblika
h(k, i) = (h1 (k) + ih2(k) ) mod m
gdje h1 i h2 predstavljaju pomoćne hash funkcije. Početna pozicija isprobavanja je T[h1 (k)], a
ostale nastavne pozicije isprobavanja odreĎene su s h2(k) i dijeljenjem po modulu m. Kod ove
tehnike niz isprobavanja, nakon početnog, varira dva puta za ključ k (kao što pokazuje slika).
k
0
h(k)
j
k
o
h1(j)
0
h(i)
i
o
0
i
j
o
h2(j)
0
Primjer:
Potrebno je umetnuti niz ključeva 7, 98, 58, 77, 79, 48, 14, 49, 29, 83 u tablicu T[] s 12 pretinaca.
Hash funkcije za dvostruko hashiranje glase
h1(k) = k mod m
h2(k) = 1 + (k mod m')
gdje je m = 12, m' = 11, i = 0, 1, …, 11.
Zagreb – Ilica 242
§Visoka
škola za primijenjeno računarstvo
§
Str.148§
§8. POGLAVLJE: TEHNIKE ADRESIRANJA
Nakon izvršenog adresiranja dvostrukim hash funkcijama, hash tablica glasi:
0
1
2
3
4
5
6
7
8
9
10
11
T[]
48
49
98
79
14
77
7
29
58
83
Iz tablice u nastavku vidimo koliko je za koji ključ bilo isprobavanja, pri čemu su tamnosivom
nijansom označene konačne adrese. Vidimo da je samo za tri ključa trebalo napraviti dvostruko
hashiranje kroz jedno isprobavanje, što je puno bolji rezultat i od linearnog i od kvadratnog
isprobavanja, ali je lošije što se tiče performansi jer koristimo dvije hash funkcije. Primjer je
pokazao da su svojstva dvostrukog hashiranja vrlo blizu performansama “idealnog“ uniformnog
hash adresiranja.
ključevi
hash funkcija
h1, i=0
i *h2, i=1
i *h2, i=2
i *h2, i=3
8.6
7
98
58
7
2
10
77 79
adrese
5
7
3
48
14
49
29
83
0
2
4
1
5
8
11
Primjena hash funkcija u kriptografiji
Pored tipične primjene hash tablica za pohranu ključeva radi brzog pretraţivanja, vrlo je česta
primjena i u kriptografiji. Proces kriptiranja informacija je proces pretvorbe informacije iz njezina
normalnog čitljivog prikaza u potpuno nečitljiv niz koji je moguće pročitati samo uz posebna znanja.
Jedan od pristupa je korištenje hash funkcija koje omogućuju korištenje jednosmjernih algoritama
koji, primijenjeni na jedinstvene ulaze (poruke) promjenjive duljine, uvijek daju jedinstven izlaz
jedinstvene fiksne duljine, nazvan hash. Naravno, kod hash algoritama poţeljno je da uopće nema
kolizija, mada neki algoritmi mogu imati kolizije za različite ulaze.
Od poznatijih algoritama za kriptiranje spomenut ćemo neke: SHA (Secure Hash Algorithm), MD5
(Message-Digest algorithm 5), CRC (Cyclic Redundancy Check) itd. Svaki od tih algoritama je
posebno područje koji izlazi izvan domene ovog kolegija, te ih stoga nećemo objašnjavati.
Kao primjer ipak istaknimo kriptiranje lozinke (password) za nekog korisnika.
Korisničko ime (user name)
Lozinka (password)
Jsmith
mypass
tel: 01 2222 182, e-mail: [email protected]
§www.racunarstvo.hr§
Str.149§
§STRUKTURE PODATAKA I ALGORITMI
Korisničko ime (user name)
Kriptirana lozinka (password)
Jsmith
5yfRRkrhJDbomacm2lsvEdg4GyY=
Ako imamo samo jedno slovo razlike u lozinci, rezultat hashiranja bit će potpuno drukčiji:
Tekstualni oblik lozinke (password)
Kriptirana lozinka (password)
Mypass
5yfRRkrhJDbomacm2lsvEdg4GyY=
mypast
hXdvNSKB5Ifd6fauhUAQZ4jA7o8=
Za različite algoritme uzima se različiti broj bitova za hashiranje, npr. MD5 (128 bitova) ili SHA-1
(160 bitova). Naravno, što je veći broj bitova, to je puno teţe probijanje kriptiranih podataka
“golom“ snagom računala jer hash algoritmi nisu reverzibilni, tj. nije moguće iz kriptirane
informacije otkriti kako glasi hash funkcija, pa je jedini način proboja isprobavanje brojnih
kombinacija.
Zagreb – Ilica 242
§Visoka
škola za primijenjeno računarstvo
§