0% found this document useful (0 votes)
11 views113 pages

Unit IV Stack

Uploaded by

gifases267
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views113 pages

Unit IV Stack

Uploaded by

gifases267
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 113

UNIT-IV

Stack
Contents:
• Stacks- concept, Primitive operations, Stack Abstract
Data Type, Representation of Stacks Using Sequential
Organization, stack operations, Multiple Stacks,
Applications of Stack- Expression Evaluation and
Conversion, Polish notation and expression
conversion, Need for prefix and postfix expressions,
Postfix expression evaluation, Linked Stack and
Operations.
• Recursion- concept, variants of recursion- direct,
indirect, tail and tree, Backtracking algorithmic
strategy, use of stack in backtracking. Case Study- 4
Queens problem, Android- multiple tasks/multiple
activities and back stack.
Introduction
• A stack is a list of elements in which an element may be
inserted or deleted only at one end, called the top of the
stack.
• Stacks are sometimes known as LIFO (last in, first out)
lists.
• As the items can be added or removed only from the top
i.e. the last item to be added to a stack is the first item to
be removed.
• The two basic operations associated with stacks are:
 Push: is the term used to insert an element into a stack.
 Pop: is the term used to delete an element from a stack.
push operations on stack
POP operations on stack
Abstract Data Type: Stack

• A finite number of objects


