Professional Documents
Culture Documents
Tfr2-23-02 Hlaðar Og Biðraðir 1
Tfr2-23-02 Hlaðar Og Biðraðir 1
Tfr2-23-02 Hlaðar Og Biðraðir 1
2. Hlaðar og biðraðir 1
Hjálmtýr Hafsteinsson
Vor 2023
▪ Huglæg gagnatög
▪ Hlaðar og biðraðir
▪ Hlaðar
▪ Útfærsla með tengdum lista 1.3
▪ Útfærsla með fylki af fastri stærð
▪ Útfærsla með fylki af breytilegri stærð
2
Hlaðar (stacks) og biðraðir (queues)
innsetning eyðing
biðröð
hlaði
▪ Hlaði: Eyða stakinu sem var síðast sett inn LIFO = "last in first out"
▪ Biðröð: Eyða stakinu sem fyrst var sett inn FIFO = "first in first out"
3
Fyrirlestraæfingar
1. Í hlaða er tekið út stakið sem síðast var sett inn. Í biðröð er það stakið sem
fyrst var sett inn. Nefnið þrjár aðrar leiðir til að velja það stak sem á að taka út.
Vísbending: Það má nota gildi staksins
3. Forrit setur (push) gildin 1, 2, 3, 4, 5 á hlaða í þessari röð. Þegar gildi eru tekin
af hlaðanum (pop) þá eru þau prentuð út. Sýnið hvenær pop-aðgerðirnar eru
framkvæmdar til að fá eftirfarandi útprentaðar runur (ef það er mögulegt)?
a. 3, 5, 4, 2, 1
b. 5, 4, 3, 1, 2
4
Forritaskil, notendaforrit og útfærsla
▪ Ávinningur:
▪ Hönnun: Býr til afmörkuð, endurnýtanleg forritasöfn (libraries)
▪ Afköst: Auðveldara að skipta inn hraðvirkari útfærslum
5
Forritaskil fyrir hlaða
▪ Afkastamarkmið: Viljum að hver aðgerð taki aðeins fastan (þ.e. Θ(1)) tíma
▪ Notendaforrit: Snúa við runu af strengjum af staðalinntaki
6
Dæmi um notendaforrit
efst á hlaða
efst á hlaða
C.
of best the was it null
8
Hlaði: útfærsla með tengdum lista
▪ Viðhalda bendi first á fyrsta hnút (node) í eintengdum lista (singly-linked list)
▪ Setja nýtt stak (push) fyrir framan first
▪ Taka stak (pop) frá first
efst á hlaða
first
9
Hlaði: útfærsla með tengdum lista
first
▪ Viðhöldum bendi á fyrsta hnút í tengdum lista
▪ Innsetning og eyðing að framan push("to")
push("be")
push("be")
pop()
10
pop-aðgerð á hlaða: útfærsla með tengdum lista
innri klasi
geyma stak til að skila private class Node
String item = first.item; {
String item;
Node next;
}
11
push-aðgerð á hlaða: útfærsla með tengdum lista
innri klasi
geyma bendi á listann
private class Node
Node oldfirst = first;
{
String item;
Node next;
}
12
Hlaði: Útfærsla með tengdum lista í Java
public class LinkedStackOfStrings
{
private Node first = null;
1. Í hlaða er tekið út stakið sem síðast var sett inn. Í biðröð er það stakið sem
fyrst var sett inn. Nefnið þrjár aðrar leiðir til að velja það stak sem á að taka út.
Vísbending: Það má nota gildi staksins
3. Forrit setur (push) gildin 1, 2, 3, 4, 5 á hlaða í þessari röð. Þegar gildi eru tekin
af hlaðanum (pop) þá eru þau prentuð út. Sýnið hvenær pop-aðgerðirnar eru
framkvæmdar til að fá eftirfarandi útprentaðar runur (ef það er mögulegt)?
a. 3, 5, 4, 2, 1
b. 5, 4, 3, 1, 2
14
Hlaði: Afköst útfærslu með tengdum lista
innri klasi
16 bæti (aukakostnaður við hluti)
private class Node
{
8 bæti (aukakostnaður við innri klasa)
String item;
Node next; 8 bæti (tilvísun á String)
}
8 bæti (tilvísun á Node)
15
Hvernig á að útfæra hlaða af fastri stærð með fylki?
efst á hlaða
efst á hlaða
0 1 2 3 4 5 6 7 8 9
16
Hlaði af fastri stærð: útfærsla með fylki
stærð = 10
0 1 2 3 4 5 6 7 8 9
17
Hlaði af fastri stærð: útfærsla með fylki
Lækka fyrst N og
nota það síðan til að ná í s[N]
(pre-decrement)
18
Álitamál með hlaða
▪ Hangs (loitering): Vera með tilvísun á hlut þegar ekki er lengur þörf á því
▪ Of dýrt:
▪ Þurfum að afrita öll stökin yfir í nýja fylkið, fyrir hverja einustu aðgerð
▪ Fylkjaaðgangar við að setja inn fyrstu N stökin = N + (2 + 4 + … + 2(N – 1)) ~ N 2
public ResizingArrayStackOfStrings() gætum líka byrjað með stærra upphafsfylki, t.d. 8 stök
{ s = new String[1]; }
21
Hlaði: jafnaðarkostnaður við innsetningu
fjöldi fylkisaðganga
fyrir hvern aðgang
N + (2 + 4 + 8 + … + N) ~ 3N
22
Hlaði: minnkun fylkisins
fullt to be or not
23
Hlaði: minnkun fylkisins
Fastayrðing:
Athugið: Hlaði með engum stökum hefur fylki af stærð 2 Fylkið alltaf á milli 25% og 100% fullt
24
Hlaði: rakning á fylki með breytilegri stærð
stækkun
stækkun
stækkun
minnkun
minnkun
25
Afköst hlaða með fylki af breytilegri stærð
▪ Jafnaðargreining (amortized analysis): Meðal keyrslutími per aðgerð yfir versta tilfellis runu
aðgerða á gagnagrind sem byrjar tóm
▪ Staðhæfing: Sérhver runa af M push- og pop-aðgerðum sem byrjar með tóman hlaða tekur
Θ(M) heildartíma
smíði 1 1 1
tvöföldunar og
helmingunar aðgerðir
push 1 N 1
pop 1 N 1
stærð 1 1 1 Athugið:
Langflest sem gert er í Java hefur
vaxtargráða keyrslutíma á N-staka hlaða jafnaðartíma (ekki versta tilfellis
útfærðum með fylki af breytilegri stærð tíma) vegna ruslasöfnunar
26
Minnisnotkun hlaða með fylki af breytilegri stærð
▪ Staðhæfing: Hlaðinn notar á milli ~8N og ~32N bæti til að geyma N stök
▪ ~8N þegar fylkið er fullt
▪ ~32N þegar fylkið er fjórðungsfullt
Athugið:
Þetta telur aðeins minnið sem hlaðinn notar
Minnið fyrir strengina sjálfa getur verið mjög breytilegt
og er "í eigu" forritsins sem notar hlaðann
27
Hlaði: tengdur listi eða fylki af breytilegri stærð
▪ Við getum útfært hlaða með tengdum lista eða fylki af breytilegri stærð. Hvor
aðferðin er betri?
▪ Útfærsla með tengdum lista:
▪ Hver aðgerð tekur fastan tíma í versta tilfelli
▪ Notar aukatíma og aukaminni til að vinna með hlekkina
28
Fyrirlestraæfingar
1. Í hlaða er tekið út stakið sem síðast var sett inn. Í biðröð er það stakið sem
fyrst var sett inn. Nefnið þrjár aðrar leiðir til að velja það stak sem á að taka út.
Vísbending: Það má nota gildi staksins
3. Forrit setur (push) gildin 1, 2, 3, 4, 5 á hlaða í þessari röð. Þegar gildi eru tekin
af hlaðanum (pop) þá eru þau prentuð út. Sýnið hvenær pop-aðgerðirnar eru
framkvæmdar til að fá eftirfarandi útprentaðar runur (ef það er mögulegt)?
a. 3, 5, 4, 2, 1
b. 5, 4, 3, 1, 2
29