You are on page 1of 7

Data Structures & Algorithms

SECTION 3

OBJECTIVES: At the end of the session, the student is expected to be able to


1. explain implementation issue pertaining to the sequential representation of a
stack using a one-dimensional array
2. discuss some important problems in computer science whose solution
requires the use of a stack
3. generalize the algorithm to convert arithmetic expressions from infix to postfix
form to include expressions involving other operators (unary, relational,
logical)
4. assess the suitability of using a stack to solve a given problem on the
computer

DISCUSSION:

Stack is one of the simplest but important data structures used in computer
algorithms. It finds applications in such diverse tasks as pattern recognition, list and
tree traversals, evaluation of expressions, resolving recursion, etc.
Abstractly, we can think of a stack as a linearly ordered set of elements on
which is imposed the discipline of “last-in, first-out”.
The two basic operations defined on a stack (Both operations are allowed at the top
of the stack only.)
a. insertion (push)
b. deletion (pop)

Insertion Deletion
(here only) (here only)

an
an-1
.
.
ai
ai-1
.
.
a2
a1

The stack as an ADT.

Section 3 Page 1 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

There are two simple ways of implementing the ADT stack as a concrete data
structure, namely:
1. as a sequentially allocated one-dimensional array or vector
2. as a linked linear list

SEQUENTIAL REPRESENTATION OF A STACK

The figure below shows the sequential representation of a stack in a vector S


of size n. The elements marked X comprise the stack, with the top element pointed
to by the variable top.

1 2 3 4 5 6 7 8 9 . . . . . . n- n
1
S(1:n) X X X X X X X X X
Deletion
Insertion

To initialize the stack, we set top Å0. It follows from this that the condition
top = 0 means that the stack is empty. The condition top = n on the other hand
means that the stack is full. An attempt to insert onto a full stack results in an
overflow condition; an attempt to delete from an empty stack results in an underflow
condition. Procedures to implement the insertion and deletion operations must test
for the occurrence of these conditions.

The EASY procedures SPUSH and SPOP implement the insertion


and deletion operations for a sequentially allocated stack in a vector S of size n
following the conventions stated above.

procedure SPUSH(S, n, top, x)


array S(1:n)
if top = n then call STACKFULL
top Å top + 1
S(top) Å x
end SPUSH

Section 3 Page 2 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

Procedure STACKFULL handles the occurrence of an overflow condition. It may take


the two possible courses of action:

1. Reallocate memory; if additional vector space becomes’ available, return


control to SPUSH via a return statement and complete the insertion
operation.
2. Issue an error message and return control to the operating system.

procedure SPOP(S, n, top, x)


array S(1:n)
if top = 0 then call STACKEMPTY
else [ X Å S(top); top Å top-1]
end SPOP

Procedure STACKEMPTY handles the occurrence of an underflow condition. The


action it takes depends on the particular application.

Example. Conversion of arithmetic expressions from infix to postfix form

This is an old problem in Computer Science. The problem has its roots in the
fact that the form in which we have been taught to write arithmetic expressions since
our elementary school days (which is infix) is not the form suitable for the efficient
evaluation of an expression by the computer (which is postfix). Thus, the need to
convert from infix to postfix form.

To put the problem in proper perspective, let us clarify what we mean by the infix
and postfix forms of an expression.

1. An expression is in infix form if every subexpression to be evaluated is of the


form operand-operator-operand. The subexpressions may or may not be
enclosed in parentheses. Their order of evaluation depends on specified
precedence values with the expression normally scanned repeatedly from left
to right during its evaluation.

Section 3 Page 3 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

2. An expression is in postfix form if every subexpression to be evaluated is of


the form operand-operand-operator. Subexpressions are never parenthesized. The
expression is scanned only once from left to right and subexpressions of the form
operand-operand-operator are evaluated in the order in which they are encountered.

Before a postfix expression is evaluated, we must first check if it is well-formed.


There is a simple theorem which states what a well-formed postfix expression is, but
first let us define few terms.

1. The degree of an operator is the number of operands it has.


2. The rank of an operand is 1. The rank of an operator is 1 minus its degree.
The rank of an arbitrary sequence of operands and operator is the sum of
the ranks of the individual operands and operators.
3. If z = x | y is a string, then x is the head of z. x is a proper head if y is a null
string.

Now, the theorem: A postfix expression is well-formed iff the rank of every
proper head is greater than or equal to 1 and the rank of the expression is one.

We will assume for ease of exposition, that the arithmetic expressions to be


converted involve the five binary operators +, -, *, /, and ^ only. The table below
lists these operators in decreasing order of priority.

Operator Priority Property Example

^ 3 Right Associative a^b^c ≡ a ^ (b^c)


*, / 2 Left Associative a/b/c ≡ (a/b) / c
+, - 1 Left Associative a-b-c ≡ (a-b) - c

