80
UNIVERZA V MARIBORU FAKULTETA ZA NARAVOSLOVJE IN MATEMATIKO Oddelek za matematiko in računalništvo DIPLOMSKO DELO Mateja Oletič Maribor, 2010

DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

UNIVERZA V MARIBORU

FAKULTETA ZA NARAVOSLOVJE IN MATEMATIKO

Oddelek za matematiko in računalništvo

DIPLOMSKO DELO

Mateja Oletič

Maribor, 2010

Page 2: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju
Page 3: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

UNIVERZA V MARIBORU

FAKULTETA ZA NARAVOSLOVJE IN MATEMATIKO

Oddelek za matematiko in računalništvo

Diplomsko delo

BAZNA DREVESA

Mentor: Kandidatka:

red. prof. dr. Aleksander Vesel Mateja Oletič

Maribor, 2010

Page 4: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

Zahvala

"Zmagovalec boste, če se nikoli ne boste predali. Ko vam je najtežje,

poskusite še enkrat." - James J. Corbett

Zahvaljujem se profesorju in mentorju red. prof. dr. Aleksandru Veselu za

strokovno pomoč in nasvete pri oblikovanju diplomskega dela.

Posebna zahvala gre staršem in sestri, ker nikoli niso podvomili vame in ker so

vedno verjeli vame. Hvala staršem za vso potrpeţljivost in finančno podporo, ki

so mi jo nudili v letih mojega študija. Vsega, kar sta mi omogočila, jima ne

morem vrniti, vendar vem, da se bosta z mano veselila dneva, ko bom v rokah

ponosno drţala diplomo.

Hvala tudi tebi Sašo, ki si me sprejel takšno kot sem in si me optimistično

spodbujal ter mi stal ob strani pri vseh mojih vzponih in padcih.

Page 5: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

UNIVERZA V MARIBORU

FAKULTETA ZA NARAVOSLOVJE IN MATEMATIKO

IZJAVA

Podpisana Mateja Oletič, rojena 08.08.1986, študentka Fakultete za naravoslovje

in matematiko Univerze v Mariboru, smer računalništvo in sociologija, izjavljam,

da je diplomsko delo z naslovom

BAZNA DREVESA

pri mentorju red. prof. dr. Aleksandru Veselu, avtorsko delo. V diplomskem delu

so uporabljeni viri in literatura korektno navedeni; teksti in druge oblike zapisov

niso uporabljeni brez navedbe avtorjev.

__________________________

Maribor, 15.10.2010

Page 6: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

Program diplomskega dela

Bazna drevesa

Bazno drevo je podatkovna struktura, v kateri so podatki urejeni glede na

primerjavo istoleţnih števk ključev predstavljenih v izbrani bazi. Predstavljena naj

bo splošna definicija in osnovne oblike baznih dreves. Opisani naj bodo algoritmi

za iskanje, vstavljanje in brisanje podatkov. Ena od oblik baznega drevesa naj bo

realizirana v programskem jeziku.

Osnovna literatura:

Parsons, T. W. Introduction to algorithms in Pascal, J. Wiley & Sons, New York,

1995.

Mentor: prof.dr. Aleksander Vesel

Page 7: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

OLETIČ, M.: Bazna drevesa.

Diplomsko delo, Univerza v Mariboru, Fakulteta za naravoslovje in matematiko,

Oddelek za matematiko in računalništvo, 2010.

IZVLEČEK

Podatkovna struktura je način organizacije podatkov. Področje podatkovnih

struktur obravnava enostavnejše strukture, kot so seznam, sklad, vrsta, tabela ter

zahtevnejše, kot so drevesa, grafi, mnoţice. V diplomskem delu se osredotočimo

na posebno obliko dreves, ki jih imenujemo bazna drevesa.

V prvem poglavju smo za boljše razumevanje nadaljnjih poglavij razloţili pojem

algoritma, pojem podatkovne strukture in pojem drevesa.

Nadaljevali smo z razlago urejanja z radiksom, ki je motivacija za uvedbo baznih

dreves. V tem poglavju razloţimo osnove urejanja z radiksom ter opišemo in

razloţimo dva načina urejanja z radiksom. Oba načina razloţimo še na podlagi

primerov.

Tretje poglavje posvetimo glavni temi našega diplomskega dela, kjer razloţimo

idejo baznih dreves.

Naslednja tri poglavja posvetimo razlagi vsake od podvrst baznih dreves. Na

podlagi teoretične razlage in praktičnega prikaza s primeri razloţimo digitalno

drevo, drevo trie in patricia drevo.

Zadnje poglavje posvetimo razlagi delovanja algoritma, ki smo ga realizirali v

programskem jeziku C++.

Ključne besede: algoritem, drevo, urejanje z radiksom, bazno drevo, digitalno drevo, trie,

patricia.

Page 8: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

OLETIČ, M.: Radix trees.

Graduation Thesis, University of Maribor, Faculty of Natural Sciences and

Mathematics, Department of Mathematics and Computer Science, 2010.

ABSTRACT

Data structure is a way of organizing data. The field of data structures treats very

simple structures such as lists, stacks, queues, arrays as well as more pretentious

structures such as trees, graphs, sets. In this diploma thesis we focus on a special

form of trees which are called radix trees.

In the first chapter we explained the idea of algorithm, data structure and tree for a

better understanding of the following chapters.

We continued with the explanation of radix sort which is the motivation for

introducing radix trees. In this chapter we explain the basics of radix sort and

describe two ways of radix sort. Both ways are explained on the bases of

examples.

The third chapter is devoted to the main topic of our diploma thesis, where the

idea of radix trees is explained.

The next three chapters are devoted to the explanations of each sub-sort of radix

trees. On the basis of theoretical explanation and the practical presentation with

examples we explain the digital tree, trie and patricia tree.

The last chapter is devoted to the explanation of the algorithm operation which

was carried out in the C++ programming language.

Key words: algorithm, tree, radix sort, radix tree, digital tree, trie, patricia.

Math. Sci. Class. (2000): 68P05

Page 9: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

IX

Kazalo

UVOD .............................................................................................................. 1

1 ALGORITEM, PODATKOVNA STRUKTURA IN DREVO ................................... 3

1.1 Definicija algoritma ..................................................................................... 3

1.2 Zahtevnost algoritma .................................................................................. 6

1.2.1 Časovna zahtevnost ..................................................................................................... 6

1.2.2 Prostorska zahtevnost ................................................................................................. 6

1.3 Podatkovna struktura .................................................................................. 7

1.4 Drevo .......................................................................................................... 7

1.4.1 Dvojiško iskalno drevo ................................................................................................. 8

2 UREJANJE Z RADIKSOM ........................................................................... 10

2.1 Motivacija za urejanje z radiksom .............................................................. 10

2.1.1 Pojem radiksa ............................................................................................................ 11

2.1.2 Ideja urejanja z radiksom .......................................................................................... 12

2.2 Dve obliki urejanja z radiksom ................................................................... 12

2.3 Razlike med MSD in LSD načinom............................................................... 13

2.4 Uporaba MSD metode urejanja z radiksom ................................................ 13

2.5 Uporaba LSD metode urejanja z radiksom .................................................. 14

3 BAZNA DREVESA ..................................................................................... 17

3.1 Osnovna oblika.......................................................................................... 17

3.2 Motivacija za bazna drevesa ...................................................................... 18

3.3 Osnovne operacije ..................................................................................... 18

3.4 Vrste baznih dreves ................................................................................... 23

4 DIGITALNO DREVO .................................................................................. 24

4.1 Vstavljanje podatkov v drevo ..................................................................... 25

4.2 Iskanje podatkov v drevesu ....................................................................... 29

4.3 Brisanje podatkov iz drevesa ..................................................................... 30

5 TRIE ........................................................................................................ 32

5.1 Iskanje podatkov v drevesu ....................................................................... 34

5.2 Vstavljanje podatkov v drevo ..................................................................... 36

5.3 Brisanje podatkov iz drevesa ..................................................................... 38

Page 10: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

X

6 PATRICIA ................................................................................................ 41

6.1 Pravila patricia drevesa.............................................................................. 41

6.2 Vstavljanje podatkov v drevo in razvijanje drevesa ..................................... 43

6.3 Iskanje podatkov v drevesu ....................................................................... 52

7 OPIS PROGRAMA .................................................................................... 54

7.1 Vnos podatkov in potek programa ............................................................. 54

7.2 Delovanje programa za primer digitalnega drevesa .................................... 55

ZAKLJUČEK..................................................................................................... 59

LITERATURA .................................................................................................. 61

PRILOGA ........................................................................................................ 62

Page 11: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

1

UVOD

Dandanes si ţivljenja brez računalnikov sploh ne moremo več predstavljati.

Uporabljamo jih doma, v šoli, v sluţbi. V nekoliko drugačni obliki so prisotni tudi

v avtomobilih, strojih, naši mobilni telefoni so ţe na nek način nekakšni majhni

računalniki. Če zavrtimo čas za trideset let nazaj, nam lahko naši starši povedo,

kako so takrat profesorji na fakulteti razlagali, da bomo nekoč imeli doma v

stanovanju po dva, tri ali celo štiri računalnike, da bo to nekaj vsakdanjega. In če

pogledamo situacijo danes, lahko tem besedam samo pritrdimo, saj danes skorajda

ne najdemo stanovanja, kjer ne bi imeli vsaj enega računalnika.

Računalniki nam olajšajo marsikatero nalogo ali problem, ki ga vedo rešiti v

bistveno hitrejšem času, v primerjavi s časom, ki bi ga potrebovali ljudje, če bi

hoteli rešiti enak problem ali nalogo. Poleg tega nam omogočajo shranjevanje

velike količine podatkov, urejanje le-teh ter prikaz različnih simulacij, ki jih v

realnem ţivljenju ne moremo predstaviti. S pojavom računalnika se nam je

bistveno olajšalo ţivljenje, lahko rečemo, da skorajda na vseh področjih.

Velikokrat so podatki, ki prihajajo v računalnik, neurejeni, zato potrebujemo

posebne postopke, ki bodo te podatke uredili tako, da bodo le-ti postali urejeni.

Samo urejanje podatkov v računalništvu lahko poteka na različne načine, ki jih

opišemo z algoritmi urejanja. Pomembna komponenta urejanja je hitrost urejanja

podatkov. Najprej so bili le-ti počasnejši in preprostejši. Zaradi potrebe po

hitrejšem urejanju so se razvili različni postopki in pristopi. Posledično je to

privedlo do tega, da poznamo danes številne algoritme urejanja.

Podatki so lahko urejeni tudi v obliki dreves. Drevo je na področju računalništva

pogosto rabljena podatkovna struktura. Elementi so v drevesu urejeni hierarhično

v razmerju »roditelj – otrok« in so med seboj povezani. Ločimo veliko različnih

vrst dreves, na primer dvojiška drevesa, dvojiška iskalna drevesa, bazna drevesa,

B-drevesa, AVL drevesa, itd. V nekaterih vrstah dreves ima roditelj tudi več

otrok, medtem, ko ima otrok vedno le enega roditelja.

Page 12: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

2

Dvojiško ali binarno drevo je drevesna podatkovna struktura, kjer ima vsako

vozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni

otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

računalništva. V našem vsakdanjem ţivljenju lahko na primer s pomočjo

dvojiških dreves predstavimo druţinsko drevo. Tako lahko predstavimo

rodoslovne podatke oziroma sorodstvene relacije neke druţine.

Bazno drevo je posebna vrsta dvojiškega drevesa, ki se v osnovni obliki uporablja

za shranjevanje niza s poljubno dolţino bitov (sestavljajo ga samo ničle in enice).

Ta vrsta drevesa ima svoje različice oziroma podvrste, katere omogočajo

shranjevanje ne samo bitnega niza s poljubno dolţino bitov, ampak tudi druge

podatkovne oblike, kot so črke, besede, ...

Diplomsko delo je razdeljeno na sedem poglavij. Prvo poglavje opredeljuje pojem

algoritma, pojem podatkovne strukture in pojem drevesa. Naslednje poglavje

opiše algoritem urejanja z radiksom. Tretje poglavje predstavi osnovno obliko

baznih dreves. Nadaljnja tri poglavja podajajo razlago vsake od treh podvrst

baznih dreves posebej. V zadnjem poglavju je opisan program za delo z

digitalnim drevesom, ki je realiziran v programskem jeziku C++.

Page 13: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

3

1 ALGORITEM, PODATKOVNA STRUKTURA IN

DREVO

Za laţje oziroma boljše razumevanje poglavij, ki sledijo, bomo to poglavje

namenili razlagi definicije algoritma, njegove zahtevnosti ter podatkovne

strukture in razlagi definicije drevesa.

1.1 Definicija algoritma

Vsak dan se srečujemo z različnimi problemi, ki jih tudi rešujemo. Pri tem si

pomagamo z izkušnjami, znanjem, s spretnostjo. Reševanje nekaterih problemov

se nam zdi povsem logično, saj poznamo vse korake, ki nas vodijo do same

rešitve problema. Včasih pa se nam zgodi, da rešitve problema ne poznamo v

naprej. Takrat potrebujemo dodatne informacije, ki nas bodo pripeljale do

končnega cilja. Kot primer vzemimo nakup hiše na hipoteko. Najverjetneje o

