You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
A274101 TIETORAKENTEET<br />
JA ALGORITMIT<br />
PERUSTIETORAKENTEET – LISTA,<br />
PINO, JONO, PAKKA<br />
ABSTRAKTI TIETOTYYPPI<br />
<br />
<br />
<br />
<br />
Tietotyyppi on abstrakti, kun se on määritelty<br />
(esim. matemaattisesti) ottamatta kantaa<br />
varsinaiseen toteutukseen<br />
Määrittelyyn kuuluu<br />
tietojen keskinäinen organisointi<br />
toimenpiteet, jotka rakenteelle voidaan tehdä<br />
Abstraktille tietotyypille käytetään lyhennettä ADT<br />
(Abstract Data Type).<br />
käsitellään seuraavat ADT:t sekä niiden<br />
toteutustapoja<br />
lista (list)<br />
<strong>pino</strong> (stack)<br />
<strong>jono</strong> (queue)<br />
27.9.2005 KyAMK - TiRak, syksy 2005 2<br />
ABSTRAKTI TIETOTYYPPI<br />
TIETOTYYPPIEN TOTEUTUKSESTA<br />
ADT:n toteutus voi käsittää seuraavat osat<br />
Liitäntä (interface)<br />
Toteutus (implementation)<br />
Asiakas (client)<br />
1. Liitäntä (interface)<br />
Sisältää tietotyypin määrittelyn siten, että käyttäjä pystyy hyödyntämään<br />
sitä tietämättä enempää<br />
Javassa rajapinta (tai abstrakti luokka)<br />
C++:ssa luokkamäärittely (tiedosto luokka.h)<br />
Ideana on kapselointi (encapsulation)<br />
Tietorakenteen käyttäjän ei tarvitse tuntea sen toteutustapaa<br />
<br />
Toteutus voi myöhemmin muuttuakin kunhan vain liitäntä pysyy ennallaan<br />
<br />
2. Toteutus, "implementaatio" (implementation)<br />
Sisältää varsinaisen ohjelmakoodin – rakenteelle suoritettavat toimenpiteet<br />
Javassa rajapinnan tai abstraktin luokan implementointi<br />
C++:ssa luokan metodit<br />
3. Asiakas (client)<br />
Ohjelma, joka käyttää tietorakennetta – ei tarvitse tietää toteutusta<br />
Sovellus toimii, vaikka tietorakenteen toteutus muuttuisi vähentää<br />
korjaustarvetta asiakkaan koodiin<br />
<br />
<br />
<br />
<strong>Lista</strong>, <strong>pino</strong> ja <strong>jono</strong> – toteutustapa voi olla joko<br />
Taulukko<br />
Linkitetty lista<br />
Taulukon käyttö tuttua ja yksinkertaista<br />
Taulukolla on kiinteä koko<br />
Voidaan viitata suoraan indeksillä<br />
Linkitetty lista<br />
Koostuu alkioista (node)<br />
Alkiot on linkitetty toisiinsa, kuten esim. alla<br />
data data data data<br />
…<br />
(null)<br />
27.9.2005 KyAMK - TiRak, syksy 2005 3<br />
27.9.2005 KyAMK - TiRak, syksy 2005 4
(null)<br />
LINKITETTY LISTA<br />
LISTA ADT JA SEN TOTEUTUS<br />
<br />
<br />
Linkitetty lista on ns. dynaaminen tietorakenne<br />
<strong>Lista</strong>n alkioiden järjestys määräytyy osoittimien avulla<br />
Esimerkki: Alkion toteutus Javalla<br />
class Node {<br />
Object data;<br />
Node next;<br />
public Node() {<br />
data = null;<br />
next = null;<br />
}<br />
…<br />
}<br />
<br />
<br />
<br />
<br />
Huom: <strong>Lista</strong> ADT ja linkitetty lista ovat eri asia!<br />
<strong>Lista</strong> ADT voidaan määritellä rekursiivisesti:<br />
<strong>Lista</strong> on tyhjä, tai se on alkio, jota seuraa lista.<br />
<strong>Lista</strong> voidaan esittää alkioiden luettelona: a 1 , a 2 , …, a n<br />
<strong>Lista</strong> ADT:n operaatioita (ei täydellinen)<br />
CreateList - luo tyhjän listan<br />
IsEmpty - vastaus kysymykseen, onko lista tyhjä<br />
InsertNode - lisää solun listaan (annetun solun perään)<br />
DeleteNode - poistaa solun listasta<br />
FindData - etsii solua, jonka data annettu<br />
NextNode - annettua solua seuraava solu<br />
PreviousNode - annettua solua edeltävä solu<br />
PrintList - tulostaa listan sisällön<br />
DeleteList - tuhoaa koko listan<br />
27.9.2005 KyAMK - TiRak, syksy 2005 5<br />
27.9.2005 KyAMK - TiRak, syksy 2005 6<br />
LISTA ADT JA SEN TOTEUTUS<br />
LISTA ADT JA SEN TOTEUTUS<br />
Taulukkototeutus<br />
2-ulotteinen taulukko<br />
1. kentässä data<br />
2. kentässä ”linkki”<br />
249<br />
343<br />
128<br />
…<br />
992<br />
2<br />
5<br />
1<br />
Ominaisuuksia<br />
Muistinvaraus etukäteen <br />
suurin mahdollinen määrä<br />
Etuna on, että jokainen<br />
alkio voidaan hakea yhtä<br />
nopeasti<br />
Lisäys on hidasta, ellei<br />
lisätä aina loppuun<br />
Jos lisätään ”keskelle” <br />
joudutaan siirtämään<br />
alkioita, aikavaatimus O(n)<br />
Poistaminen myös hidasta<br />
joudutaan siirtämään<br />
alkioita, O(n)<br />
Ongelmia tulee – jatkossa<br />
keskitytään enemmän<br />
linkitettyyn listaan<br />
Toteutus linkitettynä listana<br />
<br />
<br />
<br />
Rakenne data data data data<br />
Linkitetyn listan ominaisuuksia<br />
Ei tuhlaa muistia – varataan jokaiselle uudelle<br />
alkiolle erikseen<br />
Uuden alkion lisäys on nopea, O(1)<br />
Etsintä on hitaampaa kuin taulukolla, O(n)<br />
Alkion poisto on hidas, kuten taulukollakin, O(n)<br />
Käytännössä listan alkuun kannattaa<br />
sijoittaa tyhjä alkio (head) osoittamaan<br />
ensimmäiseen varsinaiseen alkioon<br />
…<br />
27.9.2005 KyAMK - TiRak, syksy 2005 7<br />
27.9.2005 KyAMK - TiRak, syksy 2005 8
LISTA ADT JA SEN TOTEUTUS<br />
LISTA ADT JA SEN TOTEUTUS<br />
Esimerkki<br />
public class LinkedList {<br />
private Node head; // osoittaa 1. alkioon<br />
}<br />
public LinkedList() {<br />
head = new Node(); // Luo head-alkion, joka ei<br />
osoita<br />
} // mihinkään (huom. Noden<br />
toteutus)<br />
…<br />
public boolean isEmpty() {<br />
if (head.getNext() == null){<br />
return true;<br />
}<br />
return false;<br />
}<br />
27.9.2005 KyAMK - TiRak, syksy 2005 9<br />
<br />
Luonnin jälkeen lista siis sisältää<br />
vain yhden alkion (head)<br />
<br />
<br />
Head-alkion data on merkityksetön<br />
(sisältää mitä sattuu)<br />
Head-alkion linkki ei aluksi osoita<br />
minnekään, vaan sen arvona on null<br />
Voidaan käyttää tarkistamaan, onko<br />
lista tyhjä (isEmpty() –metodi)<br />
27.9.2005 KyAMK - TiRak, syksy 2005 10<br />
TÄRKEIMMÄT LISTAN OPERAATIOT<br />
TÄRKEIMMÄT LISTAN OPERAATIOT<br />
<br />
Lisääminen<br />
1. Luodaan uusi alkio<br />
2. Asetetaan siitä linkki seuraavaan alkio<br />
3. Käännetään linkki edellisestä alkiosta<br />
uuteen alkioon<br />
data<br />
2.<br />
data<br />
1.<br />
3.<br />
X<br />
data<br />
(null)<br />
<br />
Poistaminen<br />
1. Etsitään poistettavaa alkiota edeltävä<br />
alkio<br />
2. Asetetaan siitä linkki poistettavaa<br />
seuraavaan alkioon<br />
3. Poistetaan alkio<br />
1.<br />
X<br />
data data data<br />
3.<br />
2.<br />
(null)<br />
27.9.2005 KyAMK - TiRak, syksy 2005 11<br />
27.9.2005 KyAMK - TiRak, syksy 2005 12
(null)<br />
(null)<br />
TÄRKEIMMÄT LISTAN OPERAATIOT<br />
LISTOJEN KÄYTÖSTÄ<br />
<br />
Läpikäynti (traverse-list)<br />
Käydään läpi listan jokainen alkio ja tehdään siinä<br />
yhteydessä jotakin<br />
Ei yksinään tee siis mitään, vaan liittyy aina johonkin<br />
toimintaan<br />
Alkoiden määrän laskeminen, listan lopun etsiminen, …<br />
Tärkeä järjestämisalgoritmeissa<br />
public void traverseList() {<br />
Node p = this.getHead();<br />
while (p.getNext() != null) {<br />
p = p.getNext();<br />
doSomething();<br />
}<br />
}<br />
<br />
<br />
Listoja käytetään, kun dynaamisesta<br />
rakenteesta on huomattavaa hyötyä<br />
Uutta tietoa syntyy ja vanhaa poistuu<br />
Muistin määrä on rajoitettu (sulautetut<br />
järjestelmät)<br />
Muita listarakenteita<br />
Kahteen suuntaan linkitetty lista<br />
<br />
data data data data<br />
Rengaslista<br />
data data data data<br />
…<br />
…<br />
…<br />
27.9.2005 KyAMK - TiRak, syksy 2005 13<br />
27.9.2005 KyAMK - TiRak, syksy 2005 14<br />
PINO ADT (STACK) JA SEN<br />
TOTEUTUS<br />
PINO ADT (STACK) JA SEN<br />
TOTEUTUS<br />
<br />
<br />
<br />
Pino on rakenteeltaan kuten lista, mutta eroaa<br />
toiminnaltaan merkittävästi<br />
Pino toimii ns. LIFO –periaatteella<br />
(Last In, First Out) eli<br />
Pinoon voidaan tallettaa vain "päälle”<br />
Pinosta voidaan poistaa vain päältä<br />
Tyypillisiä <strong>pino</strong>n toimenpiteitä ovat<br />
Push - Tallennus <strong>pino</strong>on päällimmäiseksi (Insert)<br />
Top - Päällimmäisen alkion haku poistamatta sitä (Find)<br />
Pop - Päällimmäisen alkion haku poistamalla (Delete)<br />
Pino on toiminnoiltaan rajoitettu lista<br />
Voidaan toteuttaa sekä taulukkona että<br />
linkitettynä listana<br />
Toimenpiderajoitukset on otettava<br />
huomioon<br />
Toteutuksena katsotaan linkitettyä listaa<br />
<strong>Lista</strong> koostuu samantyyppisistä alkioista<br />
kuin edelläkin<br />
Head –alkion käyttö jälleen hyödyllistä<br />
27.9.2005 KyAMK - TiRak, syksy 2005 15<br />
27.9.2005 KyAMK - TiRak, syksy 2005 16
PINON KÄYTTÖSOVELLUKSIA<br />
Symbolien balanssin tarkastus:<br />
Tarkastellaan matemaattisessa<br />
lausekkeessa esiintyviä sulkumerkkejä ()<br />
[] {}<br />
Merkkejä voi olla peräkkäin ja sisäkkäin<br />
"kielioppi" oikein, jos samantyyppiset vasen ja<br />
oikea sulku esiintyvät pareittain<br />
Lauseke 1: { [ ( ) [ ( ) ] ( ) ] ( ) } Oikein<br />
Lauseke 2: [ ( ) { ( ) { ( ) } ] ( ) ] Väärin<br />
PINON KÄYTTÖSOVELLUKSIA<br />
Tarkastusalgoritmi:<br />
Luetaan lauseketta merkki kerrallaan<br />
Jos merkki on vasen sulku, talletetaan se<br />
<strong>pino</strong>on<br />
Jos merkki on oikea sulku, luetaan yksi<br />
merkki <strong>pino</strong>sta - jos luettu on samaa<br />
tyyppiä oleva vasen sulku, ok<br />
Lauseke on virheellinen jos:<br />
<strong>pino</strong>sta tulee vääräntyyppinen vasen sulku<br />
<strong>pino</strong> on tyhjä sieltä luettaessa<br />
luettavien merkkien loppuessa <strong>pino</strong> ei ole tyhjä<br />
27.9.2005 KyAMK - TiRak, syksy 2005 17<br />
27.9.2005 KyAMK - TiRak, syksy 2005 18<br />
PINON KÄYTTÖSOVELLUKSIA<br />
Funktion kutsu:<br />
Ohjelmointikielissä funktion kutsu<br />
toteutetaan lähes aina <strong>pino</strong>n avulla<br />
Tallennettavaa tietoa ovat<br />
parametrit<br />
paluuosoite<br />
Esim.<br />
C-kielisen kutsun f( a, b, c ) suorituksen<br />
jälkeen <strong>pino</strong>n 4 päällimmäistä alkiota ovat:<br />
c, b, a, paluuosoite.<br />
JONO ADT (QUEUE)<br />
Jono on myös rakenteeltaan listan<br />
kaltainen<br />
Ero: <strong>jono</strong> toimii FIFO –periaatteella<br />
(First In, First Out)<br />
Jonoon voidaan tallentaa vain loppuun<br />
Jonosta voidaan poistaa vain alusta<br />
Tyypillisiä <strong>jono</strong>n toimenpiteitä ovat<br />
Enqueue - Tallennus <strong>jono</strong>on viimeiseksi (Insert)<br />
First - Ensimmäisen alkion haku poistamatta sitä (Find)<br />
Dequeue - Ensimmmäisen alkion haku poistamalla se (Delete)<br />
27.9.2005 KyAMK - TiRak, syksy 2005 19<br />
27.9.2005 KyAMK - TiRak, syksy 2005 20
JONO ADT (QUEUE)<br />
PAKKA ADT (DEQUE)<br />
<br />
<br />
Jono on toiminnoiltaan rajoitettu lista voidaan<br />
myös toteuttaa taulukkona tai linkitettynä listana<br />
Jonolla on lukuisia käyttökohteita<br />
Matematiikassa sillä on oma tutkimusalueensa,<br />
<strong>jono</strong>teoria<br />
Teknillisiä käytännön esimerkkejä<br />
prosessien suoritus<strong>jono</strong> moniajoympäristössä<br />
tulostus<strong>jono</strong><br />
<strong>jono</strong> palvelimen levylle verkkoympäristössä<br />
puhelu<strong>jono</strong> puhelinkeskuksessa<br />
…<br />
Jono on keskeinen tietorakenne myös<br />
tietokonesimuloinneissa<br />
Pakka on <strong>pino</strong>n ja <strong>jono</strong>n yhdistelmä<br />
Pakkaa voidaan käsitellä sekä <strong>pino</strong>että<br />
<strong>jono</strong>-operaatioilla<br />
Pakkaan voidaan siis tallentaa sekä<br />
alkuun tai loppuun<br />
Pakasta voidaan hakea sekä alusta<br />
tai lopusta<br />
27.9.2005 KyAMK - TiRak, syksy 2005 21<br />
27.9.2005 KyAMK - TiRak, syksy 2005 22<br />
SEURAAVALLA KERRALLA…<br />
Puurakenteet<br />
Mikä on puutietorakenne<br />
Binääripuu<br />
27.9.2005 KyAMK - TiRak, syksy 2005 23