Kap 07 Stakk Stakk Definisjon En stakk er

  • Slides: 58
Download presentation
Kap 07 Stakk

Kap 07 Stakk

Stakk - Definisjon En stakk er en lineær struktur hvor elementer kan innsetttes /

Stakk - Definisjon En stakk er en lineær struktur hvor elementer kan innsetttes / fjernes kun i den ene enden av listen, kalt toppen av stakken. Stakk: LIFO (Last In First Out). To basis-operasjoner knyttet til stakk: push pop Innsetting av element i en stakk Fjerning av element fra en stakk

Anvendelser Prosedyrer / funksjoner Rekursjon Beregning av aritmetiske uttrykk Sortering Backtracking Diagnostisering Labyrinttraversering. .

Anvendelser Prosedyrer / funksjoner Rekursjon Beregning av aritmetiske uttrykk Sortering Backtracking Diagnostisering Labyrinttraversering. . .

Innsetting i en stakk Plassering av elementene A, B, C, D, E, F i

Innsetting i en stakk Plassering av elementene A, B, C, D, E, F i nevnte rekkefølge i en stakk.

Innsetting / Uttak 1. 2. 3. 4. 5. 6. 7. 8. push pop push

Innsetting / Uttak 1. 2. 3. 4. 5. 6. 7. 8. push pop push pop A B C (C) (B) D E (E) 1 2 3 4 5 6 7 8

Prosedyrer / Funksjoner

Prosedyrer / Funksjoner

