Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Chapter #3:
STACKS AND QUEUES
Fundamentals of
Data Structures in C
Horowitz, Sahni and Anderson-Freed
Computer Science Press
Revised by H. Choo, September 2000.
Data Structures in C
top
B
A
top
C
B
A
top
D
C
B
A
top
E
D
C
B
A
top
D
C
B
A
top
Data Structures in C
Data Structures in C
fp
a1
local variables
old frame pointer
return address
(a)
fp
main
Data Structures in C
Data Structures in C
Data Structures in C
Data Structures in C
application
- procedure calls/returns
- syntactic analyzer
- converting recursive procedures to
non-recursive procedures
Data Structures in C
rear
front
B
A
rear
front
C
B
A
rear
front
D
C
B
A
rear
front
D
C
B
rear
front
Data Structures in C
IsEmptyQ(queue)
return (front == rear);
IsFullQ(queue)
return rear == (MAX_QUEUE_SIZE-1);
Networking Laboratory Chap. 3-10
Data Structures in C
Data Structures in C
rear
-1
0
1
2
2
2
Q [0]
J1
J1
J1
Q [1]
J2
J2
J2
Q [2]
J3
J3
J3
Q [3]
com m ents
queue is em pty
job 1 is added
job 2 is added
job 3 is added
job 1 is deleted
job 2 is deleted
Data Structures in C
Data Structures in C
Circular Queues
Data Structures in C
Circular Queues
more efficient queue representation
- regarding the array
queue[MAX_QUEUE_SIZE] as circular
- initially front and rear to 0
rather than -1
- the front index always points one
position counterclockwise from the
first element in the queue
- the rear index points to the
current end of the queue
Data Structures in C
Circular Queues
empty queue
[2]
[3]
[2]
[3]
J2
[1]
[4]
[0]
[5]
front = 0
rear = 0
[1]
J3
J1
[4]
[0]
[5]
front = 0
rear = 3
Data Structures in C
Circular Queues
full queue
full queue
[2]
[3]
J2
[1]
[2]
J3
J1
J8
J4
[4]
[1]
front = 0
rear = 5
[4]
J6
[5]
J9
J7
J5
[0]
[3]
J5
[0]
[5]
front = 4
rear = 3
Data Structures in C
Circular Queues
implementing insertions and deletions
- use modulus operator for circular
rotation
- circular rotation of the rear
*rear = (*rear + 1) % MAX_QUEUE_SIZE;
Data Structures in C
Circular Queues
void addq(int front,int *rear,element
item)
{
*rear = (*rear + 1) % MAX_QUEUE_SIZE;
if (front == *rear) {
queue_full(rear);
/* reset rear and print error */
return;
}
queue[*rear] = item;
}
add an item to a circular queue
- rotate rear before we place the item
in queue[rear]
Networking Laboratory Chap. 3-19
Data Structures in C
Circular Queues
element deleteq(int *front, int rear)
{
element item;
if (*front == rear)
return queue_empty();
/* queue_empty returns an
error key */
*front = (*front + 1) %
MAX_QUEUE_SIZE;
return queue[*front];
}
delete from a circular queue
Networking Laboratory Chap. 3-20
Data Structures in C
Circular Queues
tests for a full queue and an empty
queue are the same
- distinguish between the case of
full and empty
1) permitting a maximum of
MAX_QUEUE_SIZE - 1 rather than
MAX_QUEUE_SIZE elements, or
2) add new variable
no data movement necessary
- ordinary queue: O(n)
- circular queue: O(1)
Data Structures in C
Mazing Problem:
(Skipped)
Data Structures in C
A Mazing Problem
the representation of the maze
- two-dimensional array
- element 0 : open path
- element 1 : barriers
entrance
0
1
0
1
1
0
0
0
1
0
0
1
0
1
1
1
0
1
0
1
0
1
0
0
1
0
0
1
1
1
0
1
0
0
0
0
1
1
1
1
1
0
1
0
0
1
0
1
0
0
1
0
0
1
1
1
1
0
1
0
1
0
1
1
1
1
1
0
0
1
1
1
0
1
1
1
1
0
1
1
0
0
1
1
0
0
0
1
0
1
1
1
1
0
1
1
1
0
1
0
1
1
1
1
1
1
1
1
0
0
1
0
1
0
1
0
1
1
0
1
1
1
0
0
1
1
0
1
1
0
1
1
1
1
0
1
1
1
1
1
0
1
1
1
1
1
0
1
0
1
0
0
1
1
1
1
1
0
1
1
1
1
0
0
0
exit
Data Structures in C
A Mazing Problem
NW
N
NE
[row-1][col-1] [row-1][col] [row-1][col+1]
[row][col-1]
W
X
[row][col]
[row][col+1]
E
SE
allowed move
Data Structures in C
A Mazing Problem
[row][col] which is on border
- has only three neighbors
- surround the maze by a border of
1s
m
-
* p maze
requires (m + 2) * (p + 2) array
entrance position: [1][1]
exit position: [m][p]
Data Structures in C
A Mazing Problem
typedef struct {
short int vert;
short int horiz;
} offsets;
offsets move[8];
/* array of moves for each direction */
name
N
NE
E
SE
S
SW
W
NW
dir
0
1
2
3
4
5
6
7
move[dir].vert move[dir].horiz
-1
0
-1
1
0
1
1
1
1
0
1
-1
0
-1
-1
-1
table of move
Networking Laboratory Chap. 3-26
Data Structures in C
A Mazing Problem
position of next move
- move from current position
maze[row][col]
to the next position
maze[next_row][next_col]
next_row = row + move[dir].vert;
next_col = col + move[dir].horiz;
Data Structures in C
A Mazing Problem
maintain a second two-dimensional
array, mark
- avoid returning to a previously
tried path
- initially, all entries are 0s
- mark to 1 when the position is
visited
Data Structures in C
A Mazing Problem
initialize a stack to the mazes entrance coordinates and direction to north;
while (stack is not empty) {
/* move to position at top of stack */
<row,col,dir> = delete from top of the stack;
while (there are more moves from current position) {
<next_row,next_col> = coordinates of next move;
dir = direction of move;
if ((next_row == EXIT_ROW) && (next_col == EXIT_COL)) success;
if (maze[next_row][next_col] == 0 && mark[next_row][next_col] == 0) {
mark[next_row][next_col] = 1;
add <row,col,dir> to the top of the stack;
row = next_row;
col = next_col;
dir = north;
}
}
}
printf(no path found\n);
Data Structures in C
A Mazing Problem
#define MAX_STACK_SIZE 100
typedef struct {
short int row;
short int col;
short int dir;
} element;
element stack[MAX_STACK_SIZE];
Data Structures in C
A Mazing Problem
0
1
1
0
1
1
1
0
1
0
1
0
1
0
1
0
1
0
0
1
0
1
0
1
0
1
0
0
1
0
1
0
1
0
1
0
0
1
0
1
0
1
0
1
0
1
0
1
1
1
0
1
1
0
Data Structures in C
Evaluation of
Expressions
Data Structures in C
Evaluation of Expressions
Introduction
x = a/b-c+d*e-a*c
to understand the meaning of a
expressions and statements,
- figure out the order in which the
operations are performed
operator precedence hierarchy
- determine the order to evaluate
operators
associativity
- how to evaluate operators with the
same precedence
Networking Laboratory Chap. 3-33
Data Structures in C
Evaluation of Expressions
token
() [] -> .
-- ++
-- ++ ! ~ - + & * sizeof
(type)
*/%
+<< >>
> >= < <=
== !=
&
^
|
&&
||
?:
= += -= /= *= %= <<= >>= &= ^= |=
,
precedence
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
associativity
left-to-right
left-to-right
right-to-left
right-to-left
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
left-to-right
right-to-left
right-to-left
left-to-right
Data Structures in C
Evaluation of Expressions
by human_being
1)assign to each operator a priority
2)use parenthesis and evaluate
inner-most ones
(((a*(b+c))+(d/e))-(a/(c*d)))
by compiler
- by reworking to postfix form
1) translation (infix to postfix)
2) evaluation (postfix)
infix form : operand (operator) operand
postfix form : operand operand (operator)
Data Structures in C
Evaluation of Expressions
infix
2+3*4
a*b+5
(1+2)*7
a*b/c
((a/(b-c+d))*(e-a)*c
a/b-c+d*e-a*c
postfix
2 3 4*+
ab*5+
1 2+7*
ab*c/
abc-d+/ea-*c*
ab/c-de*+ac*-
Data Structures in C
[0]
6
6
6/2
6/2
6/2-3
6/2-3
6/2-3
6/2-3
6/2-3+4*2
stack
[1]
[2]
2
3
4
4
4*2
top
0
1
0
1
0
1
2
1
0
postfix evaluation
Data Structures in C
eval()
- if the token is an operand, convert
it to number and push to the stack
- otherwise
1) pop two operands from the stack
2) perform the specified operation
3) push the result back on the
stack
Data Structures in C
Evaluation of Expressions
#define MAX_STACK_SIZE 100 /* max stack size */
#define MAX_EXPR_SIZE 100
/* max expression size */
typedef enum {lparen, rparen, plus, minus,
times, divide, mode, eos, operand
} precedence;
int stack[MAX_STACK_SIZE]; /* global stack */
char expr[MAX_EXPR_SIZE]; /* input string */
Data Structures in C
Evaluation of Expressions
function to evaluate a postfix expression
int eval()
{
precedence token;
char symbol;
int op1, op2;
int n = 0;
int top = -1;
token = get_token(&symbol, &n);
while (token != eos)
if (token == operand)
push(&top, symbol-0);
else {
op2 = pop(&top);
op1 = pop(&top);
switch (token) {
case plus: push(&top, op1+op2); break;
case minus: push(&top, op1-op2); break;
case times: push(&top, op1*op2); break;
case divide: push(&top, op1/op2); break;
case mod: push(&top, op1%op2);
}
}
token = get_token(&symbol, &n);
}
return pop(&top);
}
Networking Laboratory Chap. 3-40
Data Structures in C
Evaluation of Expressions
function to get a token
precedence get_token(char *psymbol, int *pn)
{
*psymbol = expr[(*pn)++];
switch (*psymbol)
case ( : return lparen;
case ) : return rparen;
case + : return plus;
case - : return minus;
case * : return times;
case / : return divide;
case % : return mod;
case : return eos;
default : return operand; /* no error checking */
}
}
Networking Laboratory Chap. 3-41
Data Structures in C
Data Structures in C
Infix to Postfix
algorithm for producing a postfix
expression from an infix one
1) fully parenthesize the expression
2) move all binary operators so that
they replace their corresponding
right parentheses
3) delete all parentheses
eg) a/b-c+d*e-a*c
((((a/b)-c)+(d*e))-a*c))
ab/c-de*+ac*- requires two passes
Data Structures in C
Infix to Postfix
form a postfix in one pass
- order of operands is the same in infix
and postfix
- order of operators depends on
precedence
- we can use a stack
Data Structures in C
Infix to Postfix
token
a
+
b
*
c
eos
[0]
+
+
+
+
stack
[1]
*
*
[2]
top
-1
0
0
1
1
-1
output
a
a
ab
ab
abc
abc*+
Data Structures in C
Infix to Postfix
Data Structures in C
Infix to Postfix
token
a
*
(
b
+
c
)
*
d
eos
[0]
*
*
*
*
*
*
*
*
*
stack
[1]
(
(
(
(
[2]
+
+
top
output
-1
0
1
1
2
2
0
0
0
0
a
a
a
ab
ab
abc
abc+
abc+*
abc+*d
abc+*d*
Data Structures in C
stack
compare
in-stack precedence
token
incoming precedence
Data Structures in C
Data Structures in C
Data Structures in C
Data Structures in C
Data Structures in C
Data Structures in C
Data Structures in C
m-1
memory
boundary[0] = -1
top[0] = -1
stack 1
boundary[1] = m
top[1] = m
stack 2
Data Structures in C
Data Structures in C
m/n
2 m/n
boundary[0]
boundary[1] boundary[2]
top[0]
top[1]
m-1
boundary[n]
top[2]
Data Structures in C
Data Structures in C
Data Structures in C
S1
3 4
S2
7 8
S3
S4
11 12
15 16
b[3]=11
t[3]=13
b[4]=15
t[4]=16
19
x
b[0]=-1
t[0]=-1
b[1]=3
t[1]=7
b[2]=7
t[2]=11
Data Structures in C