You are on page 1of 19

STRUKTURE PODATAKA I ALGORITMI

-STEK (STACK)-
Elektrotehnički fakultet, Banja Luka

Dijana Vuković 2010 1


Stek (stack)
• Stek je specijalna vrsta liste, kod koje se elementi umeću i
skidaju s istog kraja.
– LIFO struktura

• Posljednji spremljeni podatak uzima se prvi na obradu


• Operacije
– push Dequeue::enqueueFront()
– pop Dequeue::dequeueFront()
– top Dequeue::head()

push(5) push(12) push(1) pop() pop() pop()

1 1

12 12 12 12
5 5 5 5 5 5

Dijana Vuković 2010 2


Implementacija steka

• Može se implementirati kao dek sa operacijama


enqueueFront() i dequeueFront(), što odgovara
operacijama push() i pop(), respektivno (relativno
neefikasno)

• Jednostavna implementacija korištenjem niza


elemenata

• Implementacija korištenjem jednostruko


povezane liste

Dijana Vuković 2010 3


Stek implementiran nizom elemenata
stekPoljem.c

int stack[MAXN];
int TOS = -1;

top-of-stack (vrh steka)


Indeks posljednjeg elementa stavljenog na stek
(-1 za prazan stek)

push(17) pop() pop() pop() pop()

TOS = 3
17

TOS = 2 TOS = 2
15 15 15

TOS = 1
12 12 12 12
TOS = 0
10 10 10 10 10 TOS = -1

Dijana Vuković 2010 4


push(), pop(), top()
push()
int push(int element, int stack[], int n, int *TOS)
{ TOS = 3
if (*TOS >= n-1) return 0; 17
stack[++(*TOS)] = element;
return 1; TOS = 2 15 15
}
12 12

10 10
int pop(int *element, int stack[], int n, int *TOS)
{
if (*TOS < 0) return 0;
*element = stack[(*TOS)--]; pop()
return 1;
}
TOS = 3
17
TOS = 2
15 15
int top(int *element, int stack[], int n, int *TOS)
{ 12 12
if (*TOS < 0) return 0;
*element = stack[*TOS]; 10 10
return 1;
}

Dijana Vuković 2010 5


Stek realizovan listom
stekListom.c

• U praksi se često koristi stek realizovan


jednostruko povezanom listom sa
implementiranim operacijama insertFront() i
removeFront()

typedef int tip;


17 35 42
struct node {
tip element; TOS
struct node *next;
};
typedef struct node node;
node *TOS;
TOS prazan stek

Dijana Vuković 2010 6


push()
int push(int element, node **TOS)
{
node *novi;
if (novi = malloc (sizeof (node))) {
novi->element = element;
novi->next = *TOS;
*TOS = novi;
return 1;
}
return 0;
}

19

17 35 12

TOS

Dijana Vuković 2010 7


pop()
int pop(int *element, node **TOS)
{
node *stari;
if (*TOS == NULL) return 0;
stari = *TOS;
*element = stari->element;
(*TOS) = stari->next;
free(stari);
return 1;
}

19 17 35 12

TOS

Dijana Vuković 2010 8


Obrada aritmetičkih izraza
• Aritmetički izrazi se u programskim jezicima obično predstavljaju tako da se u
binarnim operacijama operator nalazi između pripadajućih operanada, a u
unarnim operacijama operator se stavlja ispred operanda. Ovakav način
predstavljanja naziva se infiksna notacija.
• Nedostatak ovakve notacije je u tome što može doći do problema kod
određivanja pripadnosti operatora (nedostatak se može ukloniti korištenjem
potpunih zagrada za definisanje pripadnosti – svaki operator se zajedno sa
svojim operandima okruži zagradama).
• Pored infiksne notacije postoje još i prefiksna i postfiksna notacija. U
prefiksnoj notaciji operator se nalazi ispred operanda, a u postfiksnoj iza,
Tako izraz A+B u infiksnoj notaciji, u postfiksnoj ima oblik AB+, a u prefiksnoj
+AB.
• Konverzija iz infiksne u postfiksnu (RPN) notaciju
– izraz se posmatra sa potpunim zagradama
– operator zamijeni odgovarajuću desnu zagradu
– lijeve zagrade se uklone
Primjer:
 A+B*(C-D)+(E-F)*G/H
 ((A+(B*(C-D)))+(((E-F)*G)/H))
 ABCD-*+EF-G*H/+
Dijana Vuković 2010 9
Zadatak 1.
• Izvršiti konverziju izraza u infiksnoj notaciji u izraz
u postfiksnoj notaciji (RPN)

A+B*C-(D+E-F^G^H)*(I+(J-K)*L)/M

Dijana Vuković 2010 10


Rješenje
IN2POST(infix, postfix)
INIT-STACK(S, n)
rank = 0
next = INPUT(infix)
while (next) do
if (next = operand) then
OUTPUT(next, postfix)
rank = rank + 1
else
while (not(STACK-EMPTY(S)) and (IPR(next)SPR(TOP(S))) do
x = POP(S)
OUTPUT(x, postfix)
rank = rank + R(x)
if (rank  1) then
ERROR(Nepravilan izraz)
end_if
end_while
if (STACK-EMPTY(S) or (next  ‘)’ )) then
PUSH(S, next)
else
x = POP(S)
end_if
end_if
next = INPUT(infix)
end_while

Dijana Vuković 2010 11


