You are on page 1of 33

Lecture 4

On

Stack

1
Stack is a Data structure that manages data elements linearly but provides access at
only one end i.e. data elements can be inserted and removed from one end only.

Example 1:-

Example 2:- the following figure illustrate a stack which can accommodate
maximum 10 elements

2
3
NOTE:-

In Stack, the elements are removed only in the inverse order of their arrival i.e. the
last inserted element is removed first of all so, it has last so, it has last-in/first
in/first-out (LIFO) behavior.

Why Stack

There are many practical situations which can be best handled using stack

The papers put in the tray of a printer. The papers from the tray are removed
by the printer in reverse order they are put in the tray
Stack is used to evaluate expressions like 10x(12+7)
A runtime system uses a stack to handle function calls and return.

Specification of Stack

Elements: Any valid data type


Structure: An arrangement of elements that allows to remove first of all the
element that is stored last of all

4
Domain: Number of elements is bounded
Operations:

Representation of Stack

Stack can be represented as


- Using Array
- Using Linked List

5
6
Performance Comparison Performance Comparison

Array Based Implementation

An array p based implementation suffers from the drawback that all the
storage space must be reserved in advance and the maximum depth of
the stack is limited to this arrays size.
Time complexity of all stack operations is O (1).

Linked List based Implementation

The time complexity of all operations is O (1).


For applications in which the maximum stack size is known ahead of
time, an array is suitable
If the maximum stack size is not known beforehand we can use If the
maximum stack size is not known beforehand, we can use a linked list

ARRAY BASED STACK


The stack, which is implemented using array is called array based stack. To create an
array based stack, at first we have to declare an array with required size.
1. # define MAXSIZE 10
int STACK [MAXSIZE];
int top = -1; // null value

7
2. # define MAXSIZE 10
Struct stack
{
int S [MAXSIZE];
int top;
}

8
9
OPERATIONS
1. PUSH OPERATION
Push operation means to add an element to a stack.
Here, we shall use array based stack, so , an array will be treated as a
stack.
We need an indicator or index identifier to add element to the stack and
this indicator will mark the top of the stack.
To add an element we have to check whether the array is already full or
not.
If the array is already full, then we can not add any element, other we
can.

10
11
Performance:-
The performance of the stack data structures for n elements is:
The space complexity is O(n)
The time complexity of each operation is O(1)

12
The size of the stack, implemented using array , must be defined in advanced,
i.e. , a priori. Moreover, the size cannot be changed.

LINK BASED STACK


The stack that is created or implemented using a linked list is called a link
based stack or linked stack.

CREATE A LINKED BASED STACK


To create a linked stack, we have to use a pointer to point the top element
(node) of the stack. We named this pointer as top.
We create an empty stack first, so, the top (pointer) will be null.
Then we shall create a node
After that, we make link between the new node and stack.
To make link between the new node and the stack, at first the next pointer
of the new node will point the top node of the stack, then top(pointer) will
point the new node. Thus we create a linked stack.
ALGORITHM TO CREATE A LINKED STACK
// top is the pointer that points the top node of the stack and nptr is the pointer to the
new node. Item is an inter type variable.
1. Declare node and pointer:
Struct node
{

13
Int data;
Node *next;
};
Node *top, *nptr;
2. Create empty list: top = NULL;
3. Create a new node:
nptr = new (node);
nptr data = item;
nptr next = NULL;
4. Make linked between stack and new node:
If ( top = = NULL )
top = nptr;
else
{
nptr next = top;
top = nptr;
}
5. Repeat step 3 and 4 to create stack of several nodes.
6. Output a linked stack.

PUSH OPERATION (ADD AN ELEMENT TO THE STACK)


Push operation in a linked stack can be performed simply by adding a new
node to the stack.

ALGORITHM
SAME AS PREVIOUS ALGORITHM (except step 5)

14
// Push operation function using C
Void push()
{
Int data;
Struct node *n = (struct node *) malloc (sizeof (struct node));
Printf(\n Enter the element to push in stack:);
Scanf(%d, &data);
ninfo =data;
nnext = top;
top = n;
}

POP OPERATION (Deletion of an item)


Pop operation means to delete top node from the linked stack.
Pop operation in the linked list is very simple
We know the top (Pointer), points the top node of the stack, so to delete top
node, we use a temporary pointer that will point the top node and advanced
the top to the next node (using next pointer).
Now the top is pointing the next node
We delete the top node using temporary pointer.

ALGORITHM: algorithm to delete a node from a linked stack


// top is a pointer that points the top node of the stack and tptr is a temporary pointer
used to delete the node.