poteku takega nakupa nimamo vseh informacij, ne poznamo vseh korakov v

naprej, ki bi nas pripeljali do cilja, torej do nakupa hiše, v primerjavi z nakupom v

trgovini, kjer točno vemo, kako poteka postopek nakupovanja. Nekateri problemi

ne zahtevajo samo naše iznajdljivost in ustvarjalnost in zato med te vrste

problemov prištevamo tudi razvoj algoritmov. Algoritmično razmišljanje človeku

ni prirojeno. V to se lahko prepričamo ob primerih iz našega ţivljenja [3].

Čeprav se nam zdi, da nam je jasno kaj je treba storiti (razumemo vprašanje

KAJ?), se nam pri izpeljavi dejstva kako to storiti (vprašanje KAKO?) lahko kaj

hitro zaplete, tako da lahko pridemo na koncu čisto nekam drugam, samo k

zastavljenemu cilju ne. Da bi bili pri reševanju problemov uspešni, moramo

upoštevati naslednje principe [4]:

razumevanje problema: problem smo ţe na pol rešili, ko vemo, kateri

problem je potrebno rešiti. Najprej je pomembno razumevanje problema,

potem sledi nedvoumna definicija problema, opis dejstev, pravil in ciljev.

Page 14: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

4

abstrakcija problema: opis problema je treba abstrahirati, tako da se

obdrţijo samo pomembni podatki; nepomembne podatke je treba

zanemariti. Pri abstrakciji identificiramo pomembne objekte, jih

imenujemo, določimo relacije med njimi in definiramo operacije na teh

objektih.

izbira notacije: izbira ustrezne notacije ključno vpliva na hitrost in

uspešnost reševanja problemov. Večji del programiranja je spreminjanje

notacije, ki jo razume človek, v notacijo, ki jo razume stroj. Notacija je

simbolična predstavitev, ki modelira skupne značilnosti razreda objektov

ali situacije in moţne operacije na simbolih. Uporabljamo slikovne ali

besedne simbole. Katere izberemo je povsem odvisno od subjektivne

izbire. Nekateri si laţje vizualizirajo problem, drugim pa je bliţji besedni

opis.

razbitje problema na podprobleme: pri reševanju kompleksnih problemov

je pomembna razgradnja problema na manjše zaokroţene podprobleme.

Pomembno je, da poskušamo kompleksen problem razgraditi na

preprostejše podprobleme, ki jih lahko rešujemo neodvisno. Problem

navadno razgrajujemo od zgoraj navzdol, lahko pa izberemo tudi obratno

strategijo, kjer iz rešitev manjših problemov sestavljamo rešitve bolj

zapletenih problemov.

Slika 1: Snovanje algoritmov

Page 15: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

5

podobnost med problemi: pogosto si lahko pri reševanju problemov

pomagamo z rešitvami podobnih problemov. S transformacijo lahko

problem poenostavimo, posplošimo ali samo preoblikujemo v izomorfni

problem. Z rešitvijo poenostavljenega problema lahko dobimo idejo za

rešitev bolj zapletenega problema.