Shown below are examples of arithmetic expressions in infix form and the
corresponding postfix expressions. It is easy to verify that the expressions are well-
formed and that both forms evaluate to the same quantity.

Section 3 Page 4 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

Infix Expression Postfix Expression

a+b*c/d abc*d / +
a/b ∧ c∧d abcd ∧ ∧/
a*( b + (c + d) / e ) – f abcd + e / + * f –

Even with these few examples we can already deduce some general patterns or
rules. Can you cite any?
1. The order of the operands in both forms is the same, whether or not
parentheses are present in the infix expression.
2. The infix expression contains no parentheses, then the order of the operators
in the postfix expression is according to their priority ( ∧ followed by + or – ).
For operators of the same priority, the order in the infix form is preserved.
3. If the infix expression contains parenthesized subexpressions, Rule 2 applies
for each subexpression.

With a little more thought, and guided by these observations, it should be


possible to work out an algorithm to convert an infix expression to postfix form. It is
readily apparent that such an algorithm will use a stack.
The algorithm to perform the desired conversion from infix to postfix form uses
two priority numbers associated with each token (operand, operator or opening
parenthesis) – a priority number when the token, say x, is an in-coming symbol,
icp(x); and a priority number when the token is in the stack, isp(x). These numbers
are summarized in the table below.

Token x Icp(x) isp(x) rank

operand 0 - +1
+ - 1 2 -1
* / 3 4 -1
∧ 6 5 -1
( 7 0 -

Section 3 Page 5 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

Now, the algorithm.


1. Get next token, say x.
2. If x is an operand, then output x onto the stack.
3. If x is the ( , then push x onto the stack.
4. If x is the ) , then output stack elements until an ( is encountered. Pop stack
once more to delete the (. If top = 0, the algorithm terminates.
5. If x is an operator, then while icp(x) < isp(stack(top)), output stack elements;
else, if icp(x) > isp(stack(top)), then push x onto the stack.
6. Go to step 1.
Let us apply the algorithm to the expression (A * (B + (C-D) / E)+F ). Note that the
whole expression is parenthesized.
In-coming Stack Output Remarks
Symbol Elements
( ( Push ( onto stack
A ( A Output Operand
* (* A icp[*] > isp [ ( ]
( (*( A
B (*( AB
+ (*(+ AB icp[+] > isp [ ( ]
( (*(+( AB
C (*(+( ABC
- (*(+(- ABC icp[ - ] > isp [ ( ]
D (*(+(- ABCD
) (*(+ ABCD- Pop Stack until top element
is (; pop again to delete (
/ (*(+/ ABCD- icp[ / ] > isp [ + ]
E (*(+/ ABCD-E
) (* ABCD-E/+ Pop stack until …
+ ( ABCD-E/+* icp[ + ] < isp [ * ]
+ (+ ABCD-E/+* icp[ + ] > isp [ ( ]
F (+ ABCD-E/+*F
) ABCD-E/+*F+ Pop stack until …
(top = 0, stop )

Section 3 Page 6 of 7
Jennifer Laraya-Llovido
Data Structures & Algorithms

The EASY function procedure POLISH implements the algorithm to convert an


arithmetic expression from infix to postfix form. (Postfix is also called reverse Polish
notation, after the Polish logician Jan Lukasiewicz). The procedure incorporates the
aforementioned test for a well-formed postfix expression.

procedure POLISH(infix, postfix)


//Give an input string infix representing a parenthesized infix expression, POLISH
generates the corresponding postfix expression in the string postfix. POLISH uses
the following procedures:
NEXTTOKEN(string) – returns next token in string
ICP(x) – returns icp(x)
ISP(x) – returns isp(x)
RANK(x) – returns rank(x)
LENGTH(string) – returns length of string
POLISH returns rank of postfix expression as function value.//
array S (1:100)
top Å 0; postfix Å ‘’ // null string //
loop
x Å NEXTTOKEN (infix)
case

: ICP (x)=0; postfix | x // concatenation //


: x = ‘(‘ ; call SPUSH (S, 100, top, x)
: x = ‘)’ ; [ while S(top) <> ‘(‘ do
call SPOP(S, 100, top, x)
postfix Å postfix | x
endwhile
call SPOP (S, 100, top, x)
if top = 0 then go to TEST ]
: else : [while ICP (x) < ISP (S(top)) do
call SPOP(S, 100,top, x)
postfix Å postfix |x
endwhile
call SPUSH(S, 100, top, x)]
endcase
forever
//Determine if generated postfix expression is well-formed//
TEST: len Å LENGTH (postfix)
rÅ0
while len <> 0 do
x Å NEXTTOKEN (postfix)
r Å r + RANK (x)
if r < 1 then return (r)
len Å len –1
endwhile
return (r)
end POLISH

Section 3 Page 7 of 7
Jennifer Laraya-Llovido

You might also like