Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

Kap 07 Stakk. Stakk - Definisjon En stakk er en lineær struktur hvor elementer kan innsetttes / fjernes kun i den ene enden av listen, kalt toppen av.

Liknende presentasjoner


Presentasjon om: "Kap 07 Stakk. Stakk - Definisjon En stakk er en lineær struktur hvor elementer kan innsetttes / fjernes kun i den ene enden av listen, kalt toppen av."— Utskrift av presentasjonen:

1 Kap 07 Stakk

2 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: pushInnsetting av element i en stakk popFjerning av element fra en stakk

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

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

5 Innsetting / Uttak 1.pushA 2.pushB 3.pushC 4.pop(C) 5.pop(B) 6.pushD 7.pushE 8.pop(E)

6 Prosedyrer / Funksjoner

7 push - Array-implementering top x x x push (stakk,maxStakk,post,top,full) /*Rutinen plasserer en post (et element) i en stakk*/ /*stack:stakken som posten skal plasseres i*/ /*maxStakk: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 = maxStack THEN full:= true ELSE full := false top:= top + 1 stakk[top]:= post ENDIF post

8 pop - Array-implementering pop (stakk,post,top,tom) /*Rutinen returnerer og sletter en post i en stakk*/ /*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 x x x post

9 push - Lenket liste implementering x top dataneste 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 := new stakkNode p.data := post p.neste := top.neste top.neste := p stakkNode post p

10 pop - Lenket liste implementering x top dataneste 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 = null tom := true ELSE tom := false p := top.neste post := p.data top.neste := p.neste delete(p) ENDIF stakkNode post p

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

12 Beregning av aritmetisk uttrykk (2/3) 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. a + b * c Operator

13 Beregning av aritmetisk uttrykk (3/3) 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. 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. Operator Operand

14 Prefix - Infix - Postfix (1/2) a + b + a b 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. a b + 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

15 Prefix - Infix - Postfix (2/2) a + b * c + a * b c 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. a b c * + 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

16 Infix - Postfix a + b * c a b c * + 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 * 42 + (3 * 4) === * ==

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

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

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

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

21 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.

22 Jernbane-algoritme - Ombytting Opprinnelig togsett (1 er lokomotivet) Togsett hvor to av vognene (3 og 4) er byttet om Disse to skal byttes om 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).

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

24 Jernbane-algoritmen - Figur Infix Streng som inneholder det aritmetiske uttrykket i infix-notasjon Postfix Streng som inneholder det aritmetiske uttrykket i postfix-notasjon OpStakk Array-stakk som kan inneholde aritmetiske operatorer+ - * / ^ venstreparenteser( spesielt avslutningstegn# a / b ^ c + d * e - a * ca b c ^ / d e * + a c * - ^/#^/#

25 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.

26 slutt= # vParentes=( hParentes=) operator={ +,-,*,/,^ } uOperator=operator + vParentes Operator

27 infix_postfix (infix, postfix) /* Rutinen omformer fra infix til postfix*/... REPEAT Les(infix,si)// les si IF si IN uOperator THEN// uOperator pop(opStakk,so) WHILE stakkPrioritet(so) >= infixPrioritet(si) concat(postfix,so) pop(opStakk,so) ENDWHILE push(opStakk,so) push(opStakk,si) ELSEIF si = hParentes THEN// hParentes pop(opStakk,so) WHILE so != vParentes concat(postfix,so) pop(opStakk,so) ENDWHILE ELSEIF si = slutt// slutt pop(opStakk,so) WHILE NOT tom concat(postfix,so) pop(opStakk,so) ENDWHILE ELSE// operand concat(postfix,si) ENDIF UNTIL si = slutt JernbanealgoritmenJernbanealgoritmen JernbanealgoritmenJernbanealgoritmen

