class3
class3
local variables
old frame pointer fp old frame pointer
stack frame of invoking function
return address return address
main
system stack before a1 is invoked system stack after a1 is invoked
(a) (b)
*Figure 3.2: System stack after function call a1 (p.103)
3.1 The stack ADT (3/5)
The ADT specification of the stack is shown in
Structure 3.1
3.1 The stack ADT (4/5)
Implementation: using array
3.1 The stack ADT (5/5)
3.2 The queue ADT (1/7)
A queue is an ordered list in which all insertion take
place one end, called the rear and all deletions
take place at the opposite end, called the front
If we insert the elements A, B, C, D, E, in that
order, then A is the first element we delete from the
queue
A stack is also known as a First-In-First-Out (FIFO)
list
3.2 The queue ADT (2/7)
The ADT specification of the queue appears in
Structure 3.2
3.2 The queue ADT (3/7)
Implementation 1:
using a one dimensional array and
two variables, front and rear
3.2 The queue ADT (4/7)
problem: there may be available space when IsFullQ is true i.e. movement is
required.
3.2 The queue ADT (5/7)
Example 3.2 [Job scheduling]:
Figure 3.5 illustrates how an operating system might
process jobs if it used a sequential representation for
its queue.
As jobs enter and leave the system, the queue gradually shift
to right.
In this case, queue_full should move the entire queue to the
left so that the first element is again at queue[0], front is at -1,
and rear is correctly positioned.
Shifting an array is very time-consuming, queue_full has a
worst case complexity of O(MAX_QUEUE_SIZE).
We can obtain a more efficient
3.2 (6/7) representation if we regard the array
queue[MAX_QUEUE_SIZE] as
circular.
Implementation 2:
regard an array as a circular
queue
front: one position
counterclockwise from the
first element
rear: current end
array 1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1
1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1
The entrance is at 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1
position [1][1] and the exit at [m][p] 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1
1 0 0 1 1 0 1 1 0 1 1 1 1 1 0 1 1
1 1 1 0 0 0 1 1 0 1 1 0 0 0 0 0 1
1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 1
1 0 1 0 0 1 1 1 1 1 0 1 1 1 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
exit
3.3 A Mazing Problem (2/8)
If X marks the spot of our current location,
maze[row][col], then Figure 3.9 shows the
possible moves from this position
3.3 A Mazing Problem (3/8)
A possible implementation:
Predefinition: the possible directions to move in an array,
move, as in Figure 3.10.
Obtained from Figure 3.9
typedef struct {
short int vert;
short int horiz;
} offsets;
offsets move[8]; /*array of moves for each direction*/
If we are at position, maze[row][col], and we wish to find
the position of the next move, maze[row][col], we set:
next_row = row + move[dir].vert;
next_col = col + move[dir].horiz;
3.3 A Mazing Problem (4/8)
Initial attempt at a maze traversal algorithm
maintain a second two-dimensional array, mark, to record
#define MAX_STACK_SIZE
100 /*maximum stack size*/
typedef struct {
short int row;
short int col;
short int dir;
} element;
element
stack[MAX_STACK_SIZE];
R: row
R1C1D1 C: col
R4 C12
R3 C14 D 5
2
D: dir
R3 C13 D 6
3
Pop out
R2 C12 D 3
R2 C11 D 2
maze[1][1]: entrance Initially set mark[1][1]=1
R1 C10 D 3
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R1C9D2 1 0 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ ██ █ █
R1C8D2 1 1 0 0 0 1 1 0 1 1 1 0 0 1 1 1 1 █ █ █ █ █ █ █ █ █ ██ █ █ █ █ █ █
1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R2C7D1
1 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R3C6D1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R3C5D2 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
1 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R2C4D3 1 0 0 1 1 0 1 1 0 1 1 1 1 1 0 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R1C5D5 1 1 1 0 0 0 1 1 0 1 1 0 0 0 0 0 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R1C4D2
1 0 1 0 0 1 1 1 1 1 0 1 1 1 1 0 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R1C3D2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
R2C2D1
R1C1D3
1 maze[15][11]: exit
3.3 A Mazing Problem (6/8)
Review of add and delete to a stack
3.3 A Mazing
Problem (7/7)
Analysis:
The worst case of
computing time of path
is O(mp), where m and
p are the number of
rows and columns of
the maze 0
respectively 7 N 1
6 W E 2
5 S 3
4
(1,1)
(m,p)
(m+2)*(p+2)
3.3 A Mazing Problem (8/8)
The size of a stack
0 0 0 0 0 1
1 1 1 1 1 0
1 0 0 0 0 1
0 1 1 1 1 1
1 0 0 0 0 1
1 1 1 1 1 0
1 0 0 0 0 1
0 1 1 1 1 1
1 0 0 0 0 0 m*p mp m / 2 / p, or p / 2 / m
*Figure 3.11: Simple maze with a long path (p.116)
3.4 Evaluation of Expressions
(1/14)
3.4.1 Introduction
The representation and evaluation of expressions is of
great interest to computer scientists.
((rear+1==front) || ((rear==MAX_QUEUE_SIZE-1) && !front)) (3.1)
x = a/b - c+d*e - a*c
(3.2)
If we examine expressions (3.1),
we notice that they contains:
operators: ==, +, -, ||, &&, !
operands: rear, front, MAX_QUEUE_SIZE
parentheses: ( )
3.4 Evaluation of Expressions
(2/14)
Understanding the meaning of these or any other
expressions and statements
assume a = 4, b = c = 2, d = e = 3 in the statement
(3.2), finding out the value of x = a/b – c + d*e - a*c
Interpretation 1: ((4/2)-2)+(3*3)-(4*2) = 0+8+9 = 1
Interpretation 2: (4/(2-2+3))*(3-4)*2 = (4/3)*(-1)*2 = -2.66666 …
we would have written (3.2) differently by using
parentheses to change the order of evaluation:
x = ((a/(b - c+d))*(e - a)*c (3.3)
How to generate the machine instructions
corresponding to a given expression?
precedence rule + associative rule
3.4 (3/14)
Precedence
hierarchy and
associative for
C
3.4 Evaluation of Expressions
(4/14)
Evaluating postfix expressions
The standard way of writing expressions is known as
infix notation
binary operator in-between its two operands
Infix notation is not the one used by compilers to
evaluate expressions
Instead compilers typically use a parenthesis-free
notation referred to as postfix
Postfix:
no
parentheses,
no precedence
3.4 Evaluation of Expressions
(5/14)
Evaluating postfix expressions is much simpler
than the evaluation of infix expressions:
There are no parentheses to consider.
To evaluate an expression we make a single left-to-
right scan of it.
We can evaluate
an expression
easily by using
a stack
Figure 3.14 shows this
processing when the
input is nine character
string 6 2/3-4 2*+
3.4 Evaluation of Expressions (6/14)
Representation
We now consider the representation of both the stack and
the expression
3.4 Evaluation of Expressions
(7/14)
Get Token
3.4 (8/14)
Evaluation of
Postfix Expression
3.4 Evaluation of Expressions
(9/14)
string: 6 2/3-4 2*+
6 2 / 3 - 4 2 * +
2 2
thean
not answer
notoperator,
an
is an isoperator,
operator,
not
is operator,
an
an operator,
not annot
isoperator,
an
an
isend
operator,
an
operator,
of
operator,
string,
put into
put into
pop
thepop
put
stack
the
twointo
two
stack
elements
put
the
elements
into
put
pop
stackthe
into
pop
two
pop
stack
the
two
elements
thestack
elements
stack 1 4*2
2
3
4
6/2-3 + 4*2
of the
of the
stackstack of theofand
stack
theget
stack
answer
0 6/2-3+4*2
6/2-3
6/2
6
top
STACK
now, top must -1
+1
-2
3.4 Evaluation of Expressions
(10/14)
We can describe an algorithm for producing a postfix
expression from an infix one as follows
(1) Fully parenthesize expression
a/b-c+d*e-a*c
((((a / b) - c) + (d * e)) - (a * c))
(2) All operators replace their corresponding right
parentheses
((((a / b) - c) + (d * e)) - (a * c))
* * two passes
/ - + -
(3)Delete all parentheses
ab/c-de*+ac*-
The order of operands is the same in infix and
postfix
3.4 Evaluation of Expressions
(11/14)
Example 3.3 [Simple expression]: Simple expression a+b*c, which
yields abc*+ in postfix.
icp isp
12
12
13 13
13
0
13 13
20 0
0
12 12
12
19 match )13
13 13
13
0 13
3.4 Evaluation of Expressions
(12/14)
Algorithm to convert from infix to postfix
Assumptions:
operators: (, ), +, -, *, /, %
operands: single digit integer or variable of one character
1. Operands are taken out immediately
2. Operators are taken out of the stack as long as their in-stack
precedence (isp) is higher than or equal to the incoming
precedence (icp) of the new operator
3. ‘(‘ has low isp, and high icp
op ( ) + - * / %
eos
isp 0 19 12 12 13 13 13 0
icp 20 19 12 12 13 13 13 0
precedence stack[MAX_STACK_SIZE];
/* isp and icp arrays -- index is value of precedence lparen,
rparen, plus, minus, times, divide, mod, eos */
static int isp [ ] = {0, 19, 12, 12, 13, 13, 13, 0};
static int icp [ ] = {20, 19, 12, 12, 13, 13, 13, 0};
3.4 Evaluation of Expressions
(13/14)
a * ( b + c ) / d
operand,
operator
operator
operand,
operator
operand,
operator
operator
operand,
eos
print out print out print out print out
pushthe
pop into
stack
the stack
and printout 2 +
the
operator
isp of“)”,
“(
“/
“+““pop
is 13
12
0 and
and
andprint
the
theicp
icp
outofof
until
“*“*
“(“““(”
isis13
20
13
1 (
output 0 */
top
a b c + * d / stack
now, top must -+1
1
3.4 Evaluation of Expressions
(14/14)
Complexity: (n)
The total time spent
here is (n) as the
number of tokens that
get stacked and
unstacked is linear in n
where n is the number
of tokens in the
expression
3.5 MULTIPLE STACKS AND
QUEUE (1/5)
Two stacks
bottommost bottommost
stack 1 stack 2
More than two stacks (n)
memory is divided into n equal segments
boundary[stack_no]
0 stack_no < MAX_STACKS
top[stack_no]
0 stack_no < MAX_STACKS
3.5 MULTIPLE STACKS AND
QUEUE (2/5)
Initially, boundary[i]=top[i].
All stacks are empty and divided into roughly equal segments.
3.5 MULTIPLE STACKS AND
QUEUE (3/5)
a*(p.128)
#define MEMORY_SIZE 100 /* size of memory */
#define MAX_STACK_SIZE 100 /* max number of stacks plus 1 */
/* global memory declaration */
element memory [MEMORY_SIZE];
int top [MAX_STACKS];
int boundary [MAX_STACKS];
int n; /* number of stacks entered by the user */
*(p.129) To divide the array into roughly equal segments :
top[0] = boundary[0] = -1;
for (i = 1; i < n; i++)
top [i] =boundary [i] =(MEMORY_SIZE/n)*i;
boundary [n] = MEMORY_SIZE-1;
3.5 MULTIPLE STACKS AND
QUEUE (4/5)
*Program 3.12:Add an item to the stack stack-no (p.129)
void add (int i, element item) {
/* add an item to the ith stack */
if (top [i] == boundary [i+1])
stack_full (i); may have unused storage
memory [++top [i] ] = item;
}
*Program 3.13:Delete an item from the stack stack-no (p.130)
element delete (int i) {
/* remove top element from the ith stack */
if (top [i] == boundary [i])
return stack_empty (i);
return memory [ top [i]--];
}
3.5 MULTIPLE STACKS AND
QUEUE (5/5)
Find j, stack_no < j < n ( 往右 )
such that top[j] < boundary[j+1]
or, 0 j < stack_no ( 往左 )
b[0] t[0] b[1] t[1] b[i] t[i] t[i+1] t[j] b[j+1] b[n]
b[i+1] b[i+2]
meet
b=boundary, t=top
往左或右找一個空間
*Figure 3.19: Configuration when stack i meets stack i+1, but the memory is not full (p.130)