Rješenje A+B*C-(D+E-F^G^H)*(I+(J-K)*L)/M

operator ul.pr stek pr. R ulaz stek izlaz rank

+,- 2 2 -1 A A 1
*,/ 3 3 -1 + + A 1

5 4 -1 B + AB 2

* +* AB 2
( 6 0 -
C +* ABC 3
) 1 - -
- - ABC*+ 1
( -( ABC*+ 1
D -( ABC*+D 2
+ -(+ ABC*+D 2
E -(+ ABC*+DE 3
- -(- ABC*+DE+ 2
… … … …

Dijana Vuković 2010 12


Rješenje (2) A+B*C-(D+E-F^G^H)*(I+(J-K)*L)/M

operator ul.pr stek pr. R ulaz stek izlaz rank

+,- 2 2 -1 F -(- ABC*+DE+F 3


^ -(-^ ABC*+DE+F 3
*,/ 3 3 -1
G -(-^ ABC*+DE+FG 4
 5 4 -1
^ -(-^^ ABC*+DE+FG 4
( 6 0 - H -(-^^ ABC*+DE+FGH 5
) 1 - - ) - ABC*+DE+FGH^^- 2
* -* ABC*+DE+FGH^^- 2
( -*( ABC*+DE+FGH^^- 2
I -*( ABC*+DE+FGH^^-I 3
+ -*(+ ABC*+DE+FGH^^-I 3
( -*(+( ABC*+DE+FGH^^-I 3
… … … …

Dijana Vuković 2010 13


Rješenje (3) A+B*C-(D+E-F^G^H)*(I+(J-K)*L)/M

operator ul.pr stek pr. R ulaz stek izlaz rank

+,- 2 2 -1 J -*(+( ABC*+DE+FGH^^-IJ 4


*,/ 3 3 -1 - -*(+(- ABC*+DE+FGH^^-IJ 4
K -*(+(- ABC*+DE+FGH^^-IJK 5
 5 4 -1
) -*(+ ABC*+DE+FGH^^-IJK- 4
( 6 0 -
* -*(+* ABC*+DE+FGH^^-IJK- 4
) 1 - - L -*(+* ABC*+DE+FGH^^-IJK-L 5
) -* ABC*+DE+FGH^^-IJK-L*+ 3
/ -/ ABC*+DE+FGH^^-IJK-L*+* 2
M -/ ABC*+DE+FGH^^-IJK-L*+*M 3
<END> ABC*+DE+FGH^^-IJK-L*+*M/- 1

Dijana Vuković 2010 14


Zadatak 2.

• Implementirati u programskom jeziku C


algoritam za prevođenje izraza iz infiksne u
postfiksnu (RPN) notaciju. Pretpostaviti da je
stek realizovan listom, kao u primjeru
stekListom.c

Dijana Vuković 2010 15


Rješenje
IN2POST(infix, postfix)
INIT-STACK(S, n)
rank = 0
next = INPUT(infix)
while (next) do
if (next = operand) then
OUTPUT(next, postfix)
rank = rank + 1
else
while (not(STACK-EMPTY(S)) and (IPR(next)SPR(TOP(S))) do
x = POP(S)
OUTPUT(x, postfix)
rank = rank + R(x)
if (rank  1) then
ERROR(Nepravilan izraz)
end_if
end_while
if (STACK-EMPTY(S) or (next  ‘)’ )) then
PUSH(S, next)
else
x = POP(S)
end_if
end_if
next = INPUT(infix)
end_while

Dijana Vuković 2010 16


Rješenje
int infix2rpn(char *infix, char *rpn) else infix2RPN.c
{ {
node *TOS = NULL;
int rank = 0; while (TOS != NULL &&
int posIn = 0; ipr(next) <= spr(TOS->element))
int posOut = 0; {
char next; pop(&x, &TOS);
char x; rpn[posOut++] = x;
while (next = infix[posIn++]) rank += R(x);
{ if (rank < 1)
if (isOperand(next)) return 0;
{ }
rpn[posOut++] = next; if (TOS == NULL || next != ')')
rank++; push(next, &TOS);
} else
pop(&x, &TOS);
}
}
while (pop(&x, &TOS))
rpn[posOut++] = x;
rpn[posOut] = '\0';
return 1;
}

Dijana Vuković 2010 17


Rješenje (pomoćne funkcije)
int isOperand(char c) int ipr(char c)
{ {
if (c == '+' || switch (c)
c == '-' || {
c == '*' || case '+':
c == '/' || case '-':
c == '^' || return 2;
c == '(' || case '*':
c == ')') return 0; case '/':
else return 1; return 3;
} case '^':
return 5;
case '(':
return 6;
operator ul.pr stek pr. R case ')':
return 1;
+,- 2 2 -1 default:
return -1;
*,/ 3 3 -1 }
 5 4 -1 }

( 6 0 -
) 1 - -

Dijana Vuković 2010 18


Rješenje (pomoćne funkcije) (2)
int R(char c) int spr(char c)
{ {
switch (c) switch (c)
{ {
case '+': case '+':
case '-': case '-':
case '*': return 2;
case '/': case '*':
case '^': case '/':
return -1; return 3;
default: case '^':
return 0; return 4;
} case '(':
} return 0;
default:
return -1;
}
}
operator ul.pr stek pr. R
+,- 2 2 -1
*,/ 3 3 -1
 5 4 -1
( 6 0 -
) 1 - -

Dijana Vuković 2010 19

You might also like