28 #a/b^c+d*e-a*c# aa#/b^c+d*e-a*c# /a/#b^c+d*e-a*c# bab/#^c+d*e-a*c# ^ab^/# c+d*e-a*c# cabc^/# +d*e-a*c# +abc^/+#d*e-a*c# dabc^/d+#*e-a*c# *abc^/d*+#e-a*c# eabc^/de*+#-a*c# -abc^/de*+-#a*c# aabc^/de*+a-#*c# *abc^/de*+a*-#c# cabc^/de*+ac*-## #abc^/de*+ac*-# Infix --> Postfix - Eksempel Lest tegn Postfix Stakk Infix

29 Postfix --> Verdi - Figur Gjenstår å lage en rutine for beregning av et aritmetisk uttrykk på postfix-form. -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. 7a b c ^ / d e * + a c * a / b ^ c + d * e - a * c 8 / 2 ^ * * 3 = 7 Verdi Verdi-stakk Postfix

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

31 abc^/de*+ac*-# a8bc^/de*+ac*-# b2-8c^/de*+ac*-# c3-2-8^/de*+ac*-# ^8-8 /de*+ac*-# /1 de*+ac*-# d5-1e*+ac*-# e6-5-1*+ac*-# *30-1+ac*-# +31ac*-# a8-31c*-# c3-8-31*-# *24-31-# -7# #7 Postfix --> Verdi - Eks Lest tegn Verdi Stakk Postfix a b c ^ / d e * + a c *

32 Quicksort - Strategi 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.

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

34 quickSort (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)// scan mot venstre j := j - 1 ENDWHILE IF j != i tab[i] := tab[j] i := i + 1 ENDIF WHILE (ref > tab[j]) AND (i < j)// scan mot høyre i := i + 1 ENDWHILE IF j != i tab[j] := tab[i] j := j - 1 ENDIF ENDWHILE tab[j] := ref// plasser ref rest(stakk,i,j,l,r)// behandle resten UNTIL (r = 0) AND (l = 0)// tom stakk Quicksort - Algoritme (1/2)

35 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)// behandle det minste segmentet først k := j + 1 // for å minimalisere stakk-størrelsen 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 Quicksort - Algoritme (2/2)

36 quickSort (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)// scan mot venstre j := j - 1 ENDWHILE IF j != i tab[i] := tab[j] i := i + 1 ENDIF WHILE (ref > tab[j]) AND (i < j)// scan mot høyre i := i + 1 ENDWHILE IF j != i tab[j] := tab[i] j := j - 1 ENDIF ENDWHILE tab[j] := ref// plasser ref rest(tab,i,j,l,r)// behandle resten Quicksort - Algoritme - Rekursjon (1/2)

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

38 StackA - Simple StackAsArray StackA stackArray x x x x x x top maxSize = 5

39 StackA - Simpl push / pop x x x x x x top pushpop

40 StackA - Simple isEmpty / isFull stackArray x x x x x x top maxSize = 5

41 StackA - Simple Test_StackA stackArray top maxSize = 5

42 x x next Zt StackA - Simple StackAsList - Zt (1/2)

43 x x next Zt StackA - Simple StackAsList - Zt (2/2)

44 StackA - Simple StackAsList StackL x x next x x Zt head push pop

45 StackA - Simple StackAsList Test_StackL elem3elem elem1

46 Klassehierarki - Stack StackAsArray I_Stack StackAsLinkedList Test I_ContainerA_Container I_ComparableA_Object I_Visitor A_Visitor Visitor_Print

47 Interface I_Stack Interface I_Stack som gir grensesnittet for datastrukturen stakk:

48 StackA - Adv StackAsArray

49

50

51

52 StackA - Adv StackAsLinkedList

53

54

55

56 StackA - Adv Test_StackAsArray

57 StackA - Adv Test_StackAslinkedList

58 ENDEND


Laste ned ppt "Kap 07 Stakk. Stakk - Definisjon En stakk er en lineær struktur hvor elementer kan innsetttes / fjernes kun i den ene enden av listen, kalt toppen av."

Liknende presentasjoner


Annonser fra Google