Beseda algoritem je izpeljana iz imena perzijskega matematika Abu Ja`far

Mohamed ibn Musa al Khowarizmi, in sicer na naslednji način [3]:

al-Khowarizmi → algorism → algorithm → algoritem.

Za podajo natančne definicije algoritma bi se morali nasloniti na formalni model

računalnika, kateremu je seveda algoritem namenjen. V definicijo bi mogli

vključiti pojme, kot so: nabor podatkov, osnovne operacije, organizacijo dela, …

Za nas bodo primerni algoritmi, ki jih izvajamo na računalniku, zato lahko

podamo naslednjo definicijo algoritma [4].

Algoritem je končno zaporedje natančno določenih ukazov, ki opravijo neko

nalogo v končnem številu korakov. Algoritem sprejme vhodne podatke in vrne

rezultat. Zanj velja, da ima podatke, vrne rezultate, je natančno določen, saj mora

vsak ukaz nedvoumno povedati, kaj storiti in da se vedno konča.

Ţe prej omenjeno vprašanje KAJ je treba storiti, moramo razgraditi na manjše,

laţje probleme, ki nam posledično povedo KAKO to storiti. Zato je v končnem

smislu algoritem nekakšno zaporedje preprostih ukazov, kot so na primer: seštej,

odštej, zmnoţi, pogoj, v katerem določamo ali je neka vrednost večja, manjša ali

enaka 0, itd.

Algoritem lahko zapisujemo [4]:

z diagrami poteka – pomeni grafični prikazni potek,

s psevdokodo – jezik za zapis algoritmov (lahko smo manj natančni),

v programskih jezikih – zahtevano poznavanje podrobnosti programskega

jezika, omejeni smo z ukazi programskega jezika.

Page 16: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

6

1.2 Zahtevnost algoritma

Kot smo ţe prej omenili v definiciji besede algoritem, je algoritem rešitev nekega

problema. Računalniku ga ne pustimo v slepo izvajanje, ampak ga analiziramo

koliko časa bo tekel in koliko prostora bo zasedal v računalniškem pomnilniku.

Pravimo, da analiziramo njegovo časovno in prostorsko zahtevnost. V splošnem z

zahtevnostjo imenujemo količino računalniški virov in sredstev, ki jih

potrebujemo za rešitev problema po izbranem postopku.

1.2.1 Časovna zahtevnost

Poleg preverjanja pravilnosti algoritma je najpomembnejši del analize algoritma

določitev njegove časovne zahtevnosti. Časovna zahtevnost je odvisna od

velikosti vhodnih podatkov. Na zahtevnost lahko vplivajo različne vrednosti

vhodnih podatkov, na primer število podatkov, velikost posameznega podatka,

vrstni red podatkov, … [4]. Merimo jo v osnovnih aritmetično-logičnih operacijah

(seštevanje, odštevanje, mnoţenje, deljenje, primerjave/prireditve). Časovno

zahtevnost označimo s T(n). Oznaka T(n) je funkcija, ki podaja hitrost naraščanja

zahtevnosti s številom podatkov.

Časovno zahtevnost lahko dobimo na dva načina:

analiziramo algoritem in preštejemo, koliko bo opravil ali

preprosto izmerimo, koliko časa potrebuje glede na različne vhodne

podatke.

1.2.2 Prostorska zahtevnost

Prostorska zahtevnost je količina pomnilnika, potrebnega za izvajanje algoritma.

Merimo jo v enotah primarnega ali sekundarnega pomnilnika (zlogi, bloki,

besede).

Glede na vhodne podatke poiščemo, koliko časa teče algoritem za najneugodnejše

in najugodnejše podatke. Dobljeni vrednosti imenujemo časovna zahtevnost v

najslabšem in najboljšem primeru. Pri ocenjevanju zahtevnosti nas večinoma ne

bo zanimalo, koliko operacij ali prostora potrebujemo, temveč nas bo zanimal le

Page 17: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

7

red velikosti hitrosti rasti zahtevnosti algoritma in ne natančna vrednost. Glede na

red velikosti hitrosti rasti zahtevnosti algoritma v odvisnosti od števila podatkov

delimo probleme na: lahke in teţke. Med lahke algoritme spadajo algoritmi, ki se

izvršijo v polinomskem času, medtem ko med teţke prištevamo algoritme, ki

zahtevajo eksponentno rešitev [3].

1.3 Podatkovna struktura

Študija algoritmov in podatkovnih struktur sta med seboj tesno povezana, saj

pravzaprav govorita o isti stvari iz dveh zornih kotov [3]. Vsaka podatkovna

struktura ima dva vidika – matematičnega in računalniškega. Ko gledamo na

podatkovno strukture iz matematičnega vidika, nas zanimajo predvsem njene

matematične lastnosti. V računalništvu pa se ukvarjamo z vprašanjem, kako

podatkovno strukturo predstavimo v računalniku in kako učinkovito opravljamo

osnovne operacije na podatkovni strukturi.

Podatkovna struktura je način organizacije podatkov. V vsakdanjem ţivljenju

srečamo podatkovne strukture kot so seznam, sklad, vrsta, tabela itd. V

računalništvu poznamo še nekatere druge podatkovne strukture, kot so drevesa,

grafi, mnoţice.

Podatkovna struktura določa:

kako so podatki predstavljeni,

kakšne so osnovne operacije za delo s podatkovno strukturo.

Katero podatkovno strukturo izberemo, je odvisno od tega, kaj bi radi s podatki

počeli.

1.4 Drevo

Obstaja nekaj različnih definicij pojma drevesa. V teoriji grafov je drevo

definirano kot povezan graf brez ciklov. Osnovni element v drevesu je vozlišče.

Page 18: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

8

Vsako vozlišče ima lahko nič ali več otrok, vendar kvečjemu enega roditelja.

Koren je vrhnje vozlišče, edino vozlišče v drevesu brez roditelja.

Oglejmo si nekaj definicij pojmov, ki se nanašajo na podatkovno strukturo drevo:

koren drevesa: samo eno vozlišče v nepraznem drevesu je brez roditelja in

mu pravimo koren drevesa.

vozlišče: osnovni element drevesa, ki vsebuje podatke in informacije o iz

njega izhajajočih poddrevesih. Vozlišče ima lahko več potomcev, prednika

pa ima samo enega.

list: vozlišče brez otrok.

notranje vozlišče: vozlišče, ki ima vsaj enega otroka.

poddrevo: poddrevo danega vozlišča je drevo, katerega koren je otrok

danega vozlišča. Otrokom istega roditelja pravimo sorojenci.

stopnja vozlišča: število otrok danega vozlišča.

stopnja drevesa: največje število otrok nekega notranjega vozlišča.

prazno drevo: drevo brez vozlišč.

dvojiško drevo: vsako vozlišče ima največ dva otroka.

1.4.1 Dvojiško iskalno drevo

Dvojiško iskalno drevo je dvojiško drevo, za katerega v vsakem vozlišču velja, da

so vsi ključi v levem poddrevesu manjši od korena in v desnem poddrevesu večji

od korena.

Page 19: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

9

Slika 2: Primer drevesa

Pri dvojiških iskalnih drevesih poznamo tri osnovne operacije:

vstavljanje v drevo: ţelen element vstavljamo v drevo. Če koren drevesa še

ne obstaja, potem prvi element, ki ga vstavljamo postane koren drevesa.

Drugače poteka vstavljanje v drevo po pravilih, ki ga določa le-ta.

iskanje po drevesu: iščemo nek element v drevesu, kjer kot prvo preverimo

če obstaja koren drevesa. Če le-ta obstaja, nadaljujemo iskanje po drevesu.

brisanje iz drevesa: pri brisanju imamo več moţnosti glede na to, ali je

vozlišče, ki ga ţelimo izbrisati, list ali ima vozlišče enega samega otroka

ali pa ima vozlišče dva otroka.

Page 20: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

10

2 UREJANJE Z RADIKSOM

V vsakdanjem ţivljenju se marsikdaj srečamo s problemom, ko ţelimo nekaj

zloţiti, urejati, na primer po velikosti, barvi, po abecedi. Kot vemo iz izkušenj,

med urejenimi predmeti laţje najdemo ţelenega. Podoben pomen ima urejanje

tudi v svetu računalništva. Zelo pomemben je zato študij algoritmov za urejanje.

Ločimo primerjalno urejanje, kjer poteka pregledovanje elementov s

primerjalnimi operatorji, ponavadi je to operator manjše ali enako (≤). Ta vrsta

urejanja zajema naslednje znane algoritme za urejanje: urejanje z vstavljanjem,

urejanje z mehurčki, hitro urejanje, urejanje z zlivanjem, urejanje s kopico.

Obstaja še druga vrsta urejanja in sicer neprimerjalno urejanje. To uporablja druge

metode za razvrščanje podatkov in ne uporablja primerjalnih operatorjev. V to

vrsto prištevamo: urejanje z radiksom (proučuje posamezne bite v ključu),

urejanje s štetjem (šteje pojavitve vrednosti elementov), urejanje s koši/sektorsko

urejanje (preučuje bite ključa). Algoritem urejanja z radiksom bomo v

nadaljevanju poglavja podrobneje opisali in prikazali na primeru, saj bo sluţil kot

motivacija za bazna drevesa.

2.1 Motivacija za urejanje z radiksom

Nekoč so bili računalniški programi napisani v programskem jeziku Fortran,

katere so vnašali v računalnik s pomočjo luknjanih kartic. Na vsaki kartici je bila

v stolpcih 1 do 72 zapisana koda programa, stolpci od 73 do 80 so pomenili

številko kartice. Če so kartice po nesreči kdaj padle na tla, je nastal velik problem,

saj je bilo za en program potrebnih tudi 2000 kartic. Problem so lahko rešili tako,

da so pomešane kartice vstavili v napravo, ki jih je razvrstila po vrstnem redu [6].

Naprava za urejanje kartic je bila velikosti treh ali štirih velikih omar. Imela je

vhod za kartice in deset izhodnih zabojev, ki so bili oštevilčeni od 0 do 9. Prebrala

je vsako kartico in jo postavila v zaboj, glede na številko v določenem stolpcu, na

primer stolpcu 80. Tako dobimo deset kupov kartic, en kup v vsakem zaboju.

Page 21: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

11

Kartice so bile urejene najprej po najmanj pomembni cifri (stolpec 80), pozneje

po najpomembnejši (stolpec 73) [6].

Številne aplikacije urejanja, ki uporabljajo ključ za določitev vrstnega reda

zapisov, so lahko kar zahtevne. Kot primer lahko podamo kompleksnost ključa v

telefonskem imeniku ali v knjiţničnem katalogu. Obdelava celega ključa na

vsakem koraku je pogosto nepotrebna. Pri iskanju v telefonskem imeniku

preverjamo samo nekaj prvih črk in ne celega imena, torej samo del ključa.

Urejanje podatkov, kjer je ključ, ki definira urejenost podatkov, zapleten, lahko

nadomesti učinkovita metoda urejanja po delih, saj uporabljamo to metodo takrat,

kadar je ključ moţno razbijati na dele, ki so fiksne dolţine (bite, znake, cifre).

Binarna števila so zaporedja bitov, nizi so zaporedja znakov, decimalna števila so

zaporedja cifer. Povsem drugačen pogled na razvrščanje nam da razvrščanje z

delčki ključa, v primerjavi z razvrščanjem s celim ključem. Metode urejanja, ki za

urejanje uporabljajo samo del ključa naenkrat imenujemo urejanje z radiksom.

Razlago lahko podkrepimo še s primerom s področja pošte. Sortirni stroj na pošti

obdeluje kupe paketov, ki so označeni s 4-mestno poštno številko. Najprej jih

razporedi na deset kupov: prvi ima števila, ki se začnejo z 0, naslednji ima števila,

ki se začnejo z 1 in tako naprej. Kupi se lahko obdelujejo posamezno, z uporabo

metode naslednje cifre ali pa s kakšno drugo metodo. Če bi izbirali pakete iz

kupov v zaporedju od 0 do 9 tako kot so bili obdelani, bi dobili urejeno

razporeditev. Tak postopek predstavlja urejanje z radiksom z R=10 in je glavna

metoda v aplikacijah, kjer so ključi sestavljeni iz 5 do 10 mestnih števil kot so

poštne številke, telefonske številke oz. številke zdravstvenega zavarovanja [5].

2.1.1 Pojem radiksa

V grobem lahko rečemo, da je radiks števka oziroma poloţaj števke ključa

predstavljenega v izbrani bazi. V desetiškem sistemu je radiks le števka

desetiškega števila. Tako ima število 42 dve števki ali dva radiksa, to sta 4 in 2. V

šestnajstiškem sistemu ima radiks 8 bitov.

Page 22: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

12

2.1.2 Ideja urejanja z radiksom

Algoritmi urejanja z radiksom so zasnovani na abstraktnih operacijah "izvleci i-to

cifro iz ključa". Zato lahko pravimo, da je urejanje z radiksom urejanje z več

prehodi oz. urejanji. Število urejanj je enako številu radiksov vhodnega števila.

V algoritmih urejanja z radiksom so deli ključa določene velikosti. Če so v ključu

številke, potem poteka urejanje po načelu števka za števko, če pa so v ključu črke,

ki jih ţelimo razvrstiti po abecedi, potem uporabimo načelo črka za črko.

Urejanje z radiksom zahteva čas O(d (n + k)) = O(dn + dk), pri čemer je n velikost

ali število elementov, ki jih je treba urediti. Spremenljivka d predstavlja število

števk elementa oziroma kar dolţino ključa, kar pa posledično predstavlja število

urejanj. Vsaka števka je reda od 1 do k [6].

2.2 Dve obliki urejanja z radiksom

Obstajata dva bistveno različna osnovna pristopa k urejanju z radiksom, in sicer:

Prvi pristop vključuje algoritem, ki pregleduje števke v ključu od leve

strani proti desni strani, saj uporablja najbolj pomembno števko najprej

oziroma najprej obdela najpomembnejše števke. Te vrste algoritmov

imenujemo urejanje z najbolj pomembno števko ali MSD urejanje (most-

significant-digit (MSD) radix sort). MSD metoda urejanja je ugodna zato,

ker pregleduje minimalno količino informacij, potrebnih za uspešno

opravljeno razvrščanje oziroma urejanje. MSD urejanje posplošuje hitro

urejanje, ker je delitev »problema« razvrščena glede na najpomembnejše

števke ključa.

Druga vrsta metod urejanja z radiksom je drugačna. Ta metoda pregleduje

števke v ključu od desne strani proti levi strani, torej od najmanj

pomembne števke najprej. Ta metoda je splošno znana pod imenom

urejanje z najmanj pomembno števko ali LSD urejanje (least-significant-

digit (LSD) radix sort). LSD metoda deluje ravno obratno kot metoda

MSD.

Page 23: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

13

2.3 Razlike med MSD in LSD načinom

Če poznamo pri metodi MSD najmanjše število znakov, potrebnih za

razlikovanje vseh znakov, potem lahko urejamo ta števila po poloţaju. To

bi na podlagi primera lahko razloţili takole: ko so besede dolge in jih

lahko razlikujemo samo po prvih nekaj znakih, potem jih lahko

razvrščamo samo po na primer prvih treh znakih ključa. To pomeni, da

nam ni potrebno pregledovati cele dolţine ključa.

LSD pristop zahteva polnjenje oziroma dopolnjevanje kratkega ključa, če

je dolţina ključa različna. S tem bo zagotovljeno, da bodo vse števke

pregledane in da bo zaporedje urejeno. Kot primer lahko podamo zapis

števila v binarnem načinu: 3 → 112 in 12 → 11002. To pomeni, da bosta

ključu 3 dodane od spredaj še dve ničli, tako da bomo imeli naslednja

ključa: 0011 in 1100.

MSD metoda urejanje zahteva veliko več pomnilnika za razvrščanje

elementov, zato je LSD urejanje primernejša metoda.

MSD rekurzivno urejanje lahko uporabimo za vzporedno urejanje, kar

pomeni, da lahko vsak podseznam uredi neodvisno od ostalih.

2.4 Uporaba MSD metode urejanja z radiksom

Predpostavimo, da imamo ključa oblike (j, k), kjer j pomeni eno od črk med A in

F in k, ki predstavlja števko. Ključa lahko razvrstimo v šest zabojev. Enega za

vsako od črk. Po tem vsak seznam razvrstimo še po števkah. Kot primer podajmo

naslednje zaporedje [1]:

A6, C9, F5, F4, B9, D2, E9, D3, C3, B3, A5, A9, E1, F2, D4, A7, D1

Page 24: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

14

1. korak: razvrstitev po črki. Po urejanju dobimo naslednje podsezname:

A6 A5 A9 A7

B9 B3

C9 C3

D2 D3 D4 D1

E9 E1

F5 F4 F2

2. korak: sedaj pa urejamo še znotraj vsakega podseznama še po njihovem

drugem parametru, torej po števki.

A5 A6 A7 A9

B3 B9

C3 C9

D1 D2 D3 D4

E1 E9

F2 F4 F5

3. korak: urejeno zaporedje:

A5 A6 A7 A9 B3 B9 C3 C9 D1 D2 D3 D4 E1 E9 F2 F4 F5

Urejeno polje dobimo z enostavno spojitvijo dobljeni podseznamov. Tak način je

splošno neroden za urejanje, zato je bolje uporabiti kaj primernejšega. Mi smo

urejali od skrajno levega dela ključa k skrajno desnemu. Če bi hoteli uporabiti

stabilnejše razvrščanje, potem bi morali uporabiti urejanje od skrajno desne proti

skrajno levi strani. S stabilno delitveno metodo lahko prav tako urejamo od

najmanj pomembnega bita proti najbolj pomembnemu bitu. Takšen primer bomo

razloţili v naslednjem podpoglavju.

2.5 Uporaba LSD metode urejanja z radiksom

LSD metoda urejanja pregleda niz od desne strani proti levi. Spodnji primer

prikazuje, kako lahko samo s šestimi prehodi čez datoteko opravimo urejanje

Page 25: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

15

nizov s šestimi znaki. I-ti stolpec dobimo iz (i-1)-tega stolpca z izvlečenjem vseh

ključev z 0 na i-tem mestu in vračanjem nad ključe z 1 na i-tem mestu. Poglejmo

si naš primer LSD urejanja. Naš primer ima največji radiks 6, kar posledično

pomeni, da bomo izvedli šest urejanj.

I. 1. korak: najprej uredimo zaporedje glede na najmanj pomembno cifro.

II. 2. – 5. korak: nato uredimo zaporedje glede na drugo najmanj pomembno cifro.

Tako sledimo korakom urejanja vse do najpomembnejše cifre.

1 1 0 1 1 0

0 0 1 1 0 0

0 0 1 0 0 1

0 1 0 1 1 1

1 0 1 1 1 1

0 1 1 1 0 0

1 1 0 1 1 0

0 0 1 1 0 0

0 1 1 1 0 0

0 0 1 0 0 1

0 1 0 1 1 1

1 0 1 1 1 1

0 0 1 1 0 0

0 1 1 1 0 0

0 0 1 0 0 1

1 1 0 1 1 0

0 1 0 1 1 1

1 0 1 1 1 1

Page 26: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

16

III. 6. korak: zaporedje uredimo še glede na najbolj pomembno cifro.

IV. 7. korak: urejeno zaporedje.

9 →

12 →

23 →

28 →

47 →

54 →

0 0 1 0 0 1

0 0 1 1 0 0

0 1 1 1 0 0

1 1 0 1 1 0

0 1 0 1 1 1

1 0 1 1 1 1

1 1 0 1 1 0

0 1 0 1 1 1

0 0 1 0 0 1

0 0 1 1 0 0

0 1 1 1 0 0

1 0 1 1 1 1

1 1 0 1 1 0

0 1 0 1 1 1

0 0 1 0 0 1

0 0 1 1 0 0

0 1 1 1 0 0

1 0 1 1 1 1

0 0 1 0 0 1

0 0 1 1 0 0

0 1 0 1 1 1

0 1 1 1 0 0

1 0 1 1 1 1

1 1 0 1 1 0

Page 27: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

17

3 BAZNA DREVESA

3.1 Osnovna oblika

Bazno drevo je posebna vrsta dvojiškega drevesa, ki se v osnovni obliki uporablja

za shranjevanje nizov s poljubno dolţino bitov. Nize torej sestavljajo samo ničle

in enice. Vsako vozlišče ima dve razvejitvi, ki ustrezata dvojiški števki (bitu).

Nepisano pravilo pravi, da je leva razvejitev oštevilčena z 0, desna pa z 1. Vsaka

pot neničelne dolţine skozi bazno drevo se začne pri korenu drevesa, zato je ta

posledično sestavljena iz edinstvenega zaporedja ničel in enic [7].

Poleg ţe zgoraj omenjenih lastnosti baznega drevesa moramo omeniti še nekaj

značilnosti:

vsi podatki so shranjeni v listih drevesa,

imamo dve vrsti vozlišč: notranja in zunanja vozlišča. Notranje vozlišče

drevesa vsebuje samo povezave do vozlišč, medtem ko zunanje vozlišče

vsebuje ključe.

vejitve do posameznih listov v drevesu so dolge toliko, kolikor je

potrebnih korakov, da se dva ključa razlikujeta v bitni vrednosti,

oblika drevesa ni odvisna od vrstnega reda vstavljenih podatkov.

Page 28: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

18

Slika 3: Primer baznega drevesa

3.2 Motivacija za bazna drevesa

Pri določitvah, kako nastane drevo in kako se išče po drevesu, se velikokrat

uporablja celoten ključ. Obstajajo primeri, kjer je pa mogoče uporabiti le del

ključa. To idejo smo uporabili ţe pri poglavju urejanja z radiksom. Takšen način

lahko uporabimo tudi pri tvorjenju baznih dreves. Ta podatkovna struktura, z

nekaj izjemami, ne more obravnavati podvojenih ključev, zato bomo v naslednjih

poglavjih privzeli, da so vsi ključi med seboj vedno različni.

3.3 Osnovne operacije

Vstavljanje

Postopek vstavljanja začnemo v korenu drevesa. Najprej preverimo, če ta ţe

obstaja v drevesu. Če koren ţe obstaja, preverimo prvi bit ključa, ki ga ţelimo

vstaviti, saj le-ta pove, v katero poddrevo se bomo usmerili. Tako pregledujemo

bitni niz ključa (bit za bitom). Glede na bitni niz se pomikamo po drevesu, dokler

ne doseţemo zunanje vozlišče. Če je zunanje vozlišče prazno, enostavno shranimo

ključ na to mesto v drevesu. Če list vozlišča ţe vsebuje nek ključ, potem ta

postane notranje vozlišče. Na tem notranjem vozlišču ustvarimo novo poddrevo,

Page 29: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

19

katerega vejitev je odvisna od tega, kako se ţe prej vstavljeni ključ in ključ, ki ga

ţelimo vstaviti, razlikujeta v bitnem nizu. Ustvarimo novo notranje vozlišče, na

katerega poveţemo ţe prej vstavljeni ključ in ključ, ki smo ga ţeleli vstaviti.

Ţe vstavljeni elementi v bazno drevo:

Slika 4: Vstavljeni elementi v bazno drevo

V bazno drevo, ki ga kaţe slika 4 ţelimo vstaviti ključ 59, ki ima dvojiški zapis

1110112. Vrednost bita 0 ključa 59 je 1, kar pomeni, da se bomo pomaknili v

desno poddrevo. Nato preverimo vrednost naslednjega bita, ki je spet 1 (spet se

pomaknemo desno). Tu naletimo na list z vrednostjo 60. Ker smo naleteli na list,

moramo na mestu lista ustvariti novo notranje vozlišče. Koliko novih notranjih

številka 15 6 31 60 2 46 20

dvojiški

zapis 001111 000110 011111 111100 000010 101110 010100

Tabela 1: Elementi v dvojiškem zapisu

Page 30: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

20

vozlišč bomo ustvarili, je odvisno od primerjave bitnega niza ključa 60 in 59. Ker

sta vrednosti bita 1 in bita 2 teh dveh ključev enaka, pomeni, da bomo ustvarili še

dve notranji vozlišči. V bitu 3 se vrednosti razlikujeta, zato bomo na drugo

vstavljeno notranje vozlišče povezali ţe prej vstavljeno vozlišče 60 in novi ključ

59. Ključ 59 bomo vstavili na levo stran notranjega vozlišča (vrednost bita 3 je

enaka 0). Vozlišče 60 ima v tem bitu vrednost 1, zato ga vstavimo na desno stran

(glej sliko 5).

Slika 5: Vstavitev elementa v bazno drevo

Iskanje

Iskanje pričnemo v korenu drevesa. Če ţe le-ta obstaja v drevesu, preverimo prvi

bit ključa, za katerega ţelimo preveriti ali obstaja v drevesu. Prvi bit ključa nam

določi, v katerem poddrevesu bomo nadaljevali iskanje. Če ima bit 0 vrednost nič,

bomo šli v levo poddrevo in če ima bit 0 vrednost 1, bomo iskali v desnem

poddrevesu. Pri premikanju po drevesu ne primerjamo nobenih vrednosti med

seboj, saj se po drevesu premikamo glede na bitni niz, ki ga ima iskani ključ.

Postopek iskanja poteka tako dolgo, dokler ne pridemo do zunanjega vozlišča

oziroma lista. Nato preverimo, če je iskana vrednost ključa enaka vrednosti v

listu.

Page 31: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

21

Na primeru baznega drevesa, ki ga kaţe slika 3, bomo prikazali postopek iskanja.

Poiskati ţelimo vozlišče 6. Začnemo pri korenu, kjer najprej preverimo vrednost

bita 0, ki je 0. To pomeni, da se usmerimo v levo poddrevo. Vrednost bita 1 in

bita 2 je prav tako 0, zato se bomo še dvakrat pomaknili v levo. Bit 3 ima vrednost

1, zato se pomaknemo v desno stran vozlišča. Ker naletimo na list, preverimo, če

je vrednost v listu enaka vrednosti, ki jo iščemo. Če je ta enaka, pomeni da smo

našli ţeleno vozlišče.

Slika 6: Iskanje elementa po baznem drevesu

Brisanje

Pri postopku brisanja izbrišemo list vozlišča. Postopek brisanja pričnemo s

premikanjem po drevesu glede na bitni niz iskanega vozlišča. Ko najdemo ţelen

list, ki ga ţelimo izbrisati, lahko pričnemo z brisanjem. Če ima notranje vozlišče

razen lista, ki ga ţelimo izbrisati še en drug list, izbrišemo najprej ţelen list. Nato

moramo odstraniti še nepotrebna notranja vozlišča, ki so nastala ob vstavitvi

enega od obeh ključev.

Spet vzemimo primer baznega drevesa iz slike 3. Izbrisati ţelimo list z vrednostjo

59. V drevesu poiščemo list in pričnemo s postopkom brisanja. Po izbrisu

ţelenega lista, izbrišemo še nepotrebna notranja vozlišča.

Page 32: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

22

Slika 7: Brisanje elementa iz baznega drevesa

Po izbrisu dobimo naslednjo obliko drevesa, kot kaţe spodnja slika.

Slika 8: Bazno drevo po izbrisu elementa

Page 33: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

23

3.4 Vrste baznih dreves

Najpomembnejše različice baznih dreves so:

digitalno drevo,

trie,

patricia drevo.

V nadaljnjih treh poglavjih bomo podrobneje razloţili vsako od podvrst baznih

dreves.

Page 34: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

24

4 DIGITALNO DREVO

Kot prvo podvrsto baznih dreves bomo podrobneje obravnavali digitalno drevo.

Ta vrsta drevesa deluje podobno kot dvojiško iskalno drevo, z razliko pri

razvejevanju, ki temelji na bitih iskanega ključa. Pot od korena drevesa do

elementa se določi z dvojiško predstavitvijo ključa. Za laţje razumevanje

pričnimo s prikazom primera na podlagi naslednjega algoritma, ki vstavi novo

vozlišče v digitalno drevo.

I. vrednost n postavimo na 0 (n – indeks bita ključa);

II. če je koren prazen (ne obstaja), vstavimo novo vozlišče v koren;

III. sicer, dokler je n manjši ali enak številu bitov v ključu:

a. testiraj n-ti bit ključa:

i. če ima bit vrednost 0, vstavi vozlišče v levo poddrevo.

ii. če ima bit vrednost 1, vstavi vozlišče v desno poddrevo.

b. povečaj n;

Kot primer vzemimo naslednje zaporedje ključev, ki jih bomo vstavljali v drevo.

Niz ključev je naslednji: 12, 5, 10, 60, 25, 31, 70, 43.

V tej strukturi bitni vzorec ključa določa, kam bo šel zapis v drevesu. Najprej

moramo razčistit nekaj dejstev. Prvo se glasi, da ne obstaja dogovor, kako

številčiti bite ključa. Nekateri jih številčijo od leve strani proti desni, drugi jih

številčijo od desne proti levi. Nekateri jih začnejo številčiti z 0, drugi pa z 1, torej

to pomeni, da je kot prvi bit razumljeni bit 0 ali da je kot prvi bit razumljeni bit 1.

Mi bomo od sedaj uporabljali naslednje pravilo. Bite ključa bomo številčili od

desne strani proti levi, začenši z bitom 0. Če izberemo moţnost številčenja od leve

proti desni strani, potem moramo poznati najdaljši ključ, saj moramo poznati

Page 35: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

25

skrajno levo pozicijo bita. V večini programskih jezikov je laţje preveriti skrajno

desni bit, saj se lahko pomikamo, spremenimo poloţaj ključa za eno mesto v

desno, namesto, da hranimo nek bitni števec n.

4.1 Vstavljanje podatkov v drevo

Za laţje razumevanje si najprej poglejmo primer. Kot smo ţe prej zapisali, imamo

naslednji niz ključev: 12, 5, 10, 60, 25, 31, 70, 43. Ključe pretvorimo v dvojiško

obliko kot kaţe spodnja tabela.

S klicem programa razporedimo in napolnimo novo vozlišče. V našem primeru

bomo začeli s prvim številom, ki je 12. Ker nismo vstavili še nobenega ključa je

naš koren drevesa prazen oziroma še ne obstaja, zato dobi vrednost 12.

Slika 9: Vstavitev prvega elementa v digitalno drevo

Naslednji ključ je 5, ki ga dvojiško zapišemo kot zaporedje ničel in enic: 101.

Koren drevesa ţe obstaja in 0-ti bit ključa 5 je enak 1, zato gre ključ 5 v desno

poddrevo.

številka 12 5 10 60 25 31 70 43

dvojiški

zapis 1100 101 1010 111100 11001 11111 1000110 101011

Tabela 2: Podatki v dvojiški obliki

Page 36: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

26

Slika 10: Vstavitev elementa 5

Tretji ključ je 10, ki ga dvojiško zapišemo 1010. Koren drevesa ţe obstaja, zato

preverimo bit 0, ki ima vrednost 0, zato gre 10 v levo poddrevo.

Slika 11: Vstavitev elementa 10

Naslednji ključ je 60=1111002. Ker koren drevesa ţe obstaja in je bit 0 enak 0, gre

60 v levo poddrevo. Vendar koren levega poddrevesa ni prazen, saj ţe vsebuje

ključ 10, zato moramo preveriti bit 1 ključa 60. Bit 1 je 0, zato gre 60 na levo

stran poddrevesa s korenom 10.

Page 37: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

27

Slika 12: Vstavitev elementa 60

Peti ključ je 25=110012. Bit 0 je 1, zato gre ta ključ v desno poddrevo. V desnem

poddrevesu ţe obstaja ključ 5, zato pogledamo katero vrednost ima bit 1. Njegova

vrednost je 0, zato gre 25 na levo stran ključa 5.

Slika 13: Vstavitev elementa 25

Sledi ključ 31=111112. Bit 0 je 1, zato gre ključ v desno poddrevo, ker pa v tem ţe

obstajata 5 moramo preveriti bit 1, ki je 1 in ker desna stran vozlišča še ni

zasedena, gre 31 na desno stran vozlišča z vrednostjo 5.

Page 38: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

28

Naslednji ključ je 70=10001102, ki ima bit 0 z vrednostjo 0, zato se premaknemo

v levo poddrevo, v katerem ţe obstaja 10. Preverimo bit 1, ki je 1. Ker je desna

stran še prosta, gre 70 na desno stran ključa 10.

Slika 14: Vstavitev elementa 70

Zadnji ključ, ki sledi je 43=1010112. Bit 0 je 1, zato gre v desno poddrevo. Tam

ţe obstaja 5. Preverimo bit 1, ki je 1 in ker na tem mestu ţe obstaja ključ 31

preverimo bit 2, ki je 0 in ker vozlišče z vrednostjo 31 še nima otrok, gre ta lahko

zaradi bita 2, ki ima vrednost 0 na levo stran.

Page 39: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

29

Slika 15: Vstavitev elementa 43

Prej smo določili, da bomo številčenje bitov izvajali od desne strani proti levi,

začenši z bitom 0. Ob tej predpostavki je zapisana koda za vstavljanje ključev v

drevo navedena v prilogi diplomskega dela.

4.2 Iskanje podatkov v drevesu

Procedura iskanja je skoraj tako preprosta kot procedura vstavljanja. Spremenimo

običajno iskalno funkcijo, tako da se uporablja bitni model za izbiro, v katerem

poddrevesu bomo iskanje izvajali. Od tedaj ga bomo primerjali s ključem (da se

ugotovi ali ga vsebuje trenutni koren) in ga premaknili v vrsto za dostop do drugih

bitov. Algoritem ima naslednjo obliko:

I. če koren še ne obstaja, funkcija vrne false (element ni bil najden);

II. če je iskani ključ enak ključu v korenu, potem funkcija vrne true (element

je najden);

III. če iskani ključ ni enak ključu v korenu, preverjamo bit za bitom:

i. če ima preverjeni bit vrednost 0, nadaljujemo iskanje v levem

poddrevesu.

Page 40: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

30

ii. drugače nadaljujemo iskanje v desnem poddrevesu.

IV. če je bil iskani ključ najden, funkcija vrne true, drugače pa false;

Pripomniti moramo, da obstaja omejitev glede višine drevesa. Ni pomembno,

kako se je razvijalo do tedaj, če je najdaljši shranjeni ključ dolg b bitov. Dolţina

poti do tega ključa ne more biti daljša kot b-1. Na ta način je zagotovljena

košatost drevesa, če je shranjenih veliko ključev. Še več, celo izrojeno drevo ne

bo zelo visoko. Od tod lahko zaključimo, da so stroški iskanja po digitalnem

drevesu, ki vsebuje n elementov, v najslabšem primeru b-1.

Če so ključi, ki jih vstavljamo v drevo, nizi znakov, potem bo premikanje in

testiranje bitov bolj zapleteno, saj moramo takrat vzeti v obzir število bitov za

znak (sedem ali osem) in moramo nekako urediti premik za celotni niz, ko smo

prišli na konec znaka. V naslednjem poglavju si bomo ogledali še drugačno

izvedbo obdelave znakovnih nizov.

4.3 Brisanje podatkov iz drevesa

Pri digitalnem drevesu je postopek brisanja relativno enostaven, saj lahko

izbrisano vozlišče nadomestimo s katerim koli listom v poddrevesu, katerega

koren je izbrisano vozlišče. Tako list enostavno zamenjamo z vozliščem, ki ga

ţelimo izbrisati. Kazalec, ki je prej kazal na list, nastavimo na NULL.

Vzemimo prikazan primer digitalnega drevesa, ki ga kaţe slika 16. Izbrisati

ţelimo vozlišče z vrednostjo 5. Najprej moramo poiskati ţeleno vozlišče v

drevesu. Ko ga najdemo, poiščemo poljuben list, ki je potomec vozlišča, ki ga

ţelimo izbrisati. Nato izbrišemo ţeleno vozlišče s ključem 5 in na njegovo mesto

vstavimo list. V našem primeru smo izbrali list s ključem 29. Kazalec, ki je kazal

na list vozlišča 25, postavimo na NULL.

Page 41: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

31

Slika 16: Izbris elementa 5

Slika 17: Digitalno drevo po izbrisu

Page 42: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

32

5 TRIE

Pod imenom trie se skriva struktura za shranjevanje drugačnih ključev. Ključi so

shranjeni v listih drevesa, notranje vozlišče pa so uporablja le za vzdrţevanje

strukture. Ta podatkovna struktura se uporablja za shranjevanje besednih nizov.

Izraz »trie« je predlagal E. Fredkin leta 1960. Iz sredine besede »retrieval«

(pridobivanje podatkov) je izluščil besedo »trie« [1].

Razen tega, da digitalno drevo hrani binarna števila, trie pa besedne nize, je trie

vsaj v teoriji v bistvu enak digitalnemu drevesu. V praksi pa obstaja precejšnja

razlika, saj so običajno deli ključev, s katerimi bomo imeli opravka, kar črke

abecede. To posledično pomeni, da bi imelo v primeru angleške abecede vsako

vozlišče 26 otrok, namesto dveh, kot jih ima digitalno drevo. To lahko prikaţemo

na primeru, ki ga kaţe spodnja slika.

Slika 18: Vozlišče v trie

Vozlišče je sestavljeno samo iz kazalcev. Prvih 26 je v nekakšnem polju; male

črke v vsakem od kazalcev otrok kaţejo na to, kar je napisano pod njimi. Zadnji

kazalec kaţe na zapis, ki vsebuje podatke. To je list, v katerem je shranjen

element. V nadaljevanju si poglejmo, kako uredimo vsebino v strukturi trie.

I. Vse besede, ki se začnejo s črko a, so razvrščene skupaj. Potem sledijo vse

besede, ki se začnejo z b, in tako naprej vse do besed, ki se pričnejo s črko

z.

Page 43: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

33

II. Pod skupino besed, ki se začnejo s črko a, vse besede, katerih druga črka je

a, so razvrščene skupaj, nato sledijo vse besede, katerih druga črka je b, in

tako naprej, podobno za vse besede, ki se začnejo na ostale črke abecede.

III. Pod vsako podskupino črk, katerih druga črka je a, so zdruţene vse besede,

katerih tretja črka je a,… in tako naprej [1].

Ker je misel na to, da bi narisali drevo z vsemi 26 kazalci v vozlišču, brezupna,

kot primer podajamo sliko, kjer ima vozlišče v drevesu kazalce od črke a do črke

e. Primer vsebuje besede: bc, dadac in dace.

Slika 19: Primer drevesa trie

Črte med vozlišči kaţejo kako je trie med seboj povezan. Prazna mesta kaţejo na

null.

Page 44: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

34

5.1 Iskanje podatkov v drevesu

Za vhod v trie uporabljamo posamezne črke ključa, na podlagi katerih najdemo

pot skozi drevo. Kot primer za iskanje vzemimo besedo lopar iz slike 20. Najprej

bomo iskali v skupini, katere prva črka je l (z uporabo črke l kot zapisa v polju

kazalcev v korenu drevesa). Potem nadaljujemo iskanje v skupini, ki je

podskupina prejšnje skupine, v kateri je druga črka o, nato sledi podskupina, v

kateri je tretja črka p in tako naprej. Če gremo skozi ključ od črke do črke, se

pomikamo navzdol po drevesu. To bi lahko delno primerjali s polnjenjem omare.

Pogledamo v kabinet D (to je najvišja stopnja drevesa), nato najdemo predal A

(naslednja stopnja navzdol). Znotraj tega predala najdete mapo s črko C.

V našem primeru smo imeli samo eno polje, ki ga vsebuje ključ, čeprav bi v

praksi lahko bili še drugi podatki. Kot primer lahko podamo primer slovarja. Če bi

naše drevo vsebovalo slovar, bi obstajala še polja za izgovorjavo, za izpeljanke, za

definicijo besede,…

Splošen opis algoritma za iskanje vpisov v trie je opisan v spodnjih vrsticah:

I. i=0.

II. kazalec kaţe na koren.

III. dokler kazalec ni null in je i manjši kot dolţina ključa k:

i. povečaj i.

ii. nastavi kazalec na ki-ti element polja otroka.

IV. če je kazalec null ali če so podatki trenutnega vozlišča null, potem iskani

vpis v drevesu ne obstaja.

V. sicer podatkovno polje kaţe na ţeleni vnos [1].

Na kratko lahko povemo, da smo našli element v drevesu takrat, če se pot izteče v

listu (če je zadnji znak besede v nekem listu). Če pa se zgodi, da ne moremo

nadaljevati poti po drevesu in nismo porabili vseh znakov besede, pomeni da niza

ni v drevesu.

Page 45: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

35

Poglejmo si primer iskanja po drevesu trie.

Slika 20: Drevo trie

Kot lahko vidimo iz slike drevesa, imamo v drevo vstavljene naslednje besede:

lopa, lopar, osa in sars. Poiskati ţelimo besedo lopar. Iskanje pričnemo v korenu

drevesa, kjer poiščemo prvo črko iskane besede (torej črke l). Nato se pomaknemo

po povezavi do naslednjega vozlišča z enakim znakom kot ga ima iskana beseda

(črka o). Tako po enakem postopku iščemo vozlišča iskane besede v drevesu, kot

kaţe slika 21. Ker nobeno od vozlišč ni kazalo na null, pomeni, da smo našli

iskano besedo.

Page 46: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

36

Slika 21: Iskanje elementa v drevesu trie

V primeru, da bi iskali besedo lokvanj, bi pri proceduri iskanja našli prve dve črki

v drevesu. Pri preverjali tretje črke (črke k), ne bi našli povezave do iskane črke,

kar bi pomenilo, da iskana črka ne obstaja.

5.2 Vstavljanje podatkov v drevo

Vstavljanje je nekoliko teţje, čeprav gre po zgledu postopka iskanja. Spet se

premikamo po drevesu navzdol, od nivoja do nivoja, kar pa usmerjajo črke

posameznega ţe vstavljenega ključa v drevo. Postopek vstavljanja bomo prikazali

na enakem primeru kot pri postopku iskanja. Ko vpišemo ključ oblike osel,

potrebujemo niz vozlišč, ki bodo zagotovila pot do listov, ki vsebujejo ključ. Na

začetku, ko pot še ne obstaja, jo gradimo sproti. Če korena drevesa ni, ga moramo

ustvariti. Če del poti ţe obstaja, potem ji glavna zanka v proceduri vstavljanja

sledi. Če bo doseţena »slepa ulica« še pred koncem ključa, potem je potrebno

Page 47: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

37

ustvariti novo vozlišče, ki bo omogočilo nadaljevanje, ustvarjanje preostale

manjkajoče poti. Ko smo ustvarili novo vozlišče, smo postavili vse njegove

kazalce na null.

Funkcija vstavljanje nam vrne vrednost true, če je bilo vstavljanje uspešno in

vrednost false, če beseda ţe obstaja v drevesu (duplikat).

I. če koren ne obstaja:

i. ustvarimo koren drevesa;

ii. vse kazalce črk korena postavimo na null;

II. drugače za vsako črko iz ključa novega elementa:

i. če kazalec iz tekoče črke kaţe na null ustvarimo novo vozlišče s

kazalci, ki vsi kaţejo na null;

ii. sicer se spustimo v vozlišče, na katero kaţe kazalec;

III. če tekoči kazalec kaţe na null:

i. vstavimo nov element in vrnemo true;

ii. sicer vrnemo false;

Predvidevamo, da koren drevesa ţe obstaja. Vstaviti ţelimo besedo osel. Najprej

preverimo, če obstaja črka o. Črka o ţe obstaja v drevesu, zato preverimo, če

obstaja črka s. Črka s prav tako ţe obstaja v drevesu. Naslednja iskana črka je e,

ker pa pot ţe vstavljene besede osa ne vodi k črki e, moramo ustvariti novo

vozlišče za črko e. Ker ne moremo dopuščati dvojnikov ključev v drevesu, se

moramo pred vstavitvijo novega vpisa prepričati, da na tem mestu ni ničesar. Če

kazalec ni null, potem je beseda ţe v drevesu in vrnemo vrednost false, ki

opozarja klicajoči program, da predmet ni bil vstavljen.

Page 48: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

38

Slika 22: Vstavljanje elementa v drevo

5.3 Brisanje podatkov iz drevesa

Začetek postopka brisanja je podoben kot pri postopku iskanja, saj moramo

besedo najprej poiskati v drevesu in šele nato jo lahko izbrišemo. Dokler ima

iskana beseda, ki jo ţelimo izbrisati, enak začetek kot beseda, ki je ţe v drevesu,

se sprehajamo po drevesu od črke do črke. Če je ključ del poti, ki vodi do drugih

ključev, potem moramo izbrisati samo tisto podatkovno vozlišče, ki vsebuje ključ

in z njim povezane podatke. Če se ključ, ki ga ţelimo izbrisati, nahaja na koncu

poti, potem moramo ponoviti naše korake nazaj gor po poti in brišemo pot, dokler

ne pridemo do vozlišča, katerega podatkovno polje ni null. Pozorni moramo biti

na vozlišča, ki imajo dodatno povezavo do drugega vozlišča. V tem primeru jih ne

smemo izbrisati [1].

Funkcija brisanja vrne false, če ni korena drevesa ali če med iskanjem naleti na

vozlišče, ki kaţe na null. Drugače vrne true. Postopek brisanja poteka takole:

Page 49: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

39

I. če v drevesu še ni korena, potem funkcija brisanja vrne false;

II. po drevesu iščemo besedo, ki jo ţelimo izbrisati:

i. pomikamo se od vozlišča do vozlišča;

ii. če naletimo na vozlišče, ki kaţe na null, funkcija vrne false, saj

nam kazalec na null kaţe na to, da beseda ne obstaja v drevesu;

iii. če pridemo do konca besede in ta ne kaţe na null in nima otrok,

potem funkcija vrne true (to nam pove, da bodo podatki

izbrisani);

III. brisanje se vrši v nasprotni smeri s pomikanjem nazaj gor po drevesu;

IV. brisanje črk besede poteka tako dolgo, dokler ne naletimo na črko, ki jo

uporablja katera od drugih besed v drevesu (glej sliko 23);

Napisano prikaţimo še na primeru. Izbrisali bomo besedo lopar. Najprej izvedemo

iskanje besede lopar, ko pridemo do konca besede lopar, se prične postopek

brisanja.

Page 50: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

40

Slika 23: Brisanje elementa iz drevesa

Brisanje podatkov pričnemo v nasprotni smeri, tako da se pomikamo nazaj gor po

drevesu. Če črka nima povezav na otroke, jo lahko izbrišemo. Najprej izbrišemo

zadnjo črko besede lopar (črko r), nato se pomaknemo en nivo više. Pomaknemo

se po povezavi navzgor po drevesu do naslednjega vozlišča, kjer je črka a. Ker

ima to vozlišče povezavo do nekega drugega znaka, ga ne smemo izbrisati, ker

povezuje besedo lopa. Tukaj se brisanje konča.

Kot smo ţe omenili, sta si v teoriji digitalno drevo in trie podobna. Če si

predstavljamo trie, ki shranjuje binarne podatke, vidimo podobnost. V tem

primeru polje otroka zahteva le dva kazalca, enega za predstavitev 0 in enega za

predstavitev 1. Če bi ju preimenovali na levo in desno, potem podobnost med

njima postane še jasnejša.

Page 51: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

41

6 PATRICIA

Ogledali si bomo še zadnjo podvrsto baznih dreves. Patricia je še ena metoda za

pridobivanje niza znakov na podlagi drevesa. Ime patricia izhaja iz kratice:

»Practical Algorithm To Retrieve Information Coded In Alphanumeric«, kar bi v

slovenščino lahko prevedli kot praktični algoritem za vzpostavitev informacij

kodiranih v alfanumerični obliki. Patricia drevo je spremenjena različica

digitalnega drevesa, ki zmanjša število poskusov, potrebnih za premik po drevesu.

Besedilo, ki ga je treba iskati, ni vključeno v drevo in je shranjeno na drugem

mestu, v pomnilniku ali v datoteki. Drevo vsebuje kazalce do ključev v besedilu.

Iskani ključ je najden, če se kjerkoli v besedilu nahaja niz, katerega predpona je

enaka ključu. Omenimo, da to pomeni, da se lahko ujemanje podniza nanaša od

dela, kjer je prišlo do ujemanja s ključem, vse do konca besedilnega niza. Iz tega

sledi, da je patricia drevo prilagojeno za vsako besedilo posebej. Patricia drevesa,

ki nastane iz neke datoteke, ne moremo uporabiti za iskanje v drugi datoteki [1].

O tej metodi izgradnje dreves bomo pričeli razmišljati kot o poenostavljenem

digitalnem drevesu. Pri primeru digitalnega drevesa imamo pogosto vozlišče le z

enim otrokom. V tem primeru se lahko spustimo samo v enega otroka, kljub temu

pa moramo v vozlišču izvesti test. To pomanjkljivost poskušamo izboljšati s

patricia drevesom.

Kot lahko razberemo ţe iz imena te vrste dreves, je ta vrsta dreves oblikovana kot

algoritem, ki znotraj drevesa išče neko besedilo. V spremenjeni obliki lahko

iščemo tudi druge vrste podatkov, ki jih lahko zapišemo z bitnim nizom.

6.1 Pravila patricia drevesa

Kot vsaka vrsta dreves ima tudi patricia drevo svoja pravila, ki se jih moramo

drţati, če ţelimo zgraditi tako drevo, iskati elemente po njem ali jih brisati.

Page 52: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

42

I. Vsako vozlišče ima bitni indeks. To je številka, ki zaseda mesto poleg

vozlišča in je potrebna za bitno primerjavo pri operaciji iskanja po

drevesu.

Slika 24: Primer vozlišča

Kot primer si poglejmo sliko 24, ki nam kaţe vozlišče x z bitnim indeksom 2. Pri

izvajanju procedure iskanja pridemo do ţelenega vozlišča, naredimo primerjavo

na podlagi bitnega indeksa s ključem, ki ga iščemo in na podlagi tega se po

drevesu usmerimo levo če je ta 0 in desno če je 1.

II. Bitni indeks danega vozlišča se mora v drevesu zmanjševati, ko se

premikamo navzdol po drevesu. Tako bo bitni indeks roditeljevega

vozlišča v drevesu vedno večji od njegovih otrok. Kot bomo videli

kasneje, je lahko v nekaterih oblikah drevesa tudi ravno obratno.

III. Operacija iskanja po drevesu je zaključena, ko sledimo povezavi navzgor,

saj nas le-ta pripelje nazaj na vozlišče.

IV. Ključi v patricia drevesu so bitni nizi. Bitni indeksi v ključu so označeni v

vrstnem redu od leve proti desni, kot kaţe spodnji primer:

Bitni

indeks: 4 3 2 1 0

Ključ: 1 1 0 0 1

Tabela 3: Zapis ključa

Pri proučevanju drevesa patricia iz različnih literatur in virov smo odkrili nekaj

razlik. Kot prvo smo zaznali razlike glede smeri številčenja bitnega indeksa, saj se

ponekod pojavi štetje od 0 naprej - naraščajoče, drugje pa padajoče, torej proti 0.

Page 53: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

43

Do razlike pride tudi pri razumevanju skrajno leve vrednosti, kjer je le-ta ponekod

razumljena kot vrednost 0, drugod pa kot 1. Naslednja razlika se kaţe glede

razvrščanja elementov v drevesu po bitnem indeksu, saj se ponekod pojavi, da

bitni indeks od korena narašča, drugje pa pada. Za laţje razumevanje bomo

povedano prikazali še v tabeli.

Način 1: Način 2:

Številčenje bitnega

indeksa: 6 5 4 3 2 1 0 0 1 2 3 4 5 6

Skrajno leva vrednost: 1 0

Razvrščanje v drevo

glede na bitni indeks:

Koren drevesa ima

največjo vrednost bitnega

indeksa. S pomikanjem

po drevesu le-ta pada.

Koren drevesa ima

najmanjšo vrednost

bitnega indeksa. S

pomikanjem po drevesu

le-ta narašča.

Tabela 4: Načini številčenja bitnega indeksa

V tem diplomskem delu bomo uporabljali način 1.

6.2 Vstavljanje podatkov v drevo in razvijanje drevesa

Obstajata dva postopka povezana z gradnjo te vrste drevesa: vstavi v obstoječe

drevo in vstavi v novo drevo.

V obeh primerih se izvedejo naslednji koraki:

1. izvede se (neuspešen) postopek iskanja ključa, v katerem najdemo

najbliţje vozlišče;

2. poišče se bitni indeks novega vozlišča;

3. poišče se poloţaj novega vozlišča v drevesu;

4. vzpostavijo se povezave;

Page 54: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

44

Vstavi v novo drevo:

Ta postopek uporabljamo v primeru, ko smo med iskanjem najbliţjega vozlišča

našli vrednost null.

i. izvedi postopek iskanja po drevesu za novo vozlišče

ii. bitni indeks novega vozlišča je enak poziciji skrajno leve vrednosti v

ključu, ki ima vrednost 1. Za boljše razumevanje si poglejmo naslednji

primer, kjer imamo ključ 00110.

Bitni

indeks: 4 3 2 1 0

Ključ: 0 0 1 1 0

Tabela 5: Zapis ključa

Kot smo ţe povedali, je bitni indeks vozlišča tisti indeks, ki ima prvo

skrajno levo vrednost enako 1. Iz tabele lahko vidimo, da je v našem

primeru bitni indeks enak 2.

iii. vstavimo vozlišče v drevo. Imamo samo eno mesto za vstavitev novega

elementa.

iv. vzpostavitev povezave. Za novo vozlišče v novo osnovanem drevesu bo

leva povezava vedno nepovezana, desna povezava pa bo vedno povezava

navzgor, ki kaţe sama nase.

Slika 25: Vozlišče po vzpostavitvi povezav

Page 55: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

45

Vstavi v obstoječe drevo:

Ta postopek se uporablja za večino vstavitev vozlišča v drevo.

i. izvedi postopek iskanja novega vozlišča po drevesu. Ker vozlišča, ki ga

ţelimo vstaviti, še ni v drevesu, iskanje zaključimo z znanim najbliţjim

vozliščem in ga bomo uporabili za ugotovitev bitnega indeksa.

ii. bitni indeks novega vozlišča je skrajno levi bit, kjer se ključ novega

vozlišča in ključ najbliţjega vozlišča razlikujeta. Kot primer vzemimo

novo vozlišče X - 00101, najbliţje vozlišče Y – 00011.

Bitni

indeks: 4 3 2 1 0

Ključ X: 0 0 1 0 1

Ključ Y: 0 0 0 1 1

Tabela 6: Dvojiški zapis ključa x in y

V našem primeru bo bitni indeks ključa X enak 2, saj je skrajno levi bit,

kjer se ključ X in Y razlikujeta, na poziciji 2.

iii. vstavimo vozlišče v drevo. Mesto, kamor smo vstavili vozlišče, je odvisno

od bitnega indeksa novega vozlišča. Če je niţji od tistega najbliţjega

vozlišča, potem ga vstavimo pod njega, sicer pa nad njega.

a) nov bitni indeks < najbliţji bitni indeks:

Če je bitni indeks novega vozlišča niţji, potem ga lahko enostavno

vstavimo na mesto povezave navzgor, ki je rezultat neuspešnega

iskanja.

b) nov bitni indeks > najbliţji bitni indeks:

To je lahko včasih teţavno, saj se moramo za to, da najdemo ustrezno

mesto za novo vozlišče, pomikati nazaj navzgor po drevesu. Novo

Page 56: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

46

pozicijo določimo s premikanjem navzgor po drevesu do najbliţjega

vozlišča in vstavimo novo vozlišče na prvo veljavno mesto določeno

na podlagi bitnega indeksa.

iv. določitev povezav. Ena od povezav bo vedno vodila nazaj na novo

vozlišče, kar je določeno s ključem novega vozlišča in njegovega bitnega

indeksa. Če je vrednost na bitnem indeksu novega vozlišča enaka 0, potem

bo leva povezava kazala nazaj na novo vozlišče. Če pa ima vrednost 1,

potem bo pa desna povezava kazala nazaj navzgor, nase. Druga povezava

bo kazala bodisi nazaj na najbliţje vozlišče (za en nivo gor ali dol), ali, če

smo se morali pomakniti gor po drevesu za nekaj nivojev, bo druga

povezava kazala na vozlišče pod novim.

Da bi do sedaj povedano teorijo še bolje razumeli, bomo razloţeno teorijo

prikazali še na podlagi praktičnega primera. V patricia drevo bomo vstavili

podatke, ki jih kaţe spodnja tabela:

Bitni

indeks: 4 3 2 1 0

Ključ A: 0 1 0 0 1

Ključ B: 1 1 1 0 1

Ključ C: 1 0 1 0 1

Ključ D: 0 1 1 1 0

Ključ E: 0 1 0 1 1

Tabela 7: Ključi, ki jih bomo vstavili v patricia drevo

Vstavimo ključ A – 01001:

Ker drevo še ne obstaja, ne izvajamo procedure iskanja. Uporabili bomo postopek

vstavi v novo drevo.

i. poiščemo bitni indeks. V našem primeru je skrajno levi bitni indeks, ki ima

vrednost enako 1, enak 3.

Page 57: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

47

ii. vzpostavimo povezavo. Kot smo zapisali, je skrajno leva povezava

nepovezana (za novo vozlišče drevesa), desna pa kaţe nazaj na samega

sebe, saj je vrednost bitnega indeksa enak 1, kar pomeni, da gremo v desno

stran.

Slika 26: Vstavitev ključa A

Vstavimo ključ B – 11101:

i. izvedemo iskanje ključa B v našem ţe obstoječem drevesu. Začnemo pri

korenu drevesa (to je ključ A), ki ima bitni indeks 3. Preverimo kakšno

vrednost nosi bitni indeks 3 v ključu B. Ker je omenjeni bit ključa B enak

1, gremo naprej po drevesu v desno poddrevo, kjer pa naletimo na

povezavo, ki kaţe nazaj na ključ A. Tako vemo, da je ta ključ naše

najbliţje vozlišče, zato uporabimo obstoječi postopek gradnje drevesa.

ii. poiščemo bitni indeks. Primerjamo ključa A in B in iščemo najbolj levi bit,

v katerem se omenjena ključa razlikujeta.

Bitni

indeks: 4 3 2 1 0

Ključ A: 0 1 0 0 1

Ključ B: 1 1 1 0 1

Tabela 8: Primerjava ključev A in B

Najbolj levi bit, kjer se ključa razlikujeta, je bit 4, torej ima ključ B bitni

indeks 4.

Page 58: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

48

iii. poiščemo poloţaj. Ker je bitni indeks ključa B večji od bitnega indeksa

ključa A, mora biti ključ B v drevesu vstavljen nad ključ A. Premikamo se

gor po drevesu, da najdemo prvo razpoloţljivo mesto. V tem primeru je to

mesto direktno nad ključem A.

iv. vzpostavitev povezave. Na bitnem indeksu 4 ima ključ B vrednost 1. To

nam pove, da bo desna povezava kazala nazaj na ključ B, leva povezava pa

bo kazala na ključ A.

Slika 27: Patricia po vstavitvi ključa B

Vstavimo ključ C – 10101:

i. spet najprej izvedemo postopek iskanja po drevesu, da bi našli ključ C.

Pričnemo pri korenu drevesa in preverimo številko bitnega indeksa korena,

ki je v našem primeru 4. Nato preverimo kakšno vrednost vsebuje ključ C

na bitnem indeksu 4. Ker vsebuje vrednost 1, pomeni, da gremo na desno.

Tu naletimo na povezavo, ki nas vodi nazaj na ključ B. To nam pove, da je

ključ B naše najbliţje vozlišče.

ii. poiščemo bitni indeks za ključ C. Iščemo najbolj levi bit, kjer se ključa C

in B razlikujeta.

Page 59: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

49

Bitni

indeks: 4 3 2 1 0

Ključ B: 1 1 1 0 1

Ključ C: 1 0 1 0 1

Tabela 9: Primerjava ključev B in C

Tabela 9 kaţe, da je najbolj levi bit bit 3. Zato je bitni indeks vozlišča, ki

vsebuje ključ C, enak 3.

iii. vstavimo vozlišče. Ker je bitni indeks novega vozlišča 3 in je manjši od

indeksa ključa B (ki je 4), lahko C enostavno vstavimo na povezavo, ki

smo ji sledili in nas je pripeljala nazaj na ključ B in je bila desna povezava

ključa B.

iv. vzpostavimo povezavo. Ključ C ima na bitnem indeksu 3 vrednost 0, zato

postane leva povezava tista, ki kaţe sama nase, ključ B pa dobi desno

povezavo.

Slika 28: Patricia po vstavitvi ključa C

Vstavimo ključ D – 01110:

i. najprej izvedemo iskanje ključa D v drevesu. Iskanje pričnemo v korenu

drevesa, kjer nas ključ D pripelje do ključa A (ključ D ima vrednost 0 na

bitu 4, zato gremo levo). Preverimo vrednost bitnega indeksa 3 ključa D.

Page 60: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

50

Ta ima vrednost 1, zato gremo desno. Povezava na desni nas pripelje nazaj

na ključ A. To pomeni, da je naše najbliţje vozlišče, vozlišče s ključem A.

ii. poiščemo bitni indeks ključa D. Najbolj levi bit, kjer se razlikujeta ključa

D in A, ima indeks 2. Zato bitni indeks vozlišča D postane 2.

iii. poiščemo poloţaj volišča. Ker je bitni indeks novega vozlišča 2 in je

manjši od indeksa vozlišča A, lahko D vstavimo kar pod vozlišče A. Tako

vozliče D nadomesti povezavo, ki je kazala nazaj na A.

iv. vzpostavitev povezave. Ključ D ima na bitnem indeksu 2 vrednost 1, zato

dobi desno povezavo, leva povezava vozlišča D pa bo kazala na vozlišče

A.

Slika 29: Patricia po vstavitvi ključa D

Vstavimo ključ E – 01011:

i. postopek iskanja ključa E nas vodi skozi pot B→A→D→A, zato je

vozlišče A naše najbliţje vozlišče.

ii. iščemo bitni indeks. Bitni indeks vozlišča E je skrajno levi bit, kjer se

ključa E in A razlikujeta. Razlikujeta se na bitnem indeksu 1.

Page 61: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

51

iii. vstavimo E v drevo. Bitni indeks ključa E je 1, kar pomeni, da moramo

vstaviti E pod vozlišče A. Ker ima A pod sabo ţe vozlišče D z bitnim

indeksom 2, ki je spet večji od bitnega indeksa ključa E, se spet

pomaknemo za en nivo niţe. Na vozlišču D povezava, ki je kazala nazaj na

A, sedaj nadomesti naše novo vozlišče.

iv. vzpostavitev povezave. Ker ima E vrednost 1 na bitnem indeksu 1, bo

desna povezava kazala nazaj na E, leva povezava bo vodila nazaj na ključ

A.

Slika 30: Patricia po vstavitvi ključa E

Poudariti je treba še dejstvo, ki ga moramo upoštevati, saj patricia drevesa, kot

ostala digitalna iskalna drevesa ne obravnavajo dvojnikov. Zato imejmo v mislih,

da ne moremo vstaviti duplikatov ključev v patricia drevo brez nevšečnosti.

Algoritem vstavljanja novega elementa v patricia drevo bi lahko povzeli takole:

I. če koren še ne obstaja, potem je novo vozlišče koren.

II. drugače iščemo v obstoječem drevesu ključ novega elementa.

Page 62: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

52

III. če iskanje vrne kazalec na ključ, potem je novi ključ duplikat, in

zaključimo.

IV. drugače najdi vozlišče, ki se zadnje ujema v bitnem vzorcu s ključem

novega vozlišča (mesto prvega različnega bita).

V. ustvari novo vozlišče:

i. bitni indeks kaţe mesto prvega različnega bita.

ii. novo vozlišče je eno od njegovih lastnih otrok.

VI. vključi novo vozlišče v drevo.

Algoritem vstavljanja v drevo lahko implementiramo na naslednji način.

Napišemo ga kot bool funkcijo, saj njegova vrnjena vrednost pove ali je bilo

vstavljanje uspešno ali ne. Funkcija vrne true, če je bilo vstavljanje uspešno in

false, če je ključ duplikat ali predpona ţe obstoječega ključa v drevesu.

Patricia drevesa so načeloma dobro uravnoteţena. Celovita analiza patricia

drevesa je preteţka, da bi jo na enostaven način razloţili. V splošnem velja, da so

stroški vstavljanja in iskanja O(log n). Pri tem je pomembno, da v algoritmu

uporabljamo le bitne primerjave in ne primerjave nizov.

6.3 Iskanje podatkov v drevesu

V patricia drevo so lahko vstavljene posamezne črke, besede ali besedni nizi, ki se

obravnavajo kot nizi črk. Vsako vozlišče je označeno z bitnim indeksom, kar je

treba upoštevati pri odločanju, v katero smer bo šla razvejitev v drevesu. Če

vstavljamo cele besede, potem je smiselna ideja, da po vsakem besednem ključu

dodamo presledek. To nam pomaga, da lahko ločujemo trenutni ključ od ključa, ki

sledi. Poglejmo primer. Če sta v drevesu ključa JAN in JANEZ brez dodanega

presledka, drevo razume besedo JAN kot predpono ključa JANEZ. Besede JAN

ne more shraniti.

Page 63: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

53

Za primer iskanja vzemimo patricia drevo s slike 30. Predpostavimo, da bomo

iskali ključ E. Bitni indeks vozlišča B pove, kateri bitni indeks moramo preveriti v

ključu E. Ključ E ima naslednji bitni niz: 01011. Preveriti moramo vrednost

bitnega indeksa 4. Bitni indeks 4 ključa E je 0, kar pomeni, da se bomo pomaknili

v levo stran. Leva povezava vozlišča B nas popelje do vozlišča A, kjer bomo

preučili bitni indeks 3. Ključ E ima v tem bitnem indeksu vrednost 1, zato gremo

desno. Desna povezava vozlišča A nas pripelje do vozlišča D, kjer preverimo bitni

indeks 2. Vrednost bitnega indeksa ključa E je 0, zato gremo levo. Povezava nas

pripelje do vozlišča E, kjer moramo preveriti bitni indeks 1. Vrednost v tem

bitnem indeksu je 1, kar pomeni, da se bomo pomaknili desno. Pomik v desno nas

pripelje nazaj k istem vozlišču, kar pomeni, da smo našli ţelen ključ in tako lahko

zaključimo postopek iskanja.

Na kratko lahko zapišemo algoritem iskanja takole:

I. začnemo pri korenu in če ţe obstaja preverimo njegov bitni indeks.

II. ponavljamo dokler tekoči kazalec ne kaţe navzgor:

i. preverimo bitni indeks vozlišča;

ii. glede na vrednost bitnega indeksa se pomaknemo v levo ali

desno stran (v levo, če ima bitni indeks vrednost 0 in v desno,

če ima vrednost 1);

Page 64: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

54

7 OPIS PROGRAMA

V programskem jeziku C++ smo realizirali program za delo z digitalnimi drevesi.

V programu lahko izvršimo postopke gradnje oziroma vstavljanja v digitalno

drevo, iskanje po drevesu, brisanje podatka iz drevesa ter izpis drevesa. V meniju

moramo izbrati številko za izvajanje posameznega postopka. 1 - za vstavitev

podatka v digitalno drevo, 2 – za izpis digitalnega drevesa, 3 – za iskanje

elementa po digitalnem drevesu, 4 – za brisanje podatka iz digitalnega drevesa in

5- za izhod iz programa.

Slika 31: Meni programa gradnje digitalnega drevesa

7.1 Vnos podatkov in potek programa

Preden lahko izvršimo postopke iskanja, brisanja in izpisovanja, moramo vstaviti

podatke v drevo. Zato je prvi potreben korak vnos podatkov v drevo.

Podatke vnašamo v digitalno drevo z vpisom številke iz menija, ki predstavlja

vstavljanje podatka, tj. 1. Vstavimo prvi podatek, ki postane koren drevesa, ostali

podatki se vstavljajo glede na bitne vrednosti na posameznem bitu.

Page 65: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

55

Slika 32: Vstavljanje podatka v drevo

Program se izvaja tako dolgo, dokler ne vpišemo številko za izhod iz programa, tj.

številko 5.

7.2 Delovanje programa za primer digitalnega drevesa

Kot smo ţe omenili, mora digitalno drevo vsebovati podatke, ki jih lahko potem

izpišemo, iščemo in brišemo. V drevo smo en za drugim vstavljali naslednje

podatke: 24, 17, 36, 82, 19, 38, 15 in 45.

Vstavljanje podatkov:

Postopek vstavljanja podatka vstavi podatek v drevo glede na njihovo vrednost v

bitu 0, bitu 1, bitu 2, itd. Če je vrednost bita 0 enaka 0, potem bo podatek

vstavljen v levo poddrevo, drugače pa v desno poddrevo. Če drevo še ne obstaja

(koren drevesa ne obstaja), potem bo prvi vstavljeni podatek postal koren drevesa.

Drugi vstavljeni element se bo ţe vstavljal po pravilu o vrednosti bita. Ker ima

podatek 17 (100012) na bitu 0 vrednost 1, bo vstavljen v desno poddrevo.

Postopek vstavljanja se nadaljuje po povedanem pravilu. Pred vsako vstavitvijo

novega podatka preverimo, ali podatek, ki ga ţelimo vpisati, ţe obstaja v drevesu,

saj ne dopuščamo dvojnikov v drevesu. Če ţelimo vstaviti podatek, ki ţe obstaja v

drevesu, nam program javi opozorilo, da števila ne moremo vstaviti, ker je ţe v

drevesu. Pri vsakem vpisu podatka v drevo se izpiše dvojiški zapis podatka, v

Page 66: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

56

obratnem zaporedju ničel in enic (razen pri prvem elementu, ki postane koren

drevesa).

Izpis podatkov:

Izpis digitalnega drevesa izvajamo po principu LSD, najprej levi otrok, nato

roditelj in na koncu še desni otrok. Tako bi izpis digitalnega drevesa prej podanih

podatkov izgledal tako, kot kaţe slika 34.

Slika 33: Izpis drevesa

Iskanje podatkov:

Iskanje podatka v digitalnem drevesu poteka po postopku pregleda dvojiškega

zapisa iskanega podatka. Vzemimo, da ţelimo poiskati podatek 82. Dvojiški zapis

števila je 10100102. Postopek iskanja podatka poteka tako dolgo, dokler koren ne

kaţe na NULL in dokler vrednost korena ni enaka vrednosti podatka, ki smo ga

vstavili. Če koren vozlišča kaţe na NULL, pomeni, da podatka ni v drevesu in

funkcija bool vrne false. Funkcija vrne true, če je bil iskani podatek najden.

Page 67: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

57

Slika 34: Iskanje podatka v drevesu

Če je vrnjena vrednost true, se izpiše Stevilo je v drevesu!, sicer se izpiše Stevila

ni v drevesu!.

Brisanje podatkov:

Vzemimo, da ţelimo izbrisati vozlišče s ključem 36. Najprej moramo poiskati

ţeleno vozlišče v drevesu. Ko ga najdemo, si v nov kazalec shranimo njegovo

mesto, da lahko pozneje vanj zapišemo vrednost lista, s katerim ga zamenjamo.

Nato poiščemo list, ki je potomec vozlišča, ki ga ţelimo izbrisati. V vozlišče, ki

ga ţelimo izbrisati vpišemo vrednost prej iskanega lista. Ker smo list pomaknili

na mesto izbrisanega, moramo kazalec, ki je kazal na ta list nastaviti na NULL.

Slika 35: Določitev števila za izbris

Page 68: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

58

Slika 36: Izpis drevesa po brisanju

Page 69: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

59

ZAKLJUČEK

Drevesa so med najbolj uporabnimi podatkovnimi strukturami na področju

računalništva. V diplomskem delu smo opisali manj znano obliko dreves, ki se

imenujejo bazna drevesa. Podrobni obravnavi različnih tipov baznih dreves je

sledila v programskem jeziku C ++ realizirana ena od podvrst baznih dreves.

Najprej smo za laţje razumevanje nadaljnje snovi razloţili pojme algoritem,

podatkovna struktura in drevo. Kot osnovo oziroma rdečo nit nadaljnjih poglavij,

smo najprej obdelali in razloţili urejanje z radiksom, ki je na nek način predpogoj

za razumevanje baznih dreves.

Osnovna oblika baznih dreves temelji na dvojiških drevesih, ki hranijo podatke v

drevesu na podlagi posameznih bitov v bitnem nizu. Prednost te vrste dreves je v

dejstvu, da ni potrebna uporaba celega ključa, ampak samo del ključa. Potrebno je

omeniti tudi dejstvo, da ne obstaja dogovor kako številčiti bite ključa. Nekateri jih

številčijo od leve strani proti desni, drugi jih številčijo od desne proti levi. Če

izberemo moţnost številčenja od leve proti desni strani, potem moramo poznati

najdaljši ključ, saj moramo poznati skrajno levo pozicijo bita. Nekateri jih začnejo

številčiti z 0, drugi pa z 1, torej to pomeni, da je kot prvi bit razumljeni bit 0 ali da

je kot prvi bit razumljeni bit 1.

Bazna drevesa obsegajo tri pomembne podvrste, in sicer: digitalno drevo, trie in

patricia drevo.

Prva obravnavana podvrsta baznih dreves so digitalna drevesa. Za digitalna

drevesa velja, da so ključi predstavljeni kot binarni nizi. Digitalna drevesa se ne

izkaţejo najbolje, če so ključi, ki jih vstavljamo v drevo, nizi znakov. V tem

primeru je premikanje in testiranje bitov bolj zapleteno, saj moramo takrat vzeti v

obzir število bitov za znak (sedem ali osem) in moramo nekako urediti premik za

celotni niz, ko smo prišli na konec znaka. Za shranjevanje niza znakov, je zato

vpeljano drevo trie. Trie je struktura shranjevanja ključev samo v listih drevesa,

saj so notranja vozlišča uporabljena le za vzdrţevanje strukture in ta struktura se

Page 70: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

60

uporablja za shranjevanje besednih nizov. V teoriji izgledala obe prej omenjeni

podvrsti baznih dreves zelo podobni. Ločuje ju dejstvo, da digitalno drevo

razpolaga z binarnimi števili, trie pa z besednimi nizi. Razlika se kaţe tudi v

številu otrok, ki ga ima vozlišče v posamezni podvrsti. Vozlišče v digitalnem

drevesu ima največ dva otroka, medtem, ko ima v trie vsako vozlišče 26 otrok,

oziroma toliko, kolikor je črk v abecedi.

Na koncu je opisana zadnja podvrsta baznih dreves, patricia drevo. Ime patricia

izhaja iz kratice: »Practical Algorithm To Retrieve Information Coded In

Alphanumeric«, kar bi v slovenščino lahko prevedli kot praktični algoritem za

vzpostavitev informacij kodiranih v alfanumerični obliki. Patricia drevo je

spremenjena različica digitalnega drevesa, ki zmanjša število poskusov, potrebnih

za premik po drevesu. Značilnost te strukture je, da v resnici ni drevo, saj zaradi

povezav, ki jih vsebuje, lahko nastanejo cikli. Ker pa se v večini primerov

uporablja kot drevo, jo kljub temu imenujemo »drevo«.

V zadnjem poglavju smo opisali program za gradnjo in urejanje digitalnega

drevesa. Program smo predstavili na podlagi konkretnega primera. Programsko

kodo programa smo dodali kot prilogo.

Page 71: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

61

LITERATURA

[1] Parsons, T. W. Introduction to algorithms in Pascal, J. Wiley & Sons, New

York, 1995.

[2] Sedgewick, R. Algorithms in Java, Third edition (Parts 1-4): Fundamentals,

Data Structures, Sorting, Searching, Addison-Wesley, New York, 2003.

Pridobljeno 16.3.2010, iz

http://books.google.si/books?id=hyvdUQUmf2UC&printsec=frontcover&sou

rce=gbs_v2_summary_r&cad=0#v=onepage&q=&f=false

[3] Kozak, J. Podatkovne strukture in algoritmi, DMFA Slovenije, Ljubljana

1997.

[4] Kononenko, I., Robnik Šikonja, M. in Bosnić, Z. Programiranje in algoritmi,

Fakulteta za računalništvo in informatiko, Ljubljana, 2008.

[5] Domiter, J. Algoritmi urejanja, diplomsko delo, Pedagoška fakulteta, Maribor,

2005.

[6] Allison, L. Algorithms and data structures. Pridobljeno 20.3.2010, iz

http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Radix/.

[7] Radix trees. (b.d.). Pridobljeno 20.3.2010, iz

http://www.doc.ic.ac.uk/~ajf/Teaching/Haskell/Revision3.pdf.

[8] Felstead, D. How to build Patricia Tries. Pridobljeno 25.4.2010, iz

http://goanna.cs.rmit.edu.au/~stbird/Tutorials/patricia.pdf.

Page 72: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

62

PRILOGA

Program, ki smo ga predstavili v sedmem poglavju, je v prilogi zapisan v celoti, v

programskem jeziku Microsoft Visual C++.

#include "stdafx.h"

#include <iostream.h>

#define x 8

class CVozlisce

{

public:

{konstruktor, ki ustvari vozlišče s podatkom podatek}

CVozlisce(int podatek)

{

kljuc=podatek;

levi_otrok=NULL;

desni_otrok=NULL;

}

{konstruktor, ki ustvari vozlišče s podatkom podatek in kazalcem na levega in

desnega otroka}

CVozlisce(int podatek, CVozlisce* levi, CVozlisce* desni)

{

kljuc=podatek;

levi_otrok=levi;

desni_otrok=desni;

}

~CVozlisce()

{

if (levi_otrok!=NULL) delete levi_otrok;

if (desni_otrok!=NULL) delete desni_otrok;

}

int VrniPodatek() {return kljuc;} {vrnemo podatek v vozlišču}

CVozlisce* VrniLevegaOtroka(){return levi_otrok;} {vrnemo kazalec na levega

otroka vozlišča}

CVozlisce* VrniDesnegaOtroka(){return desni_otrok;} {vrnemo kazalec na

desnega otroka vozlišča}

Page 73: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

63

void SpremeniPodatek(int podatek) {kljuc=podatek;}

void SpremeniLevega(CVozlisce* levi) {levi_otrok=levi;} {spremenimo kazalec,

ki kaže na levega otroka vozlišča}

void SpremeniDesnega(CVozlisce* desni) {desni_otrok=desni;} {spremenimo

kazalec, ki kaže na desnega otroka vozlišča}

private:

int kljuc;

CVozlisce* levi_otrok;

CVozlisce* desni_otrok;

};

class CDrevo

{

public:

CDrevo() {koren=NULL;} {konstruktor, ki ustvari prazno drevo}

~CDrevo() {delete koren;}

CVozlisce* VrniKoren() {return koren;} {vrne kazalec na koren}

bool Prazen() {metoda, kjer vrnemo ali je drevo prazno}

{

if (koren==NULL)

return true;

else

return false;

}

void SpremeniKoren(CVozlisce* k) {koren=k;} {spremeni koren}

void Izpisi(CVozlisce* k); {izpiše elemente drevesa}

CVozlisce* koren;

};

void CDrevo::Izpisi(CVozlisce* k) {izpis digitalnega drevesa}

{

if (k!=NULL)

{

Izpisi(k->VrniLevegaOtroka()); {izpis levega otroka}

cout << k->VrniPodatek() << " "; {izpis starša}

Izpisi(k->VrniDesnegaOtroka()); {izpis desnega otroka}

}

}

Page 74: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

64

class CDigitalno_drevo : public CDrevo

{

public:

CDigitalno_drevo() {}

~CDigitalno_drevo() {}

void Vstavi(int podatek, int polje[x]); {metoda vstavi podatek v drevo}

bool Iskanje(int podatek, int polje[x]); {metoda poišče podatek v drevesu}

void Odstrani(int podatek, int polje[x]); {metoda odstrani podatek iz drevesa}

void Binarno(int podatek, int polje[x]); {metoda pretvori decimalno število v

dvojiško}

};

{metoda pretvori decimalno število v dvojiško in ga zapiše v polje}

void CDigitalno_drevo::Binarno(int podatek, int polje[x])

{

for (int i=0; i<x;i++) {ustvarimo polje samih ničel}

{

polje[i]=0;

}

cout<<"\n";

int ostanek;

int z=podatek;

{v polje se shrani dvojiški zapis podatka, v obratnem vrstnem redu}

for(i=0; i<x; i++)

{

if (z > 0)

{

ostanek=z%2;

z=z/2;

if (polje[i]!=ostanek) {če vrednost v polju ni enaka nič}

{

polje[i]=ostanek; {se spremeni}

}

else

{

polje[i]=ostanek; {drugače ostane enaka}

}

}

}

}

Page 75: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

65

{metoda vstavi element v drevo}

void CDigitalno_drevo::Vstavi(int podatek, int polje[x])

{

if (VrniKoren()==NULL)

{

CVozlisce* koren = new CVozlisce(podatek,NULL,NULL);

SpremeniKoren(koren);

}

else

{

CVozlisce* k=VrniKoren();

int i=0;

while(i<8)

{

if(polje[i]==0)

{ {če levi otrok še ne obstaja}

if (k->VrniLevegaOtroka()==NULL)

{

CVozlisce* novi = new CVozlisce(podatek,NULL,NULL);

k->SpremeniLevega(novi);break; {ustvari novo vozlišče,

ki postane levi otrok}

}

else

{

{če levi otrok obstaja, potem se v k shrani njegov kazalec}

k=k->VrniLevegaOtroka();

i++;

}

}

else if(polje[i]==1)

{ {če desni otrok še ne obstaja}

if (k->VrniDesnegaOtroka()==NULL)

{

CVozlisce* novi = new CVozlisce(podatek,NULL,NULL);

k->SpremeniDesnega(novi);break; {ga ustvarimo}

}

else

{

{če desni otrok obstaja, potem se v k shrani njegov kazalec}

k=k->VrniDesnegaOtroka();

i++;

}

}

}

}

}

Page 76: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

66

{metoda, s katero poiščemo podatek v drevesu}

bool CDigitalno_drevo::Iskanje(int podatek, int polje[x])

{

CVozlisce* k=VrniKoren();

int preverba=0;

int i=0;

{dokler k ni NULL in vrednost k-ja ni enaka podatku, ki ga iščemo}

while((k!=NULL)&&(k->VrniPodatek()!=podatek))

{

if(polje[i]==0) {če je vrednost v polju enaka 0}

{

k=k->VrniLevegaOtroka(); {kazalec premaknemo na naslednjega

levega otroka}

i++;

}

else

{

if(polje[i]==1)

{

k=k->VrniDesnegaOtroka(); {kazalec premaknemo na

naslednjega desnega otroka}

i++;

}

}

}

if(k==NULL) {če k kaže na null, potem podatka ni v drevesu}

return false;

else

return true; {drugače podatek obstaja v drevesu}

}

{metoda izbriše vozlišče v digitalnem drevesu}

void CDigitalno_drevo::Odstrani(int podatek, int polje[x])

{

CVozlisce* k=VrniKoren();

CVozlisce* zacasni; {kazalec zacasni kaže na roditelja premaknjenega otroka}

CVozlisce* zabrisanje; {kaže na mesto, na katerem je vozlišče za izbris –

zamenjamo ga z listom}

int i;

if((podatek==k->VrniPodatek())&&(k->VrniLevegaOtroka()==NULL)

&&(k->VrniDesnegaOtroka()==NULL)) {če je podatek, ki ga želimo

izbrisati koren in še nima otrok}

{

Page 77: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

67

SpremeniKoren(NULL);

cout << "\nKoren drevesa je bil izbrisan!\n";

}

else

{

if((podatek==k->VrniPodatek())&&((k->VrniLevegaOtroka()!=NULL)

||(k->VrniDesnegaOtroka()!=NULL))) {ko iz drevesa brišemo koren, ki

ima vsaj enega otroka}

{

zabrisanje=k;

i=0;

}

else {ko brišemo poljubno vozlišče v levem ali desnem poddrevesu}

{

i=0;

while((k->VrniLevegaOtroka()!=NULL)||

(k->VrniDesnegaOtroka()!=NULL)) {iščemo vozlišče, ki ga želimo

izbrisati}

{

zacasni=k;

if (polje[i]==0) {glede na vrednost bita se pomikamo

levo (0) ali desno (1), dokler ne najdemo vozlišče, ki ga želimo izbrisati}

{

k=k->VrniLevegaOtroka();

i++;

}

else

{

k=k->VrniDesnegaOtroka();

i++;

}

if(podatek==k->VrniPodatek()) {če je vrednost vozlišča, ki

ga želimo izbrisati enaka vrednosti v trenutnem vozlišču, v kazalec zabrisanje

zapišemo mesto vozlišča, ki ga bomo izbrisali. Ko smo ga našli, prekinemo while

zanko}

{

zabrisanje=k;

break;

}

}

}

while((k->VrniLevegaOtroka()!=NULL)||

(k->VrniDesnegaOtroka()!=NULL)) {v poddrevesu vozlišča, ki ga

brišemo, iščemo list}

{

zacasni=k;

Page 78: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

68

if(k->VrniLevegaOtroka()!=NULL) {če obstaja levi otrok, se

pomaknemo v levo poddrevo, sicer v desno}

{

k=k->VrniLevegaOtroka();

polje[i]=0;

}

else

{

k=k->VrniDesnegaOtroka();

polje[i]=1;

}

i++;

}

zabrisanje->SpremeniPodatek(k->VrniPodatek()); {v vozlišče, ki je

označeno za brisanje (s kazalcem zabrisanje) vpišemo vrednost najdenega lista}

if(polje[i-1]==0) {zaradi premaknjenega lista na mesto izbrisanega,

moramo roditelju, ki zato nima več otroka, določiti kazalec na null}

{

zacasni->SpremeniLevega(NULL);

}

else

{

zacasni->SpremeniDesnega(NULL);

}

cout << "\nElement je bil izbrisan iz drevesa!\n";

}

}

int main(int argc, char* argv[]){

CDigitalno_drevo Digitalno;

int stevilo;

int izbiranje;

int A[x];

do{

cout << "\n::::::::::DIGITALNO DREVO::::::::::\n";

cout <<"1. Vstavi element.\n";

cout <<"2. Izpisi drevo.\n";

cout <<"3. Iskanje elementa.\n";

cout <<"4. Odstrani element.\n";

cout <<"5. Izhod.\n\n";

cin >> izbiranje;

switch (izbiranje){

case 1: {

Page 79: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

69

cout << "Vpisi element:";

cin >> stevilo;

Digitalno.Binarno(stevilo,A);

if (Digitalno.Iskanje(stevilo,A)==true)

{

cout << "Stevila ne mores vstaviti, ker je ze v drevesu!";

cout << "\n";}

else

{

Digitalno.Vstavi(stevilo,A);

cout << "\n";

}

break;}

case 2:{

if (Digitalno.Prazen()==true)

{

cout << "Drevo se ne obstaja!!!\n";

}

else

{

cout << "\n Izpis digitalnega drevesa: ";

Digitalno.Izpisi(Digitalno.koren);

cout << "\n\n";

}

break;}

case 3:{

cout << "Kateri element zelis poiskati: ";

cin >> stevilo;

Digitalno.Binarno(stevilo,A);

if(Digitalno.Iskanje(stevilo,A))

{

cout << "Stevilo je v drevesu!";

cout << "\n\n";

}

else

{

cout << "Stevila ni v drevesu!";

cout << "\n\n";

}

break;}

case 4: {

cout << "Katero stevilo zelis odstraniti: ";

cin >> stevilo;

Digitalno.Binarno(stevilo,A);

Page 80: DIPLOMSKO DELO - COREvozlišče (roditelj) največ dva otroka. Po navadi se otroka imenujeta levi in desni otrok. Podatkovna struktura kot je drevo pa ni prisotno samo na področju

70

if(Digitalno.Iskanje(stevilo,A)==true)

{

Digitalno.Odstrani(stevilo,A);

}

else

{

cout << "Tega stevila ni v drevesu";

}

break;}

case 5:

return(0);

cout << "\n";

default:cout << "Napacna stevilka, ni je v meniju!\n";

}

}

while (izbiranje!=5); {ko vtipkamo 5, se program zaključi}

return 0;

}