DS Module 3 Notes
DS Module 3 Notes
Introduction of stacks
A stack is linear data structure and it is an ordered collection of items where the addition of new
items and the removal of existing items always take place at the same end. This end is commonly
referred to as the “top” of the stack.
The last item to be inserted into a stack is the first one to be deleted from it. For example, you
have a stack of trays on a table.
Stack Representation
Basic Operations
Push Operation
The process of putting a new data element onto stack is known as a Push Operation. Push
operation involves a series of steps −
Step 1 − Checks if the stack is full.
Step 2 − If the stack is full, produces an error and exit.
Step 3 − If the stack is not full, increments top to point next empty space.
Step 4 − Adds data element to the stack location, where top is pointing.
A Pop operation may involve the following steps −
• Step 1 − Checks if the stack is empty.
• Step 2 − If the stack is empty, produces an error and exit.
• Step 3 − If the stack is not empty, accesses the data element at which top is pointing.
• Step 4 − Decrease the value of top by 1.
Adding an element into the top of the stack is referred to as push operation.
Push operation involves following two steps.
1. Increment the variable Top so that it can now refer to the next memory location.
2. Add element at the position of incremented top. This is referred to as adding new element at the
top of the stack.
Stack is overflown when we try to insert an element into a completely filled stack therefore,
our main function must always avoid stack overflow condition.
Deletion of an element from the top of the stack is called pop operation. The value of the variable
top will be decremented by 1 whenever an item is deleted from the stack. The top most element of
the stack is stored in another variable and then the top is decremented by 1. The operation returns
the deleted value that was stored in another variable as the result.
The underflow condition occurs when we try to delete an element from an already empty stack.
Display of all the elements of a stack if elements are present. Otherwise, Check for emptiness of
the stack then display the message accordingly
Peek operation involves returning the element, which is present at the top of the stack without
deleting it. Underflow condition can occur if we try to return the top element in an already empty
stack.
printf("\n \n");
while(choice != 4)
{
printf("Chose one from the below options...\n"); printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n Enter your choice \n"); scanf("%d",&choice);
switch(choice)
{
case 1:
{
push(); break;
}
case 2:
{
pop(); break;
}
case 3:
{
show(); break;
}
case 4:
{
printf("Exiting. ........................... ");
break;
}
default:
{
printf("Please Enter valid choice ");
}
}
}
}
void push ()
{
int val;
if (top == n-1 ) printf("\n Overflow"); else
{
printf("Enter the value?"); scanf("%d",&val);
top = top +1; stack[top] = val;
}
}
void pop ()
{
if(top == -1) printf("Underflow"); else
top = top -1;
}
void show()
{
for (i=top;i>=0;i--)
{
printf("%d\n",stack[i]);
}
if(top == -1)
{
printf("Stack is empty");
}
}
Operations on Stack using Linked List
Adding a node to the stack (Push operation)
Adding a node to the stack is referred to as push operation. Pushing an element to a stack in linked
list implementation is different from that of an array implementation. In order to push an element
onto the stack, the following steps are involved.
1. Create a node first and allocate memory to it.
2. If the list is empty then the item is to be pushed as the start node of the list. This includes assigning
value to the data part of the node and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the new element in the beginning
of the list (to not violate the property of the stack). For this purpose, assign the address of the
starting element to the address field of the new node and make the new node, the starting node of
the list.
Deleting a node from the top of stack is referred to as pop operation. Deleting a node from the
linked list implementation of stack is different from that in the array implementation. In order to
pop an element from the stack, we need to follow the following steps:
1. Check for the underflow condition: The underflow condition occurs when we try to pop from
an already empty stack. The stack will be empty if the head pointer of the list points to null.
2. Adjust the head pointer accordingly: In stack, the elements are popped only from one end,
therefore, the value stored in the head pointer must be deleted and the node must be freed. The
next node of the head node now becomes the head node.
void main ()
{
int choice=0;
printf("\n*********Stack operations using linked list*********\n"); printf("\n
\n");
while(choice != 4)
{
printf("\n\nChose one from the below options...\n");
printf("\n1.Push\n2.Pop\n3.Show\n4.Exit"); printf("\n Enter your choice \n");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
push(); break;
}
case 2:
{
pop(); break;
}
case 3:
{
display(); break;
}
case 4:
{
printf("Exiting. .......................... ");
break;
}
default:
{
printf("Please Enter valid choice ");
}
}
}
}
void push ()
{
int val;
struct node *ptr = (struct node*)malloc(sizeof(struct node)); if(ptr == NULL)
{
printf("not able to push the element");
}
else
{
printf("Enter the value"); scanf("%d",&val); if(head==NULL)
{
ptr->val = val;
ptr -> next = NULL; head=ptr;
}
else
{
ptr->val = val; ptr->next = head; head=ptr;
}
printf("Item pushed");
}
}
void pop()
{
int item;
struct node *ptr;
if (head == NULL)
{
printf("Underflow");
}
else
{
item = head->val; ptr = head;
head = head->next; free(ptr);
printf("Item popped");
}
}
void display()
{
int i;
Applications of Stacks
✓ Backtracking
✓ Delimiter Checking or Parenthesis checking
✓ Reverse a Data
✓ Processing Function Calls
In addition to operands and operators, the arithmetic expression may also include
parenthesis like "left parenthesis" and "right parenthesis".
Example: A + (B - C)
To evaluate the expressions, one needs to be aware of the standard precedence rules for arithmetic
expression. The precedence rules for the five basic arithmetic operators are:
o Infix Notation
o Prefix Notation
o Postfix Notation
Infix Notation
The infix notation is a convenient way of writing an expression in which each operator is placed
between the operands. Infix expressions can be parenthesized or unparenthesized depending upon
the problem requirement.
Example: A + B, (C - D) etc.
All these expressions are in infix notation because the operator comes between the operands.
Prefix Notation
The prefix notation places the operator before the operands. This notation was introduced
by the Polish mathematician and hence often referred to as polish notation.
All these expressions are in prefix notation because the operator comes before the operands.
Postfix Notation
The postfix notation places the operator after the operands. This notation is just the reverse of
Polish notation and also known as Reverse Polish notation.
All these expressions are in postfix notation because the operator comes after the operands.
Algorithm or procedure
(note: Place the expression in ( ) if not given)
Step 1 : Scan the Infix Expression from left to right.
Step 2 : If the scanned character is an operand, append it with final Infix to Postfix string.
Step 3 : Else,
Step 3.1 : If the precedence order of the scanned(incoming) operator is greater than the
precedence order of the operator in the stack (or the stack is empty or the stack contains a ‘(‘ or
‘[‘ or ‘{‘), push it on stack.
Step 3.2 : Else, Pop all the operators from the stack which are greater than or equal to in
precedence than that of the scanned operator. After doing that Push the scanned operator to the
stack. (If you encounter parenthesis while popping then stop there and push the scanned operator
in the stack.)
Step 4 : If the scanned character is an ‘(‘ or ‘[‘ or ‘{‘, push it to the stack.
Step 5 : If the scanned character is an ‘)’or ‘]’ or ‘}’, pop the stack and and output it until a ‘(‘ or
‘[‘ or ‘{‘ respectively is encountered, and discard both the parenthesis.
Step 6 : Repeat steps 2-6 until infix expression is scanned.
Step 7 : Print the output
Step 8 : Pop and output from the stack until it is not empty.
Examples: Convert The Following Infix Expressions To Postfix
1. (A+B/C+D*(E-F)^G)
2. (X-Y/(Z+U)*V)
3. (A+B*C/D-F+A*E)
4. (A+B)+C-D*E
5. (K+L-M*N+(O^P)*W/U/V*T+Q)
Program
#include<stdio.h> #include<ctype.h>
void push(char x)
{
stack[++top] = x;
}
char pop()
{
if(top == -1)
return -1; else
return stack[top--];
}
int priority(char x)
{
if(x == '(') return 0;
if(x == '+' || x == '-') return 1;
if(x == '*' || x == '/') return 2;
if(x=='^') return 3;
return 0;
}
int main()
{
char exp[100]; char *e, x;
printf("Enter the expression : "); scanf("%s",exp);
printf("\n"); e = exp;
while(*e != '\0')
{
if(isalnum(*e)) printf("%c ",*e);
else if(*e == '(') push(*e);
else if(*e == ')')
{
while((x = pop()) != '(') printf("%c ", x);
}
else
{
while(priority(stack[top]) >= priority(*e)) printf("%c ",pop());
push(*e);
}
e++;
}
while(top != -1)
{
printf("%c ",pop());
}
return 0;
}
Application-2: Evaluating Postfix expression:
Stack is the ideal data structure to evaluate the postfix expression because the top element is always
the most recent operand. The next element on the Stack is the second most recent operand to be
operated on.
Before evaluating the postfix expression, the following conditions must be checked. If any one of
the conditions fails, the postfix expression is invalid.
• When an operator encounters the scanning process, the Stack must contain a pair of operands
or intermediate results previously calculated.
• When an expression has been completely evaluated, the Stack must contain exactly one
value.
Procedure for evaluating postfix expression
Begin
For each character in postfix expression do
If operand is encountered, push it onto the stack
Elseif operator is encountered, pop 2 elements
A -> top element
B-> next to top element
Result= B operator A
Push result onto stack
Return element from top of the stack
end
Example: