Module 2
Module 2
MODULE 2
CONTENTS
⚫ Stacks: Definition, Stack Operations, Array
Representation of Stacks, Stacks using
Dynamic Arrays, Stack Applications: Polish
notation, Infix to postfix conversion,
evaluation of postfix expression.
⚫ Recursion: Factorial, GCD, Fibonacci
Sequence, Tower of Hanoi, Ackerman's
function.
⚫ Queues: Definition, Array Representation,
Queue Operations, Circular Queues,
Circular queues using Dynamic arrays,
Dequeues, Priority Queues, A Mazing
Problem. Multiple Stacks and Queues.
INTRODUCTION
⚫ The linear lists and linear arrays allows one
to insert and delete elements at any place
in the list- at the beginning, at the end or in
the middle
⚫ There are certain frequent situations when
one wants to restricts insertions and
deletions so that they can take place only at
the beginning or the end of the list, not in
the middle
⚫ They are STACKS and QUEUES
STACKS
⚫ Stack is a linear list in which addition and
deletion of elements are restricted to one end
called the top.
⚫ A linear list is a list in which each element has
unique successor.
⚫ A linear list may be a restricted list or a
general list.
⚫ Stack is also called as
o LIFO Data structure
o Push down list
⚫ Stack belongs to non-primitive linear
data structure.
STACKS
Top an-1
an-2
…..
….
a1
a0
Figure 1a: Stack S
void stack_full()
{ printf(stderr,”stack is full, can’t add element”);
exit(EXIT_FAILURE);
}
void stack_empty ()
{ printf(stderr,”stack is empty, can’t delete element”);
exit(EXIT_FAILURE);
}
APPLICATIONS OF STACKS
⚫ Stack is used by compilers to check for
balancing of parentheses, brackets and
braces.
⚫ Stack is used to evaluate a postfix
expression.
⚫ Stack is used to convert an infix expression
into postfix/prefix form.
⚫ In recursion, all intermediate arguments
and return values are stored on the
processor’s stack.
⚫ During a function call the return address
and arguments are pushed onto a stack and
on return they are popped off.
EXPRESSIONS
⚫ An algebraic expression is a legal
combination of operators and operands.
“The sequence of operators and operands
that reduces to a single value after
evaluation is called Expression”.
⚫ Operand is the quantity on which a
mathematical operation is performed.
Operand may be a variable like x, y, z or a
constant like 5, 4, 6 etc.
⚫ Operator is a symbol which signifies a
mathematical or logical operation between
the operands. Examples of familiar
operators include +, -, *, /, ^ etc.
postfix and prefix notations:
⚫ Infix: It is the form of an arithmetic
expression in which we fix (place) the
arithmetic operator in between the two
operands. Example: (A + B) * (C - D)
⚫ Prefix: It is the form of an arithmetic
notation in which we fix (place) the
arithmetic operator before (pre) its two
operands. The prefix notation is called as
polish notation (due to the polish
mathematician Jan Lukasiewicz in the year
1920). Example: * + A B – C D
⚫ Postfix: It is the form of an arithmetic
expression in which we fix (place) the
CONVERSION FROM INFIX TO
POSTFIX
⚫ Scan the infix expression from left to right.
⚫ If the scanned symbol is left parenthesis,
push it onto the stack.
⚫ If the scanned symbol is an operand, then
place directly in the postfix expression
(output).
⚫ If the symbol scanned is a right
parenthesis, then go on popping all the
items from the stack and place them in the
postfix expression till we get the matching
left parenthesis.
⚫ the scanned operator onto the stack
otherwise, push the scanned operator onto
CONVERSION FROM INFIX TO
POSTFIX
⚫ If the scanned symbol is an operator, then
go on removing all the operators from the
stack and place them in the postfix
expression, if and only if the precedence of
the operator which is on the top of the
stack is greater than (or greater than or equal)
to the precedence
Operators of the precedence
scanned operator
and push ^% 4
* / 3
+ - 2
# ( 1
Example To convert infix to
postfix
⚫ Convert the following infix expression A + B * C – D / E * H into
its equivalent postfix expression
EVALUATION OF POSTFIX
EXPRESSION
Steps for evaluating postfix expression
⚫ Scan the symbol from left to right.
⚫ If the scanned-symbol is an operand, push
it on to the stack.
⚫ If the scanned-symbol is an operator, pop
two operands from the stack. The first
popped operand acts as operand2 and the
second popped operand act as operand
1.Now perform the indicated operation and
Push the result on to the stack.
⚫ Repeat the above procedure till the end of
input is encountered
EXAMPLE
Evaluate the postfix expression: 6 5 2 3 + 8 * + 3 + *
Underflow and Overflow
⚫ Underflow is a condition occurs if we try to
POP item from the empty STACK
⚫ Overflow is a condition occurs if we try to
PUSH an ITEM to the STACK which is
already full
STACK
E D C B A FULL
STACK
OVERFLOW
<--TO
P
POP
D <--TOP
STACK
EMPT
Y STACK UNDERFLOW
Array representation of Stack
⚫ Array can be used as home to the stack
⚫ Data structure
#define MAX STK 25
typedef struct {
int top;
char item[MAXSTK];
}STACK;
STACK s;
s.top= -1;
A B C D
top
Stack after – PUSH( ‘A’), PUSH( ‘B’), PUSH( ‘C’),
PUSH( ‘D’)
Evaluation of expression
⚫ Three levels of precedence for the 5 binary
operations
⚫ Highest : Exponentiation ( ) or ($) or (^) or (**)
⚫ Next Highest : Multiplication (*) and
Division(/)
⚫ Lowest: Addition (+) and Subtraction (-)
Evaluation of expression
⚫ 2 3 + 5 * 2 2 - 12 / 6
⚫ To evaluate expression is traversed three
times, each time corresponding to the level
of precedence of the operations
⚫ After first traversal expression reduces to 8
+ 5 * 4 -12 / 6
⚫ After Second traversal expression reduces
to 8 + 20 – 2
⚫ After Third traversal expression reduces to
26
Arithmetic Expression
Representation
⚫ INFIX
⚫ PREFIX – POLISH
⚫ POSTFIX – REVERSE POLISH or SUFFIX
INFIX POLISH REVERSE
POLISH
A+B*C +A*BC ABC*+
Postfix Expression
2/3–42*+
Token
Operand,
6 PUSH onto
stack
stack
Postfix Expression
2/3–42*+
6
stack
Postfix Expression
/3–42*+
Token
Operand,
2 PUSH onto
stack
6
stack
Postfix Expression
/3–42*+
2
6
stack
Postfix Expression
3–42*+
Token
Operator, POP
/ 2 top elements
from the stack
2
and store it in
6 opnd2 and
opnd1
stack
Postfix Expression
3–42*+
opnd1 opnd2
6 2
stack
Postfix Expression
3–42*+
Evaluate
opnd1 opnd2
opnd1
6 2 operator
opnd2
stack
Postfix Expression
3–42*+
Postfix Expression
3–42*+
3
stack
Postfix Expression
–42*+
Token
Operand,
3 PUSH onto
stack
3
stack
Postfix Expression
–42*+
3
3
stack
Postfix Expression
42*+
Token
Operator, POP
- 2 top elements
from the stack
3
and store it in
3 opnd2 and
opnd1
stack
Postfix Expression
42*+
Evaluate
opnd1 opnd2
opnd1
3 3 operator
opnd2
stack
Postfix Expression
42*+
Postfix Expression
42*+
0
stack
Postfix Expression
2*+
Token
Operand,
4 PUSH onto
stack
0
stack
Postfix Expression
2*+
4
0
stack
Postfix Expression
*+
Token
Operand,
2 PUSH onto
stack
4
0
stack
Postfix Expression
*+
2
4
0
stack
Postfix Expression
+
Token
Operator, POP
2 * 2 top elements
from the stack
4
and store it in
0 opnd2 and
opnd1
stack
Postfix Expression
+
Evaluate
opnd1 opnd2
opnd1
4 2 operator
opnd2
0
stack
Postfix Expression
+
Postfix Expression
+
8
0
stack
Postfix Expression
Token
Operator, POP
+ 2 top elements
from the stack
8
and store it in
0 opnd2 and
opnd1
stack
Postfix Expression
Evaluate
opnd1 opnd2
opnd1
0 8 operator
opnd2
stack
Postfix Expression
Postfix Expression
8
process
⚫ Since the order of operands in the infix and postfix
expression is same ,Scan the input infix expression from
left to right
⚫ During the scan ,operands are passed directly to the
postfix expression as they are encountered.
⚫ When the operators are encountered it is placed in the
postfix expression depending on its precedence
⚫ To get the higher precedence first in the postfix
expression, we save the operators until we know their
correct placement. To do this we follow the following
procedure
⚫ Check the precedence of the incoming operator with the
stack top.
if precedence of incoming operator is not higher than the
operator at the stack top repeatedly pop the stack and place
the popped item to the postfix expression.
⚫ place incoming operator on the stack.
⚫ Once you reach end of infix expression repeatedly pop
the stack and place the popped item to the postfix
⚫ In a parenthesized infix expression the
expression inside the parenthesis
should be converted first.
⚫ Hence we stack the operators until we
reach the right parenthesis
⚫ As we encounter left parenthesis during
scanning, we must place it on the stack
what ever may be the stack top. Once
left parenthesis becomes the stack top,
what ever may be the operators other
than the right parenthesis ,the operator
should be placed on the stack
⚫ Hence left parenthesis need to behave
like high precedence when it is out
Infix to postfix conversion
algorithm
⚫ Reverse polish(Q, P) // Q is an arithmetic expression in
INFIX notation
Algorithm converts INFIX expression Q into POSTFIX
expression P
1 push “(“ onto STACK, and append “)” to the end of Q
2 scan Q left to right and repeat Steps 3 to 6 for each
element of Q until the STACK is empty
3 If an operand is encountered place it in the POSTFIX
expression P
4 If an left parenthesis is encountered, push it on to the
STACK
Complexity – Ø(n), where n be the number of tokens in the
expression
Infix to postfix conversion
algorithm
5 If an operator is encountered, call it as incoming
operator, then:
a) Repeatedly pop from the STACK and place it in the P
which has the same precedence or higher precedence
than the incoming operator
b) b) Place the incoming operator to the STACK
[End of IF]
6 If a right parentheses is encountered
a) Repeatedly pop from the STACK and place it in the
P until left parenthesis is encountered
b) Remove the left parenthesis
[ End of If ]
[ End of Step 2 loop ]
Infix to postfix conversion
infixVect
(a+b-c)*d–(e+f)
postfixVect
Infix to postfix conversion
stackVect
infixVect
a+b-c)*d–(e+f)
postfixVect
(
Infix to postfix conversion
stackVect
infixVect
+b-c)*d–(e+f)
postfixVect
a
(
Infix to postfix conversion
stackVect
infixVect
b-c)*d–(e+f)
postfixVect
a
+
(
Infix to postfix conversion
stackVect
infixVect
-c)*d–(e+f)
postfixVect
ab
+
(
Infix to postfix conversion
stackVect
infixVect
c)*d–(e+f)
postfixVect
ab+
-
(
Infix to postfix conversion
stackVect
infixVect
)*d–(e+f)
postfixVect
ab+c
-
(
Infix to postfix conversion
stackVect
infixVect
*d–(e+f)
postfixVect
ab+c-
Infix to postfix conversion
stackVect
infixVect
d–(e+f)
postfixVect
ab+c-
*
Infix to postfix conversion
stackVect
infixVect
–(e+f)
postfixVect
ab+c-d
*
Infix to postfix conversion
stackVect
infixVect
(e+f)
postfixVect
ab+c–d*
-
Infix to postfix conversion
stackVect
infixVect
e+f)
postfixVect
ab+c–d*
(
-
Infix to postfix conversion
stackVect
infixVect
+f)
postfixVect
ab+c–d*e
(
-
Infix to postfix conversion
stackVect
infixVect
f)
postfixVect
+ ab+c–d*e
(
-
Infix to postfix conversion
stackVect
infixVect
)
postfixVect
+ ab+c–d*ef
(
-
Infix to postfix conversion
stackVect
infixVect
postfixVect
ab+c–d*ef+
-
Infix to postfix conversion
stackVect
infixVect
postfixVect
ab+c–d*ef+-
Infix to Postfix Conversion using Stack:
Example
⚫ Reversing a list
⚫ Reversing Data: We can use stacks to reverse
data.
(example: files, strings)
Very useful for finding palindromes.
Pseudocode:
1) read (data)
2) loop (data not EOF and stack not full)
1) push (data)
2) read (data)
3) Loop (while stack notEmpty)
1) pop (data)
2) print (data)
⚫ Converting Decimal to Binary: Consider the
following pseudo code
1) Read (number)
2) Loop (number > 0)
1) digit = number modulo 2
2) print (digit)
3) number = number / 2
// from Data Structures by Gilbert and Forouzan
The problem with this code is that it will print the binary
number backwards. (ex: 19 becomes 11001000 instead of
00010011. )
To remedy this problem, instead of printing the digit right
away, we can
push it onto the stack. Then after the number is done being
converted, we
pop the digit out of the stack and print it.
Parsing Data
⚫ Goal seeking
⚫ Decision Analysis
Recursion
⚫ Recursion is a process in which a
procedure calls itself. In C the function that
calls itself is called as recursive function.
⚫ Two types
1. Direct recursion – if the function A calls
function A itself
2. Indirect recursion – if function A calls
function B, function B calls function A (
recursive chain)
⚫ A recursive procedure must have the
following 2 properties
1. There must be base criteria ( terminating
Recursion
Function.
void recursion()
{
recursion(); /* function calls itself */
}
void main()
{
recursion();
}
The C programming language supports
recursion, i.e., a function to call itself.
RECURSION PROPERTIES
⚫ Base criteria − There must be at least one
base criteria or condition, such that, when
this condition is met the function stops
calling itself recursively.
void main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("%d\t", fib(i));
}
}
OUTPUT
0 1 1 2 3 5 8 13 21 34
Tower of Hanoi
Tower of Hanoi, is a mathematical puzzle which
consists of three tower (pegs) and more than one
rings; as depicted in below Figure.
⚫ The below figure shows the recursive function calls in tower of Hanoi
for 3 disks
Recursive solution - Traces for
n=3
Tower(3,A,B,C)
Tower(2,A,C,B)
Tower(1,A,B,C)
Move disk 1 from A to C
Move disk 2 from A to B
Tower(1,C,A,B)
Move disk 1 from C to B
Move disk 3 from A to C
Tower(2,B,A,C)
Tower(1,B,C,A)
Move disk 1 from B to A
Move disk 2 from B to C
Tower(1,A,B,C)
Move disk 1 from A to C
Ackermann function
⚫ It is a function with 2 arguments which can be assigned non
negative integer ( 0, 1,2…..).
⚫ Ackermann function is defined as follows.
A(m, n)= n+1 if m = 0
A(m, n) = A(m-1, 1) if m != 0 and n = 0
A(m, n) = A(m-1, A(m, n-1)) if m != 0 and n != 0
A B C D
front rea
r
ADT QUEUE
APPLICATIONS OF QUEUE
⚫ Serving requests on a single shared
resource, like a printer, CPU task
scheduling etc.
⚫ In real life, Call Center phone systems will
use Queues, to hold people calling them in
an order, until a service representative is
free.
⚫ Handling of interrupts in real-time
systems. The interrupts are handled in the
same order as they arrive, First come first
served
QUEUE BASIC OPERATIONS
⚫ enqueue() − add (store) an item to the
queue.
⚫ dequeue() − remove (access) an item from
the queue.
⚫ peek() − get the element at front of the
queue without removing it.
⚫ isfull() − checks if queue is full.
⚫ isempty() − checks if queue is empty.
int peek()
{
return queue[front];
}
QUEUE BASIC OPERATIONS
isfull()
bool isfull()
{
if(rear == MAXSIZE - 1)
return true;
else
return false;
}
isempty()
bool isempty()
{
if(front < 0 || front > rear)
return true;
else
return false;
}
Enqueue (Insert) Operation
⚫ Step 1 − Check if queue is full.
⚫ Step 2 − If queue is full, produce overflow
error and exit.
⚫ Step 3 − If queue is not full, increment rear
pointer to point next empty space.
⚫ Step 4 − Add data element to the queue
location, where rear is pointing.
⚫ Step 5 − return success
Enqueue (Insert) Operation
void enqueue(int data)
{
if(isfull())
return 0;
rear = rear + 1;
queue[rear] = data;
}
Dequeue (Delete) Operation
⚫Step 1 − Check if queue is empty.
⚫Step 2 − If queue is empty, produce underflow error
and exit.
⚫Step 3 − If queue is not empty, access data where
front is pointing.
⚫Step 4 − Increment front pointer to point next
available data element.
Dequeue (Delete) Operation
Implementation of dequeue() in C programming
language −
int dequeue()
{
if(isempty())
return 0;
int data = queue[front];
front = front + 1;
return data;
}
IMPLEMENTATION OF QUEUE
⚫ The implementation of queue is given below
JOB SCHEDULING
⚫ Queues are used for the creation of a job-queue
by an operating-system. If operating-system does
not use, then the jobs are processed in the order
they enter the system
Circular Queues
When an array is used to have a circular queue : Front is one
position counterclockwise from the first element and rear is current end
[3] [4]
C D
[2] [5]
B E
A F
[6]
[1] G
[0] [7]
Front=0, Rear=7
Circular Queue
[3] [4]
C D
[2] [5]
B E
A F
[6]
[1] G
[0] [7]
Front=0, Rear=7
A B c A A A A A
Circular Queues
⚫ The addition and deletion operations on circular
queue are given below
DYNAMICALLY ALLOCATED
ARRAYS
DYNAMICALLY ALLOCATED
ARRAYS
Program A: Addition operation on CQ
void addq(element item)
{
rear= (rear+1) % capacity;
if(front == rear)
queueFull();
queue[rear]=item;
}
void queueFull( )
{
element *newqueue;
MALLOC(newqueue, 2 * capacity * sizeof(queue));
/*copy from queue to newqueue*/
int start=(front+1)%capacity;
if (start < 2)
/* no wrap around */
copy(queue+start, queue+start+capacity-1, newqueue);
else
{
/* queue wraps around*/
copy(queue+start, queue+start+capacity, newqueue);
copy(queue, queue+rear+1, newqueue+capacity-start);
}
/* switch to newqueue */
front = 2*capacity-1;
rear = capacity-2;
capacity*=2;
free(queue);
queue = newqueue;
}
Dequeues
⚫ Double ended queue is one in which
elements can be inserted or deleted at
either end but not in the middle.
⚫ Deques are implemented as circular queue
⚫ 2 types of dequeue are
1.Output restricted – allows deletion at
only one end (front) but insertion at both
ends
2.Input restricted - allows insertion at
only one end (rear) but deletion at both
ends
Operations on a Dequeue
Operations on a Dequeue
●initialize(): Make the queue empty
●empty(): Determine if queue is empty
●full(): Determine if queue is full
●enqueueF(): Insert an element at the front end of the queue
●enqueueR(): Insert an element at the rear end of the queue
●dequeueR(): Delete the rear element
●dequeueF(): Delete the front element
●print(): Print elements of the queue
PRIORITY QUEUE
⚫ Priority Queue is more specialized data structure
than Queue.
⚫ In Priority queue items are ordered by key value so
that item with the lowest value of key is at front
and item with the highest value of key is at rear or
vice versa.
⚫ priority to item is based on its key value. Lower
the value, higher the priority
Representations of priority queue
queue
⚫ insert / enqueue − add an item to the rear of the
queue.
⚫ remove / dequeue − remove an item from the fro
the queue
⚫ Peek − get the element at front of the queue.
⚫ isFull − check if queue is full.
⚫ isEmpty − check if queue is empty.
Insert / Enqueue Operation
Remove / Dequeue Operation
⚫ Whenever an element is to be removed from queue, queue get the element using item
count. Once the element is removed, Item count is reduced by one.
One-Way List Representation of a Priority Queue
[1] Each node in the list will contain three items of information: an information Field INFO, a
priority number PRN, and a link number LINK
(b) when both have same priority but X was added to the list before Y
PRIORITY QUEUE
⚫ Algorithm deletes and processes the first element in a priority queue which
3. Process ITEM
4. exit
Algorithm that adds an item with priority number N to a priority queue which is
maintained in memory as a one-way list.
1. Traverse the one-way list until finding a node X, whose priority number
2. If no such node is found , insert ITEM as the last element of the list.
MAZE PROBLEM
∙ Mazes have been an intriguing subject for many years. Experimental
psychologists train rats to search mazes for food.
∙ The representation of maze is done using 2D array in which 0’s represent the
open paths and 1’s the barriers.
∙ The rat starts at the top left and is to exit at the bottom right. With the maze
represented as 2D array, the location of the rat in the maze can at any time be
described by the row and column position,
MAZE PROBLEM
⚫ If X is the spot of our current position, maze[row][col]. Following figure
represents the possible moves from this position. It points to specify the 8
directions of movements:- N, NE, E, SE, S, SW, W, NW as shown.
⚫ The border conditions of the maze can be represented by a border of ones.
Thus, an mxp maze will require an (m+2)x(p+2) array. The entrance is at
position[1][1] and exit at [m][p].
MAZE PROBLEM
⚫ The possible directions of movement can be predefined in the move array as
shown in following table. The 8 possible directions of movement are given by 0
to 7.
Name Dir move[dir].vert move[dir].horiz
N 0 -1 0
NE 1 -1 1
E 2 0 1
SE 3 1 1
S 4 1 0
SW 5 1 -1
W 6 0 -1
NW needed to create
The C declaration 7 this table are:--1 -1
typedef struct
{
short int vert;
short int horiz;
}offsets;
offsets moves[8];
MAZE PROBLEM
∙ If the rat is at position maze[row][col] and the next move position can be
obtained as follows:-
nextCol = col+move[dir].horoz;
∙ Here, the best possible direction is not predictable. So, the current position of
the rat is saved and arbitrarily pick a possible move.
∙ By saving the current position, it is possible to return to it back and try another
path if it is a hopeless path.
∙ Thus, all possible moved starting from the north and moving clockwise are
examined.
∙ When searching the maze from entrance to exit, all positions with 0 will be on the stack
when the exit is reached.
∙ Since, an mxp maze can have at most mp zeros, it is sufficient for the stack to have this
capacity.
Initial maze algorithm:-
while(stack is not empty)
{ /* move at position at top of stack*/
while(there are moves from current position)
{
<nextRow, nextCol>=coordinates of next move;
dir=direction of move;
if(nextRow == EXIT_ROW) && (nextCol == EXIT_COL))
success;
if(maze[nextRow][nextCol] == 0 && mark[nextRow][nextCol] == 0)
{ /* legal move and haven’t been there */
mark[nextRow][nextCol] = 1;
/* save current position & direction */
add <row, col, dir> to the top of the stack;
row = nextRow;
col = nextCol;
dir = North;
}
}
}
printf(“No path found\n”);
Maze Search function:-
void path()
{ /* output a path through the maze if such a path exists*/
int i, row, col, nextRow, nextCol, dir, found = FALSE;
Element position;
mark[1][1]=1;
top=0;
stack[0].row=1;
stack[0].col=stack[0].dir=1;
while (top>-1 && !found)
{
position = pop();
row=position.row;
col=position.col;
dir=position.dir;
while(dir<8 && !found)
{
/*move in direction dir */
nextRow = row+move[dir].vert;
nextCol = col+move[dir].horiz;
if(nextRow == EXIT_ROW && nextCol == EXIT_COL)
found – TRUE;
elseif(!maze[nextRow][nextCol] && !mark[nextRow][nextCol])
{
mark[nextRow][nextCol] = 1;
position.row = row;
position.col = col;
position.dir = ++dir;
push(position);
row=nextRow;
col=nextCol;
dir=0;
}
else ++dir;
}
}
if(found)
{
printf(“the path is:\n”);
printf(“ row col\n”);
for(i=0;i<=top;i++)
printf(“%2d %5d\n”, stack[i].row, stack[i].col);
printf(“%2d %5d\n”, row, col);
printf(“%2d %5d\n”, EXIT_ROW, EXIT_COL);
}
else
printf(“The maze doesnot have a path”);
}
Multiple stacks and
queues
Two stacks
bottommost bottommost
stack 1 stack 2
154
initial configuration for n stacks in memory
The relevant declaration are:
#define MEMORY_SIZE 100 /* size of memory */
#define MAX_STACKS 10 /* max number of stacks plus 1 */
element memory[MEMORY_SIZE];
int top[MAX_STACKS];
int n; /* number of stacks entered by the user */
To divide the array into equal segment, we use the following code:
top[0]=boundary[0]=-1;
for(j=1;j<n;j++)
top[j]=boundary[j]=(MEMORY_SIZE/n)*j;
boundary[n]=MEMORY_SIZE-1;
155
void push(int i,element item)
{
if(top[i]==boundary[i+1])
stackfull(i);
memory[++top[i]]=item;
}
Element pop(int i)
{
if(top[i]==boundary[i])
return stackempty(i);
return memory[top[i]--];
}
Find j, stack_no < j < n such that top[j] <
boundary[j+1]
or, 0 ≤ j < stack_no
157