1. Declare node and pointers;


struct node

15
{
Int data;
Node * next;
};
Node *top, *tptr;
2. Input a linked stack
tptr = top;
3. Advanced (Move forward)the pointer, top to perform deletion:
If (top Next != NULL)
{
top = top next;
delete (tptr);
}
Else top = NULL;
4. Output updated linked list.

// Pop operation function using C


int pop ()
{
int data;
struct node * t= top;
if (top == NULL)
printf (\n UNDER FLOW);
else
{
data = topinfo;
top = topnext;

16
free(t);
}
return(data)

Infix Expressions
An expression in which every binary operation appears between its operands.
Example: (i) a + b : + is a binary operation and a and b are its operands
(ii) ( a + b) c *
Prefix Expressions (Polish Notation)
An expression in which operator comes before its operands Example:
Example: (i) a + b + a b
(ii) ( a + b ) * c * + a b c
(iii) a + ( b * c ) + a * b c

17
Postfix Expressions (Reverse Polish Notation)
An expression in which operator comes after its operands
Example: (i) a + b a b +
(ii) ( a + b ) * c a b + c *
(iii) a + ( b * c ) a b c * +

Conversion of Infix form to Postfix Form


An infix expression can be converted into postfix by two methods: parenthesis
method and Stack method.

18
(1) Parenthesis method:- The following steps are used to convert an infix
expression to postfix expression by parenthesis methods:
(i) Parenthesize the expression starting from left to right.
(ii) During parenthesizing the expression, the operands associated with
operator having higher precedence are first parenthesized
(iii) The sub-expression (part of expression) which has been converted
into postfix is to be treated as single operand.
(iv) Once the expression is converted to postfix form, remove the
parenthesize.

To evaluate any arithmetic expression, the order of precedence and associativity of


the operators should be known. This is as follows.

Example 1: - Give postfix form of expression for the following:

19
A/(B+C)+D*(EF)

SOLUTION:-.

Algorithm for converting infix Expression to postfix form Postfix (Q, P)


Suppose Q is an arithmetic expression written in Q INFIX NOTATION. This
algorithm finds the equivalent postfix expression P.
1. Push ( on to stack and add ) to the end of Q.
2. Scan Q from left to right and repeat steps 3 to 6 for each statement of Q until
the stack is empty.
3. if an operand is encountered , add it top.
4. if a left parenthesis is encountered, push it onto stack.
5. if an operator x is encountered then
a. Add x to stack
b. Repeatedly pop from stack and add P each operator (on top of stack)
which has the same precedence as or higher precedence than x
6. if a right parenthesis is encountered then
a. Repeatedly pop from stack and add top each operator (on the top of
stack until a left parenthesis is encountered)
b. Remove the left parenthesis (Do not add the left parenthesis top)
Example 2: - Give postfix form of expression for the following:
5 * ( 6 + 2 ) - ( 12 / 4 )

20
SOLUTION: 5 * ( 6 + 2 ) - ( 12 / 4 ) )

Example 3: - Give postfix form of expression for the following:

Not A OR Not B AND Not C

SOLUTION:-.

Example 4: - Give postfix form of expression for the following:

21
Conversion of Infix form to Prefix Form
This algorithm is bit tricky
In this we first reverse the input expression A + B * C will become C*B
+ A and then we do the conversion and then again we reverse to get the result.
Doing this has an advantage that except for some minor modification
algorithm for infix to prefix remains almost same as the one for infix to
postfix.
Algorithm and program is same but only the difference is that firstly we
reverse the given string and then evaluate it and then again reverse it.
Example:- A + B * C
C * B + A
( (C * B + A )
((C * B) + A)
((CB*) + A)
CB * A+
+A * BC

22
ALGORITHM TO EVALUATE A POSTFIX EXPRESSION

This algorithm finds the value of an arithmetic expression written in postfix notation.

23
Example: - Evaluate the following postfix expression:

6 2 3 + - 3 8 2 / + * 2 $ 3 +

SOLUTION:-.

24
PARENTHESIS CHECKER (CHECKING THE VALIDITY OF AN
ARITHMETIC EXPRESSION)

Parenthesis checker is a program that checks whether a mathematical


expression, is properly parenthesized.
We will consider three sets of grouping symbols:
The std. parenthesis ( )
The braces { }
The brackets [ ]

For an input expression, it verifies that for each left parenthesis brace, or
bracket, there is a corresponding closing symbol and the symbols are
appropriately nested.

Some example of valid inputs Some example of invalid inputs

() ([]{}

({}[]) {}[])

({[] []}) ({([]})

25
26
Example:-

27
MINIMIZING OVERFLOW OR MULTIPLE STACKS
If we represent a stack using an array, we have to allocate sufficient space for
the stack. If the space allocated to an array is less, it may result in frequent
overflows and we may have to modify the code and reallocate more space for
array.
If we attempt to reduce the number of overflows by allocating large space for
the array, it may result to wastage of space if the typical size of the stack is
very small as compared to actual size of the array. Therefore we can say that
there exists a trade-off between the number of overflows and the space.
Various techniques have been developed which modify the array
representation of stacks one possibility to reduced this trade-off is to represent
more than one stack in the same array of sufficient size.
Example:- suppose a given algorithm requires two stacks, A and B. one can define
an array STACK with n1 elements for stack A and an array STACK B with n2
elements for stack B. overflow occur when either stack A contains more than n1
elements or stack B contains more than n2 elements.

Solution: - we define a single array STACK with n = n1 + n2 elements for stacks A


and stack B together as below

STACK[0] represent the bottom of stack A and let stack A grows from left to
right

28
STACK [n] represent as the bottom of stack B and let stack B grows from
right to left.
In this case, overflow will occur only when A and B together have more than
n = n1 + n2 elements.
This technique will usually decrease the number of times overflow occurs
even though we have not increased the total amount of space reserved for the
two stacks.

MORE THAN TWO STACKS

If we have only 2 stacks to represent. then the solution is simple. We can use
V(1) for the bottom most element in stack 1 and V(m) for the corresponding
element in stack 2.
Stack 1 can grow towards V(m) and stack 2 towards V(1).
It is therefore possible to utilize efficiently all the available space.
Can we do the same when more than 2 stacks are to be represented?
The answer is no, because a one dimensional array has only two fixed points
V(1) and V(m) and each stack requires a fixed point for its bottommost
element.
When more than two stacks, say n, are to be represented sequentially, we can
initially divide out the available memory V(1:m) into n segments and allocate
one of these segments to each of the n stacks.
This initial division of V(1:m) into segments may be done in proportion to
expected sizes of the various stacks if the sizes are known.
In the absence of such information, V(1:m) may be divided into equal
segments. For each stack i we shall use B(i) to represent a position one less
than the position in V for the bottommost element of that stack.

29
T(i), 1 i n will point to the topmost element of stack i. We shall use the
boundary condition B(i) = T(i) iff the i'th stack is empty.
If we grow the i'th stack in lower memory indexes than the i + 1'st, then with
roughly equal initial segments we have

As the initial values of B(i) and T(i), (see figure below). Stack i, 1 i n can
grow from B(i) + 1 up to B(i + 1) before it catches up with the i + 1'st stack.

30
It is convenient both for the discussion and the algorithms to define B(n + 1) =
m. Using this scheme the add and delete algorithms become:

procedure ADD(i,X)
//add element X to the i'th stack, 1 i n //
if T(i) = B(i + 1) then call STACK-FULL (i)

T(i) T(i) + 1

V(T(i)) X //add X to the i'th stack//

end ADD

procedure DELETE(i,X)

//delete topmost element of stack i//

if T(i) = B(i) then call STACK-EMPTY(i)

X V(T(i))

T(i) T(i) - 1

end DELETE

The STACK_FULL condition in algorithm ADD implies that all locations of


V are in use. In fact, there may be a lot of unused space between stack j and
j+1 for 1<=j<=n and j ! = i, the procedure STACK_ FULL ( i ) should
therefore determine whether there is any free space in V and shift stacks
around so as to make some of this free space available to the ith stack.
Several strategies are possible for the design of algorithm STACK_FULL.
The primary objective of algorithm STACK_FULL is to permit the adding of

31
elements to stacks so long as there is some free space in V. one way to
guarantee this is to design STACK_FULL along the following lines:

(a) Determine the least j , i <j<=n such that there is free space between stacks j
and j+1, i.e. T(j) < B(j+1). If there is such a j, then move stacks i+1,
i+2,.j one position to right (treating V(1) as leftmost and V(m) as
rightmost), thereby creating a space between stacks i and i+1.
(b) If there is no j as in a), then look to the left of stack i. find the largest j
such that 1 <=j <i and there is space between stacks j and j+1, i.e. T (j) < B
(j+1). If there is such a j, then move stacks j+1, j+2,i one space
left creating a free space between stacks i and i +1.
(c) If there is no j satisfying either the conditions of a) or b), then all m spaces
of V are utilized and there is no free space.

32
33

You might also like