post push - Array-implementering top x x x push (stakk, max. Stakk, post, top,

post push - Array-implementering top x x x push (stakk, max. Stakk, post, top, full) /* /* Rutinen plasserer en post (et element) i en stakk stack : stakken som posten skal plasseres i max. Stakk : Maksimalt antall elementer i stakken post : Posten som skal plasseres i stakken top : Lokasjonen til topp-elementet i stakken full : Returnerer med vedien true hvis stakken er full slik at post ikke kan plasseres IF top = max. Stack THEN full : = true ELSE full : = false top : = top + 1 stakk[top] : = post ENDIF */ */

post pop - Array-implementering pop /* /* x x x (stakk, post, top, tom)

post pop - Array-implementering pop /* /* x x x (stakk, post, top, tom) Rutinen returnerer og sletter en post i en stakk : stakken som posten skal plasseres i post : Posten som skal returneres fra stakken top : Lokasjonen til topp-elementet i stakken tom : Returnerer med vedien true hvis stakken er tom slik at post ikke kan returneres IF top = 0 THEN tom : = true ELSE tom : = false post : = stakk[top] top : = top - 1 ENDIF */ */ top

push - Lenket liste implementering top stakk. Node x post 4 1 2 3

push - Lenket liste implementering top stakk. Node x post 4 1 2 3 data neste p push (post, top) /* Rutinen plasserer en post i en stakk med dummy-element. */ /* post : Posten som skal plasseres i stakken */ /* top : Peker til toppen (dummy) i stakken */ p p. data p. neste top. neste : = : = new stakk. Node post top. neste p 1 2 3 4

pop - Lenket liste implementering post top 3 stakk. Node 2 data x p

pop - Lenket liste implementering post top 3 stakk. Node 2 data x p neste 1 pop (post, top) /* Rutinen returnerer og sletter en post i en stakk. */ /* post : Posten som skal returneres fra stakken */ /* top : Peker til toppen (dummy) i stakken */ IF top. neste = tom : = true ELSE tom : = post : = top. neste : = delete(p) ENDIF null false top. neste p. data p. neste 1 2 3

Beregning av aritmetisk uttrykk (1/3) a+b*c 2 + 3 * 4 = 2 +

Beregning av aritmetisk uttrykk (1/3) a+b*c 2 + 3 * 4 = 2 + 12 = 14 Korrekt 2+3*4 =5*4 Feil = 20 * har høyere prioritet enn + 3 skal multipliseres med 4 før dette svaret adderes til 2

Beregning av aritmetisk uttrykk (2/3) Operator a+b*c Hvis vi leser det aritmetiske uttrykket fra

Beregning av aritmetisk uttrykk (2/3) Operator a+b*c Hvis vi leser det aritmetiske uttrykket fra venstre mot høyre, kan vi ikke utføre operasjonene etter hvert som vi treffer på en operator. Vi må lese videre for å se om andre operatorer har høyere prioritet.

Beregning av aritmetisk uttrykk (3/3) Operator a+b*c Et aritmetisk uttrykk skrevet på denne måten,

Beregning av aritmetisk uttrykk (3/3) Operator a+b*c Et aritmetisk uttrykk skrevet på denne måten, med en operand på hver side av tilhørende operator, sies å være skrevet på infix-form. Operand Det er mulig å omskrive infix-uttrykket til en ny form slik at en operasjon kan utføres umiddelbart hver gang en operator påtreffes når uttrykket leses fra venstre mot høyre. To slike formes finnes: prefix og postfix.

a+b Prefix - Infix - Postfix (1/2) +ab a+b ab+ Prefix En operator står

a+b Prefix - Infix - Postfix (1/2) +ab a+b ab+ Prefix En operator står foran tilhørende to operander. Hver gang en operator påtreffes, utføres operasjonen på de to etterfølgende operandene. Infix En operator står mellom tilhørende to operander. Først paranterisering, så utføring av operasjon på operandene på hver side. Postfix En operator står bak tilhørende to operander. Hver gang en operator påtreffes, utføres operasjonen på de to foregående operandene.

a+b*c Prefix - Infix - Postfix (2/2) +a*bc a+b*c abc*+ Prefix En operator står

a+b*c Prefix - Infix - Postfix (2/2) +a*bc a+b*c abc*+ Prefix En operator står foran tilhørende to operander. Hver gang en operator påtreffes, utføres operasjonen på de to etterfølgende operandene. Infix En operator står mellom tilhørende to operander. Først paranterisering, så utføring av operasjon på operandene på hver side. Postfix En operator står bak tilhørende to operander. Hver gang en operator påtreffes, utføres operasjonen på de to foregående operandene.

a+b*c Infix - Postfix Infix En operator står mellom tilhørende to operander. a+b*c Først

a+b*c Infix - Postfix Infix En operator står mellom tilhørende to operander. a+b*c Først paranterisering, så utføring av operasjon på operandene på hver side. 2+3*4 = 2 + (3 * 4) = 2 + 12 = 14 Postfix En operator står bak tilhørende to operander. abc*+ Hver gang en operator påtreffes, utføres operasjonen på de to foregående operandene. 234*+ = 2 12 + = 14

a+b*c abc*+ Postfix - Eksempel 2 + 3 * 4 = 14 234*+ 2

a+b*c abc*+ Postfix - Eksempel 2 + 3 * 4 = 14 234*+ 2 3 4 * + = 14 2 (operand) leses 3 (operand) leses 4 (operand) leses 234*+ * (operator) leses * virker på de to siste operandene 3 og 4 og gir 3 * 4 = 12 2 12 + (operator) leses + virker på de to siste operandene 2 og 12 og gir 2 + 12 = 14 14 +

Omforming fra infix til prefix 0. Infix-form a+b*c 1. Komplett parenterisering ( a +

Omforming fra infix til prefix 0. Infix-form a+b*c 1. Komplett parenterisering ( a + (b * c) ) 2. Flytt hver operator til plassen like bak tilhørende venstre-parentes ( + a (* b c ) ) 3. Fjern alle parenteser +a*bc

Omforming fra infix til postfix 0. Infix-form a+b*c 1. Komplett parenterisering ( a +

Omforming fra infix til postfix 0. Infix-form a+b*c 1. Komplett parenterisering ( a + (b * c) ) 2. Flytt hver operator til plassen like foran tilhørende høyre-parentes ( a (b c *) + ) 3. Fjern alle parenteser abc*+

a/b^c+d*e-a*c Infix --> Postfix Parenterisering a/ b^c abc^/de*+ac*- + d *e - * ^

a/b^c+d*e-a*c Infix --> Postfix Parenterisering a/ b^c abc^/de*+ac*- + d *e - * ^ (((a/(b^c c^)/) a c^ / b * ) )+(d*e ) (((a (b Infix - + / a*c (d e*)+) (a d e* ) ) Parenterisering c*)-) Operatorflytting c* - Postfix )-(a*c + a

Infix --> Postfix --> Beregnet verdi Komplett parenterisering er en tungvint prosess spesielt mht

Infix --> Postfix --> Beregnet verdi Komplett parenterisering er en tungvint prosess spesielt mht maskinell behandling. Vi benytter følgende to-delte strategi: 1. Utform en algoritme hvor input er et infix-uttrykk og hvor output er et postfix- (eller prefix-) uttrykk. 2. Utform en algoritme som scanner gjennom postfix- (eller prefix-) uttrykket og beregner verdien.

Jernbane-algoritme - Ombytting Omforming mellom prefix, infix og postfix innebærer endring av rekkefølgen ved

Jernbane-algoritme - Ombytting Omforming mellom prefix, infix og postfix innebærer endring av rekkefølgen ved at operatorer flyttes. Til dette benytter vi en såkalt jernbane-algoritme (navnet kommer av at ombyttingen er analog med ombytting av vogner i et togsett). Togsett hvor to av vognene (3 og 4) er byttet om 5 3 4 2 1 Opprinnelig togsett (1 er lokomotivet) 5 4 3 2 Disse to skal byttes om 1

Jernbane-algoritmen - Eks ombytting 5 4 3 2 1 1. Opprinnelig togsett 4. Vogn

Jernbane-algoritmen - Eks ombytting 5 4 3 2 1 1. Opprinnelig togsett 4. Vogn 3 hektes av ved vogn 5 5 4 3 2 1 2. Vogn 5 hektes av 5 3 5. Vogn 4 hentes fra sidespor 5 3. Vogn 4 plasseres på sidespor 5 3 3 2 1 4 5 3 4 2 1 6. Resterende tog (4, 2 og 1) kobles til vognene 5 og 3 2 1 4 4 2 1

Jernbane-algoritmen - Figur Postfix Streng som inneholder det aritmetiske uttrykket i postfix-notasjon Infix Streng

Jernbane-algoritmen - Figur Postfix Streng som inneholder det aritmetiske uttrykket i postfix-notasjon Infix Streng som inneholder det aritmetiske uttrykket i infix-notasjon abc^/de*+ac*- a/b^c+d*e-a*c ^ / # Op. Stakk Array-stakk som kan inneholde aritmetiske operatorer +-*/^ venstreparenteser ( spesielt avslutningstegn #

Infixprioritet - Stakkprioritet - Alle operatorer (inkludert parentes) får tildelt en prioritetsverdi. - Operander

Infixprioritet - Stakkprioritet - Alle operatorer (inkludert parentes) får tildelt en prioritetsverdi. - Operander lest fra infix-uttrykket konkateneres til postfix-uttrykket. - Ved lesing av operator fra infix-uttrykket, sammenlignes denne operatoren med operatoren øverst på operator-stakken. Hvis infix-operatoren har høyere prioritet, pushes denne ned på stakken, hvis ikke konkateneres stakk-operatoren til postfix-uttrykket og neste stakk-operator poppes.

Operator slutt v. Parentes h. Parentes operator u. Operator = = = # (

Operator slutt v. Parentes h. Parentes operator u. Operator = = = # ( ) { +, -, *, /, ^ } operator + v. Parentes

infix_postfix J e r n b a n e a l g o r

infix_postfix J e r n b a n e a l g o r i t m e n (infix, postfix) /* Rutinen omformer fra infix til postfix */. . . REPEAT Les(infix, si) IF si IN u. Operator THEN pop(op. Stakk, so) WHILE stakk. Prioritet(so) >= infix. Prioritet(si) concat(postfix, so) pop(op. Stakk, so) ENDWHILE push(op. Stakk, so) push(op. Stakk, si) ELSEIF si = h. Parentes THEN pop(op. Stakk, so) WHILE so != v. Parentes concat(postfix, so) pop(op. Stakk, so) ENDWHILE ELSEIF si = slutt pop(op. Stakk, so) WHILE NOT tom concat(postfix, so) pop(op. Stakk, so) ENDWHILE ELSE concat(postfix, si) ENDIF UNTIL si = slutt // les si // u. Operator // h. Parentes // slutt // operand

Infix --> Postfix - Eksempel Lest tegn Postfix a / b ^ c +

Infix --> Postfix - Eksempel Lest tegn Postfix a / b ^ c + d * e a * c # a a ab ab abc^/d abc^/de*+a abc^/de*+ac*-# Stakk Infix # # /# /# ^/# +# +# *+# -# -# *-# a/b^c+d*e-a*c# c+d*e-a*c# e-a*c# c# #

8 / 2 ^ 3 + 5 *6 - 8 * 3 Postfix -->

8 / 2 ^ 3 + 5 *6 - 8 * 3 Postfix --> Verdi - Figur = 7 a/b^c+d*e-a*c Gjenstår å lage en rutine for beregning av et aritmetisk uttrykk på postfix-form. 8 2 3 7 5 6 8 3 abc^/de*+ac*- Verdi Postfix 3 2 8 Verdi-stakk - Les fortløpende operand/operator fra postfix-uttrykk. - Hvis operand er lest, pushes operandens verdi på verdi-stakken. - Hvis operator er lest, pop to verdier fra verdi-stakken, anvend operatoren på dem og push resultatet tilbake til verdi-stakken.

Postfix --> Verdi - Algoritme postfix. Verdi (postfix) /* Rutinen beregner og returnerer en

Postfix --> Verdi - Algoritme postfix. Verdi (postfix) /* Rutinen beregner og returnerer en verdi fra postfix */. . . Les(sp) // les WHILE sp != slutt IF sp IN operator // operator pop(verdi. Stakk, v 2) pop(verdi. Stakk, v 1) v : = eval(v 1, v 2, sp) ELSE // operand v : = value(sp) ENDIF push(verdi. Stakk, v) les(sp) ENDWHILE pop(verdi. Stakk, verdi) return verdi

8 2 3 Postfix --> Verdi - Eks Lest tegn Verdi a b c

8 2 3 Postfix --> Verdi - Eks Lest tegn Verdi a b c ^ / d e * + a c * # 7 5 6 8 3 abc^/de*+ac*- Stakk Postfix 8 2 -8 3 -2 -8 8 -8 1 5 -1 6 -5 -1 30 -1 31 8 -31 3 -8 -31 24 -31 7 abc^/de*+ac*-# /de*+ac*-# +ac*-# -# #

Quicksort - Strategi 51 33 17 59 70 87 12 62 90 22 78

Quicksort - Strategi 51 33 17 59 70 87 12 62 90 22 78 60 1. Vi plukker ut ett av tallene Ref (f. eks. det første tallet (51)). 2. Vi sørger for at dette tallet Ref kommer på korrekt plass i tabellen, dvs vi sørger for at etter at Ref er plassert, så skal alle tall til venstre i tabellen være mindre enne Ref og alle tall til høyre i tabellen skal være større enn Ref (tabell med flere tall like behandles også korrekt av denne algoritmen). 3. Vi gjentar punktene 1 og 2 på hver av de to tabell-delene skilt av Ref.

51 33 17 59 70 87 12 62 90 22 78 60 Quicksort -

51 33 17 59 70 87 12 62 90 22 78 60 Quicksort - Eks 22 33 17 12 51 87 70 62 90 59 78 60 1. Usortert tabell. ref 51 33 17 59 70 87 12 62 90 22 78 60 2. Plasser første tall i ref. 51 33 17 59 70 87 12 62 90 22 78 60 3. Scan fra høyre inntil første tall mindre enn ref, plasser i ledig pos. 51 33 17 59 70 87 12 62 90 22 78 60 4. Scan fra venstre inntil første tall større enn ref, plasser i ledig pos. 51 22 33 17 59 70 87 12 62 90 5. Scan fra høyre inntil første tall mindre enn ref, plasser i ledig pos. 51 22 33 17 6. Scan fra venstre inntil første tall større enn ref, plasser i ledig pos. 51 22 33 17 12 70 87 7. Scan fra høyre inntil første tall mindre enn ref (ikke mulig). Plasser ref i ledig pos. 51 22 33 17 12 8. Ref er korrekt plassert. Gjenta prosessen på de to resterende halvdelene. 78 60 70 87 12 62 90 59 78 60 87 70 62 90 59 78 60 22 33 17 12 51 87 70 62 90 59 78 60

Quicksort - Algoritme (1/2) quick. Sort (tab, max, stakk) /* Rutinen sorterer (i stigende

Quicksort - Algoritme (1/2) quick. Sort (tab, max, stakk) /* Rutinen sorterer (i stigende rekkefølge) */ /* en tabelle tab bestående av max antall elementer */ push(stakk, 0, 0) l : = 1 r : = max REPEAT i : = l j : = r ref : = tab[l] WHILE i < j WHILE (ref < tab[j]) AND (i < j) j : = j - 1 ENDWHILE IF j != i tab[i] : = tab[j] i : = i + 1 ENDIF WHILE (ref > tab[j]) AND (i < j) i : = i + 1 ENDWHILE IF j != i tab[j] : = tab[i] j : = j - 1 ENDIF ENDWHILE tab[j] : = ref rest(stakk, i, j, l, r) UNTIL (r = 0) AND (l = 0) // scan mot venstre // scan mot høyre // plasser ref // behandle resten // tom stakk

Quicksort - Algoritme (2/2) rest (stakk, i, j, l, r) /* Rutinen behandler de

Quicksort - Algoritme (2/2) rest (stakk, i, j, l, r) /* Rutinen behandler de to resterende delene av arrayen tab */ IF j = r r : =r - 1 ELSEIF i = l l : = l + 1 ELSEIF (i-l) < (r-j) k : = j + 1 push(stakk, k, r) r : = i - 1 ELSE k : = i - 1 push(stakk, l, k) l : = j + 1 ENDIF IF r <= l pop(stakk, l, r) ENDIF // behandle det minste segmentet først // for å minimalisere stakk-størrelsen

Quicksort - Algoritme - Rekursjon (1/2) quick. Sort (tab, l, r) /* Rutinen sorterer

Quicksort - Algoritme - Rekursjon (1/2) quick. Sort (tab, l, r) /* Rutinen sorterer (i stigende rekkefølge) */ /* en tabelle tab bestående av max antall elementer */ i : = l j : = r ref : = tab[l] WHILE i < j WHILE (ref < tab[j]) AND (i < j) j : = j - 1 ENDWHILE IF j != i tab[i] : = tab[j] i : = i + 1 ENDIF WHILE (ref > tab[j]) AND (i < j) i : = i + 1 ENDWHILE IF j != i tab[j] : = tab[i] j : = j - 1 ENDIF ENDWHILE tab[j] : = ref rest(tab, i, j, l, r) // scan mot venstre // scan mot høyre // plasser ref // behandle resten

Quicksort - Algoritme - Rekursjon (2/2) rest (tab, i, j, l, r) /* Rutinen

Quicksort - Algoritme - Rekursjon (2/2) rest (tab, i, j, l, r) /* Rutinen behandler de to resterende delene av arrayen tab */ IF l < j quick. Sort(tab, l, j-1) ENDIF IF r > i quick. Sort(tab, i+1, r) ENDIF

Stack. A - Simple Stack. As. Array Stack. A stack. Array max. Size =

Stack. A - Simple Stack. As. Array Stack. A stack. Array max. Size = 5 top 5 4 3 2 1 x x 0 x

push Stack. A - Simpl push / pop top pop 5 4 3 2

push Stack. A - Simpl push / pop top pop 5 4 3 2 1 x x 0 x

stack. Array Stack. A - Simple is. Empty / is. Full max. Size =

stack. Array Stack. A - Simple is. Empty / is. Full max. Size = 5 top 5 4 3 2 1 x x 0 x

stack. Array Stack. A - Simple Test_Stack. A max. Size = 5 top 5

stack. Array Stack. A - Simple Test_Stack. A max. Size = 5 top 5 4 3 2 1 5 3 0 7

Stack. A - Simple Stack. As. List - Zt Zt x (1/2) next

Stack. A - Simple Stack. As. List - Zt Zt x (1/2) next

Stack. A - Simple Stack. As. List - Zt Zt x (2/2) next

Stack. A - Simple Stack. As. List - Zt Zt x (2/2) next

Stack. A - Simple Stack. As. List Stack. L head push pop Zt Zt

Stack. A - Simple Stack. As. List Stack. L head push pop Zt Zt x next

Stack. A - Simple Stack. As. List Test_Stack. L elem 3 elem 2 elem

Stack. A - Simple Stack. As. List Test_Stack. L elem 3 elem 2 elem 1 5 3 7 .

Klassehierarki - Stack I_Comparable I_Container A_Object A_Container I_Stack I_Visitor A_Visitor Stack. As. Array Test

Klassehierarki - Stack I_Comparable I_Container A_Object A_Container I_Stack I_Visitor A_Visitor Stack. As. Array Test Stack. As. Linked. List Test Visitor_Print

Interface I_Stack som gir grensesnittet for datastrukturen stakk:

Interface I_Stack som gir grensesnittet for datastrukturen stakk:

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Array

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Stack. As. Linked. List

Stack. A - Adv Test_Stack. As. Array

Stack. A - Adv Test_Stack. As. Array

Stack. A - Adv Test_Stack. Aslinked. List

Stack. A - Adv Test_Stack. Aslinked. List

END

END