cs 235102 data structures ( 資料結構 ) chapter 3: stacks and queues spring 2012
TRANSCRIPT
2
Stack – Abstract Data Type (ADT)
Object: Stack An order list in which insertions and deletions are
made at only one end.
Operations: Insert(a) or Push(a) ::= insert element a into the stack.
Delete() or Pop() ::= delete and return top element from the stack.
IsFull ::= return FALSE or TRUE.
IsEmpty ::= return FALSE or TRUE.
Stack operates in Last-In-First-Out (LIFO) order
3
Operatons on Stack
BA
CBAtop
toptop
Insert A
A
Insert B Insert C
empty
Using a 1-D array
Stack [MAX_STACK_SIZE]
top: point to the top of the element of the stack
top = -1 denotes an empty stack.
5
Representation of a stack
6
Operations: Push
Push( int *top, element item){ if (*top >= MAX_STACK_SIZE-1) { stackFull(); return; }
*top = *top +1; stack[*top] = item;}
Operations: Pop
7
/* return the top element from the stack */element Pop (int *top){ if (*top == -1) return StackEmpty();
item = stack[*top]; *top = *top-1; return item;}
System stack:
used in the run time to process nested procedure calls
The return addresses of previous outer procedures are stored in the stack.
Application of Stack
8
9
Application of Stackmain PROC . . call Sub1 exitmain ENDP
Sub1 PROC . . call Sub2 retSub1 ENDP
Sub2 PROC . . call Sub3 retSub2 ENDP
Sub3 PROC . . retSub3 ENDP
By the time Sub3 is called, the stack contains all three return addresses:
Return address to Sub2
Return address to Sub1
Return address to main
System stack
Application of Stack
Creation and activation: record for the invoked subprogram return address for calling procedure Parameters of current procedure local variables in current procedure
When exit a subprogram, delete the activation record on the top of the stack.
10
11
Queue – Abstract Data Type (ADT)
Object: Queue an ordered list in which all insertions take place
at the end and all deletions take place at the other end
Operations: Add(a) ::= insert element a at the rear of the queue.
DeleteQ() ::= delete and return front element from the queue.
IsFullQ ::= return FALSE or TRUE.
IsEmptyQ ::= return FALSE or TRUE.
Operations on a Queue
Eg. First-In-First-Out (FIFO) order: f: front pointer r: rear pointer
12
f r f r f r
Insert A A
Insert B A B
Insert CA B C
Delete B C
f r fr
Representation of a Queue
Use a 1-D array Queue [MAX_QUEUE_SIZE]
front, rear: two variables point to the two ends of the queue. Initialization: front = -1; rear = -1
front: one less than the position of the first element in the queue.
13
Queue
Operations: AddQ
15
AddQ(int *rear, element item){ if (*rear == MAX_Queue_SIZE - 1){ QueueFull(); return; }
*rear = *rear +1; queue[*rear] = item;}
Operations: DeleteQ
16
element DeleteQ(int *front, int rear){ if (*front == rear) return QueueEmpty();
*front = *front + 1; return queue[*front];}
Operations: Problem
Problem: a Job queue by operating system
Q[1] Q[2] Q[3]…J_1 Insert J_1J_1 J_2 J_3 Insert J_2, J_3 J_2 J_3 Delete J_2 J_3 J_4 J_5 Insert J_4, J_5 J_3 J_4 J_5 Delete J_4 J_5 Delete
The queue shifts to the right
When queue is full, we need to move the entire queue left
time consuming17
Solution
Use a circular array to represent a queue,
18
if rear == Max_Queue_Size -1 then rear = 0;else rear = rear +1;
rear = (rear+1) % Max_Queue_Size;[1]
[0]
[2]
[3]
[4][5]
front
rear
How to test “Empty” & “Full” ?
Full <=> rear + 1 == front
use only n-1 element
use n elements will not be able to distinguish
full or empty 20
[2]
[1]
[0]
[3]
front rear
[4]
AddQ using Circular Array
21
AddQ( int front, int *rear, element item){ *rear = (*rear +1) % MAX_QUEUE_SIZE; if (front == *rear){ QueueFull(); return; } Queue[*rear] = item;}
DeleteQ using Circular Array
22
element DeleteQ(int *front, int rear){ if (*front == rear)
return QueueEmpty();
*front = (*front +1) % MAX_QUEUE_SIZE; return queue[*front];}
Evaluation of An Expression
x = A/B-CHow to evaluate an expression ?
let A=6, B=3, C=2(A/B)-C
=(6/3)-2=2-2=0
(A/(B-C)) =(6/(3-2) )
=6/1=6
23
Rules to evaluate an expression
Assign precedence to operator, and Evaluate first the operator with higher
precedence
Left to right for the operator with the same precedence (in general),
Right to left for prefix unary operators
24
Relues to evaluate an expression
25
Token Operator Precedence1 Associativity
( ) [ ] -> .
function call array element struct or union member
17 left-to-right
-- ++ increment, decrement2 16 left-to-right
-- ++ ! - +
decrement, increment3
logical not unary minus or plus
15 right-to-left
(type) type cast 14 right-to-left
* / % mutiplicative 13 left-to-right
+ - Add, substract 12 left-to-right
Example 1
ALU
two operands & one result
Compiler generates codes for the ALUEg: D=A+B*C
mul B C T1add A T1 D
source destination
26
+, -, *, /
Example 2
Eg2: D=A+B-C
add A B T1sub T1 C D
Generates correct code so that when the code is evaluated, the expression is computed correctly.
27
Infix and Postfix Notations
Infix notation = operator comes in–between
the operandsEg: A+B*C
A+B-C
It is not easier for compiler to generate code to evaluate an expression in infix notation
Postfix notation: each operator appears after
its operands
Eg: A+B-C infix AB+C- postfix
28
Translate infix to postfix
How to translate from infix to postfix? A/B-C
First Algorithm:
(1) Fully parenthesize the expression
(2) Move all operators so that they replace their corresponding right parenthesis
(3) Delete all parenthesis
29
Examples
Eg1:( ( A / B ) – C ) A B / C -
Eg2: ( ( A + B ) - ( C * D ) ) A B + C D * -
Eg3:((((A / B ) – C ) + ( D * E ) ) - ( A * C ) )
A B / C - D E * + A C * -
30
What is good about postfix?
Evaluation of postfix expression done in one passEg1:
A + B - C A B + C - add A B T1
sub T1 C T2
Scan the expression from left to right
Use stack to hold operands
Example 1
31
+T1
T2-
Example 1: A B + C -
‘+’pop operands A, BT1 = A + Bpush T1 to stack
32
ABA T1=A+B
A B
C
CT1=A+B
‘-’pop operands C, T1T2 = T1 – Cpush T2 to stack
T2=T1-C
Example 2 Ex2:
A+B-C*D A B + C D * -
33
ABA
A B
T1=A+B
‘+’pop two operands A,
BT1 = A+Bpush the result
“*”pop two operands C,
DT2 = C*Dpush the result
CT1=A+B
C
DC
T1=A+B
D
T2=C*DT1=A+B
Example 2
34
T2=C*DT1=A+B
‘-’pop T1, T2T3 = T1 – T2push the
resultT3=T1-T2
Ex2:A+B-C*D A B + C D * -
Example 3
‘-’pop two
operandsT2=T1-Cpush the result
36
CT1=A/B T2=T1-C
C
Ex3. A B / C – D E * + A C * -
Example 3
“*”pop two
operandsT3= D*Epush the result
37
DT2=T1-C
D
ED
T2=T1-C
E
T3=D*ET2=T1-C
Ex3. A B / C – D E * + A C * -
Example 3
“*”Pop two operandsT4=T3+T2Push the result
38
T4=T3+T2A
T4=T3+T2
A
CAT4
C
Ex3. A B / C – D E * + A C * -
Example 3
“*”Pop two
operandsT5=A*CPush the result
39
T5=A*CT4 T6=T4-T5
Ex3. A B / C – D E * + A C * -
“-”Pop two
operandsT6=T4 – T5Push the result
Postfix vs Infix
Postfix- when you see an operator, operands have been seen in front of it (on the top of the stick)
Infix- when you see an operator, you do not know if the operand is ready
Thus when we see the operator, we cannot do the evaluation for this operator yet.
40
Evaluate Postfix Expression
EvalPostfixExpression(expression e){
x = NextToken(e); while (x is not end of expression) do
{ if (x is an operand)
then push(&top, x) else{ /* x is an operator */
1. pop the correct number of operands for x from
stack;2. perform the operation; (or
generate the code)
3. push the result onto the stack; }
x = NextToken(e); }
}
How to Transform Infix to Postfix?
How to translate from infix to postfix?
First algorithm:
• “Fully parenthesize” the expression• Convert full parenthesized expr. to
postfix
Disadvantage:
• Need two passes of scanning the expression
42
Algorithm Two
Alg2: 1. scan the expression just once2. utilize stack
Observations:
1: The positions of operands are not changed passing any operands to the output
immediately
2: Store the operator in stack until it is time to pass it to the output
43
Algorithm Two
“it is time”:
means that the precedence of operator in the stack is larger or equal to that of the incoming operator (left-to-right associativity)
44
Example 1
2.1 push operator to the stack
2.2 operators are taken out of stack as long as their precedence is higher or equal to the precedence of new incoming operator
Eg1: A / B – C A B / C -
45
/
A
/
A B
-
AB/
-
AB/C AB/C-
- eoe
Example 2
Eg2:A + B – C * D A B + C D * -
46
+
A
+
A B
-
AB+*-
AB+C
*-
AB+CD
AB+CD* -
AB+CD*-
- *
eoe
Example 3
Eg3: A / B – C + D * E – A * C
48
A B/C-DE *+
AB/C-DE*+
-
-
+
AB/C-DE*+A-
*
AB/C-DE*+AC *-
AB/C-DE*+AC*-
Transform Infix Expr. with ( )
Expression with ( )1. ‘( )’ evaluate first2. ‘(‘ push ‘(’ to stack always 3. when ’(’ is on top of the stack,
then push other operators (always) to stack
4. ‘)’ pop the operators until you see the matched ‘(‘
Eg. A * ( B + C ) / D
49
*
(
(*
AB
(*
+
A+(*
Transform Infix to Postfix
51
PosfixExpression(InfixExpression: e) { while (not end of expression){ x = NextToken(e); if x is an operand then write (x) else switch(x){ case ’(’: push (&top, ‘(’); break;
case ‘)’: do { y = pop(&top); if (y!= ‘(’) write(y); }
while y!= ‘(’; break;
default: while (precedence of operator on top of stack >= precedence of x) {
y=pop(&top); write(y);
} push(&top, x);
} } do{ y = pop (&top); write(y);} while !EmptyStack();}
Multiple Stacks
Multiple stacks Store multiple stacks in 1-D array
# of stacks = 2 : - Using top[0] & top[1]
# of stacks = k > 2 : - Using b[i] & top[i] for each stack
b[0] b[1] b[2] b[k] 52
top[0]
top[1]
B[i] and Top[i] for each Stack
B[i] : points to the position immediately to the left
of the bottom element of stack[i]
Top[i]: points to the top element of stack[i]
53
To test empty & full of stack[i] empty: top[i] == b[i] full: top[i] == b[i+1]
Add an item to stack[i]
Operations
54
void push(int i, element item){ if (top[i] == b[i+1]) then StackFull(i); else {
top[i] = top[i]+1; M[top[i]] = item;
}}