31.01.2015 Views

Luento 4 - Lista, pino, jono, ADTt

Luento 4 - Lista, pino, jono, ADTt

Luento 4 - Lista, pino, jono, ADTt

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!