– Not necessarily distinct
– Having the same data type
– Ordered by when they were added
• Operations
– isFull()
– isEmpty()
– push(newEntry)
– pop()
– peek()/top()
Implementing a Stack
• There are two ways to implement a stack
– Using array
– Using linked list
• Which method to use depends on the
application
– what advantages and disadvantages does each
implementation have?
Implementing Stacks: Array
• Advantages
– best performance
• Disadvantage
– fixed size
• Basic implementation
– initially empty array
– field to record where the next data gets placed into
– if array is full, push() returns false
• otherwise adds it into the correct spot
– if array is empty, pop() returns null
• otherwise removes the next item in the stack
#define MAX 10
class Stack
{
int top;
public:
int a[MAX]; //Maximum size of
Stack
Stack() { top = -1; }
void push(int x);
int pop();
int top();
bool isEmpty();
bool isFull();

};
bool Stack::isEmpty() int Stack::top() / peek()
{ {
return (top < 0); if (!isEmpty()
} return a[top];
}

bool Stack::isFull()
{
return (top == MAX-
1);
}
void Stack::push(int x) int Stack::pop()
{ {
if (isFull()) if (isEmpty())
{ {
cout << "Stack Overflow"; cout << "Stack Underflow"
return -1;
} }
else
else
{
a[++top] = x;
{
} int x = a[top--];
} return x;
}
}
Stack Applications
Stacks are useful for any application requiring
LIFO storage. There are many, many of these.
• evaluating arithmetic expressions
• expression conversion
• parsing context-free languages
• function call management
• traversing trees and graphs (such as depth
first traversals)
• recursion removal
Group-C
Assignment-1
• A palindrome is a string of character that‘s the same forward
and backward. Typically, punctuation, capitalization, and spaces
are ignored. For example, ‖Poor Dan is in a droop‖ is a
palindrome, as can be seen by examining the characters ―poor
danisina droop‖ and observing that they are the same forward
and backward. One way to check for a palindrome is to reverse
the characters in the string and then compare with them the
original-in a palindrome, the sequence will be identical. Write
C++ program with functions-
1. To check whether given string is palindrome or not that uses a
stack to determine whether a string is a palindrome.
2. To remove spaces and punctuation in string, convert all the
Characters to lowercase, and then call above Palindrome
checking function to check for a palindrome
3. To print string in reverse order using stack
#define SIZE 10 Stack :: Stack()
class Stack {
{ top = -1;
private : strcpy(ST,"");
int top; }
public :
char ST[SIZE];
Stack(); int Stack :: isEmpty()
void push(char X); {
char pop(); if(top == -1)
int isEmpty(); return 1;
int isFull(); else
void convert_string(char[], char[]); return 0;
int ispalindrome(char[]); }
void reverse(char[]);
};
int Stack :: isFull() char Stack :: pop()
{ {
if(top == SIZE-1) if(!isEmpty())
return 1; {
else char X ;
return 0; X = ST[top];
} top--;
return X;
void Stack :: push(char X) }
{ }
if(!isFull())
{
top++;
ST[top] = X;
}
else
cout<<"\nStack Overflow !! Error!!";
}
/* To remove spaces and punctuation in string, convert all the
Characters to lowercase, and then call above Palindrome checking
function to check for a palindrome */

void Stack::convert_string(char Str[], char Str1[])


{
int i=0, j=0;
while(Str[i]!='\0')
{
if(Str[i] >= 'a' && Str[i] <= 'z')
Str1[j++] = Str[i++];
else if(Str[i] >= 'A' && Str[i] <= 'Z')
Str1[j++] = Str[i++] + 32;
else if(!isalpha(Str[i]) || Str[i]== ' ')
i++;
}
Str1[j] = '\0';
}
• ASCII value of a=97
• ASCII value of A=65;
• To change char from ‘A’ to ‘a’=65+32
/* C++ function to check whether given string is palindrome or not that uses
a stack to determine whether a string is a palindrome.*/

int Stack :: ispalindrome(char Str[30]) {


int i,flag=1;
for(i = 0; Str[i] != '\0'; i++)
push(Str[i]);
i=0;
while(!isEmpty()) {
if(Str[i++] != pop())
{
flag = 0;
top=-1;
break;
}
}
return flag;
}
/* To print string in reverse order using stack */

void Stack :: reverse(char Str[30])


{
for(int i = 0; Str[i] != '\0'; i++)
push(Str[i]);
cout<<"\nReverse String = ";
while(!isEmpty())
{
cout<<pop();
}
}
int main()
{
int ch;
char Str[30],Str1[30];
Stack S;
cout<<"\nEnter the string to be checked for palindrome : ";
cin.ignore();
cin.getline(Str,29);
cout<<"\nEntered String is "<<Str;
S.convert_string(Str,Str1);
cout<<"\nconverted String is : "<<Str1;

if(S.ispalindrome(Str1))
cout<<"\nGiven string is a palindrome\n";
else
cout<<"\nGiven String is not a palindrome\n“;
cout<<"\nEnter the string to be reversed : ";
cin.ignore();
cin.getline(Str,29);
cout<<"\nString entered is "<<Str;
S.reverse(Str);

return 0;
}
• cin.ignore() is a predefined function which
ignores/clears one or more characters from the
input buffer.
The cin treats a white space i.e " " , "\t" , "\n" as
delimiter character.
• cin.getline():
• It allows to specify the terminating character for
input. The default value is the newline character.
• This function reserve one character for the required
terminating character.
Example: Evaluating postfix expressions

• Postfix notation is another way of writing arithmetic


expressions.
• In postfix notation, the operator is written after the
two operands.
infix: 2+5 postfix: 2 5 +
• Expressions are evaluated from left to right.

• Precedence rules and parentheses are never


needed!!
Postfix Evaluation Algorithm

• Assume we have a string of operands and operators, an


informal, by hand process is
• Scan the expression left to right
• Skip values or variables (operands)
• When an operator is found, apply the operation to the
preceding two operands
• Replace the two operands and operator with the calculated
value (three symbols are replaced with one operand)
• Continue scanning until only a value remains--the result of
the expression
• A more formal algorithm:
1. Create a new stack
2. while(input stream is not empty)
2.1 token = getNextToken();
2.2 if(token instanceof operand)
2.2.1 push(token);
else if (token instance of operator)
2.2.1’ op2 = pop();
2.2.2’ op1 = pop();
2.2.3’ result = calc(token, op1, op2);
2.4.4’ push(result);
3. return pop();
Postfix expressions:
Algorithm using stacks (cont.)
Infix transformation to Postfix
• Create an empty stack and an empty postfix output
string/stream
• Scan the infix input string/stream left to right
• If the current input token is an operand, simply
append it to the output string
• If the current input token is an operator, pop off all
operators that have equal or higher precedence and
append them to the output string; push the operator
onto the stack. The order of popping is the order in
the output.
• If the current input token is '(', push it onto
the stack
• If the current input token is ')', pop off all
operators and append them to the output
string until a '(' is popped; discard the '('.
• If the end of the input string is found, pop all
operators and append them to the output
string.
Precedence of operators
Example 1
University asked questions
• Explain the stepwise conversion using stack for the
given infix expression to the postfix expression:
A * (B + C) * D
Group-C
Assignment-2
• Implement C++ program for expression
conversion as infix to postfix and its evaluation
using stack based on given conditions
i. Operands and operator, both must be single
character.
ii. Input Postfix expression must be in a desired
format.
iii. Only '+', '-', '*' and '/ ' operators are expected.
class Stack {
private :
int top;
int ST[SIZE];
public :
Stack();
void push(int X);
int pop();
int peek();
int isEmpty();
int isFull();
char* infix_postfix(char[]);
int priority(char c);
void postfix_eval(char[]);
int cal(int,int,char);
};
Stack :: Stack()
{
top = -1; int Stack :: isFull()
for(int i=0;i<SIZE;i++) {
ST[i]=0; if(top == SIZE-1)
} return 1;
int Stack :: isEmpty() else
{
return 0;
if(top == -1)
return 1; }
else
return 0;
}
void Stack :: push(int X) {
if(!isFull()) {
top++;
ST[top]=X;
}
else
cout<<"\nStack Overflow !! Error!!";
}
int Stack :: pop() {
if(!isEmpty()) {
int X = 0;
X = ST[top];
top--;
return X;
}
else
cout<<"\nStack Underflow !! Error!!";
}
int Stack :: peek()
{
int X;
if(top==-1)
X=-1;
else
X = ST[top];
return X;
}
char* Stack::infix_postfix(char infix[SIZE])
{
char postfix[SIZE],c;
int j=0;
/*Scan the infix input string/stream left to right*/
for(int i=0;infix[i]!='\0';i++)
{
/* If the current input token is an operand, simply append it to the output
string*/
if(isalnum(infix[i]))
postfix[j++]=infix[i];
else
{
/* If the current input token is '(', push it onto the stack */
if(isEmpty()||infix[i]=='(')
{
push(infix[i]);

}
else if(infix[i]==')‘)
{
/* If the current input token is ')', pop off all operators and append them to the
output string until a '(' is popped; discard the '('. */
c=pop();
while(c!='(‘)
{
postfix[j++]=c;
c=pop();
}
}
/* If the current input token is an operator, pop off all operators that have equal or
higher precedence and append them to the output string; push the operator onto
the stack. */
else if(priority(peek()) < priority(infix[i]))
push(infix[i]);
else
{
while(!isEmpty() && priority(peek()) >= priority(infix[i]))
postfix[j++]=pop();
push(Str[i]);
}
}
}
/*If the end of the input string is found, pop all operators and append
them to the output string. */
while(!isEmpty())
postfix[j++]=pop();

postfix[j]='\0';
return postfix;
}
int Stack::priority( char c)
{
int i=-1;
if(c=='+'||c=='-')
i=1;
else if(c=='*'||c=='/')
i=2;
else if(c=='^')
i=3;
else if(c==')')
i=0;
return(i);
}
void Stack::postfix_eval(char postfix[15])
{
if(isalpha(postfix[0]))
cout<<"\nInvalid Expression!";
else
{
for(int i=0;postfix[i]!='\0';i++)
{
if(isdigit(postfix[i]))
push((postfix[i])-48);
else
{
int op2=pop();
int op1=pop();
int res=cal(postfix[i],op1,op2);
push(res);
}
}
cout<<pop();
}
}
int Stack::cal(char optr,int op1,int op2)
{
int res=0;
switch(optr)
{
case '+': res=op1+op2;
break;
case '-': res=op1-op2;
break;
case '*‘: res=op1*op2;
break;
case '/': res=op1/op2;
break;
}
return res;
}
Infix to Prefix Conversion
• Expression = (A+B^C)*D+E^5
Step 1. Reverse the infix expression.
5^E+D*)C^B+A(
Step 2. Make Every '(' as ')' and every ')' as '('
5^E+D*(C^B+A)
Step 3. Convert expression to postfix form.
Expression Stack Output
5^E+D*(C^B+A) Empty -
^E+D*(C^B+A) Empty 5
E+D*(C^B+A) ^ 5
+D*(C^B+A) ^ 5E
D*(C^B+A) + 5E^
*(C^B+A) + 5E^D
(C^B+A) +* 5E^D
C^B+A) +*( 5E^D
^B+A) +*( 5E^DC
B+A) +*(^ 5E^DC
+A) +*(^ 5E^DCB
A) +*(+ 5E^DCB^
) +*(+ 5E^DCB^A
End +* 5E^DCB^A+
End Empty 5E^DCB^A+*+
• Step 4. Reverse the expression.
+*+A^BCD^E5
Prefix to Postfix conversion

Algorithm for Prefix to Postfix:


• Read the Prefix expression in reverse order (from right
to left)
• If the symbol is an operand, then push it onto the Stack
• If the symbol is an operator, then pop two operands
from the Stack
Create a string by concatenating the two operands and
the operator after them.
string = operand1 + operand2 + operator
And push the resultant string back to Stack
• Repeat the above steps until end of Prefix expression.
University asked questions
• Convert the following prefix expression into postfix.
* + a – bc / - de + - fgh
Prefix to Infix conversion

Algorithm for Prefix to Infix:


•Read the Prefix expression in reverse order (from right
to left)
•If the symbol is an operand, then push it onto the Stack
•If the symbol is an operator, then pop two operands
from the Stack
•Create a string by concatenating the two operands and
the operator between them.
string = (operand1 + operator + operand2)
And push the resultant string back to Stack
•Repeat the above steps until end of Prefix expression.
Postfix to Prefix conversion
• Read the Postfix expression from left to right
• If the symbol is an operand, then push it onto the Stack
• If the symbol is an operator, then pop two operands
from the Stack
Create a string by concatenating the two operands and
the operator before them.
string = operator + operand1 + operand2
And push the resultant string back to Stack
• Repeat the above steps until end of Prefix expression.
Postfix to Infix Conversion
• Algorithm
1.While there are input symbol left
1.1 Read the next symbol from the input.
2.If the symbol is an operand
2.1 Push it onto the stack.
3.Otherwise,
3.1 the symbol is an operator.
3.2 Pop the top 2 values from the stack.
3.3 Put the operator, with the values as
arguments and form a string.
3.4 Push the resulted string back to stack.
4.If there is only one value in the stack
4.1 That value in the stack is the desired infix
Multiple Stacks
• Implement two stacks in an array
• Method 1 (Divide the space in two halves)
A simple way to implement two stacks is to divide
the array in two halves and assign the half half space
to two stacks,
i.e., use arr[0] to arr[n/2] for stack1, and arr[(n/2) +
1] to arr[n-1] for stack2 where arr[] is the array to be
used to implement two stacks and size of array be n.

0 Stack1 n/2 (n/2)+1 Stack2 (n-1)


Disadvantages

• The problem with this method is inefficient use of


array space.
• A stack push operation may result in stack overflow
even if there is space available in arr[]. For
example, say the k is 2 and array size (n) is 6 and
we push 3 elements to first and do not push
anything to second stack.
• When we push 4th element to first, there will be
overflow even if we have space for 3 more
elements in array.
• Method 2 (A space efficient implementation)

- This method efficiently utilizes the available space.


- It doesn’t cause an overflow if there is space
available in arr[].
- The idea is to start two stacks from two extreme
corners of arr[].
- stack1 starts from the leftmost element, the first
element in stack1 is pushed at index 0.
- The stack2 starts from the rightmost corner, the
first element in stack2 is pushed at index (n-1).
• Both stacks grow (or shrink) in opposite direction.
• To check for overflow, all we need to check is for
space between top elements of both stacks
Contents:
• Stacks- concept, Primitive operations, Stack Abstract
Data Type, Representation of Stacks Using Sequential
Organization, stack operations, Multiple Stacks,
Applications of Stack- Expression Evaluation and
Conversion, Polish notation and expression
conversion, Need for prefix and postfix expressions,
Postfix expression evaluation, Linked Stack and
Operations.
• Recursion- concept, variants of recursion- direct,
indirect, tail and tree, Backtracking algorithmic
strategy, use of stack in backtracking. Case Study- 4
Queens problem, Android- multiple tasks/multiple
activities and back stack.
Linked Stack and Operations
class Node class Stack
{ {
public: Node * top;
int data; public :
Node *next; Stack();
Node(int val) void push(int);
{ int pop();
data=val; int isEmpty();
next=NULL; };
}
};
Stack :: Stack()
{
top=NULL;
}
int Stack :: isEmpty()
{
if(top == NULL)
return 1;
else
return 0;
}
Void Stack :: push(int data)
{
Node *newnode=new Node(newnode);
if(top==NULL)
top=newnode;
else
{
newnode->next=top;
top=newnode;
}
}
int Stack :: pop()
{
Node *temp=NULL;
if(!isEmpty())
{
temp=top;
int val=temp->data;
top=top->next;
delete temp;
return val;
}
else
cout<<"\nStack Underflow !! Error!!";
}
Contents:
• Stacks- concept, Primitive operations, Stack Abstract
Data Type, Representation of Stacks Using Sequential
Organization, stack operations, Multiple Stacks,
Applications of Stack- Expression Evaluation and
Conversion, Polish notation and expression
conversion, Need for prefix and postfix expressions,
Postfix expression evaluation, Linked Stack and
Operations.
• Recursion- concept, variants of recursion- direct,
indirect, tail and tree, Backtracking algorithmic
strategy, use of stack in backtracking. Case Study- 4
Queens problem, Android- multiple tasks/multiple
activities and back stack.
Recursion
• Recursion is nothing but function calls itself.
• The factorial of an integer can be expressed using a
recursive definition. For example, 5 factorial (5!)
may be expressed as:
5! = 5 * 4 * 3 * 2 * 1
However, a more concise definition involving recursion
would be
5! = 5 * 4!
Now, in order to find the definition of 5! We must first
find the definition of 4!, then 3!, then 2! And finally 1!.
Cont..
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 (basis case or
stopping state)
• A more generic recursive factorial definition would be:
N! = N * (N-1)!
– This assumes that N >= 0 and that the factorial of 0
is 1 and the factorial of 1 is also 1 (a non-recursive
definition).
Types of recursion
• There are two types of recursion
– Direct recursion is when a function contains a call
to itself within its own body.
– Ex.factorial
unsigned int fact(unsigned int
n)
{
if (n == 0) return 1;

return n*fact(n-1);
}
Cont..
– Indirect recursion is when a function calls a second
function which in turn calls the first function.
void g( ) {
f ( ); // indirect recursive call
}
void f ( ) {
g ( );
}
void main ( ) {
f ( );
}
Tail recursion
• A recursive function is tail recursive when recursive
call is the last thing executed by the function. For
example the following C++ function print() is tail
recursive.
// An example of tail recursive function
void print(int n)
{
if (n < 0) return;
cout << " " << n;

// The last executed statement is recursive call


print(n-1);
}
• Why do we care?

- The tail recursive functions considered better than


non tail recursive functions as tail-recursion can be
optimized by compiler.
- The idea used by compilers to optimize tail-
recursive functions is simple, since the recursive call
is the last statement, there is nothing left to do in
the current function, so saving the current
function’s stack frame is of no use.
Tree Recursion
• A tree of recursive calls is generated. Example
of tree recursion is Fibonacci series.
int Fibonacci(int n)
{
if ( n == 0 )
return 0;
else if ( n == 1 )
return 1;
else
return ( Fibonacci(n-1) + Fibonacci(n-2) );
}
Backtracking
• Backtracking is a technique used to solve problems
with a large search space, by systematically trying and
eliminating possibilities.
• A standard example of backtracking would be going
through a maze.
– At some point in a maze, you might have two options of
which direction
on to go:
ncti
Ju

Portion A
Portion B
Backtracking
One strategy would be on
ncti
to try going through Ju
Portion B
Portion A of the maze.
 If you get stuck before
you find your way out,

Portion A
then you "backtrack" to
the junction.

At this point in time you


know that Portion A will
NOT lead you out of the
maze,
 so you then start
Backtracking
• Clearly, at a single junction
you could have even more
than 2 choices.

• The backtracking strategy


says to try each choice, one
after the other, on
cti
– if you ever get stuck,
Ju n
"backtrack" to the junction C
B
and try the next choice.
A

• If you try all choices and


never found a way out, then
there IS no solution to the
University asked questions
• What is stack? Write an ADT for stack.
• What is recursion? Explain use of stack for recursion.
• Explain the stepwise conversion using stack for the
given infix expression to the postfix expression:
A * (B + C) * D
• Write an algorithm for postfix evaluation with suitable
example.
• Convert the following prefix expression into postfix.
* + a – bc / - de + - fgh
Cont..
• Write an algorithm to convert infix expression to
postfix expression.
• Explain evaluation of postfix expression using stack
with suitable example.
• Explain the stepwise conversion using stack for the
given infix expression to the postfix expression:
A*B+C*D

You might also like