Data Structures-Stacks

Stack

A stack is a linear data structure in which follows a particular order in which the operations are performed. The insertion and deletion of elements are performed in Last in First out (LIFO) order or First in Last out (FILO) order. We can say that the insertion and deletion can be done at one end only.

                                                              

There are many real-life examples of a stack. For example, the plates are stacked over another in the canteen. The plate which is at the top is the first one to be removed which means the plate which is at the bottom most position remains in the stack for the longest period of time.

 

Basic Operations of Stack

The following are the basic operations performed in the stack:

Push: Adds an item to the stack. If the stack is full, then it is said to be an Overflow condition.

Pop: Removes an item from the stack. The items are popped in the reverse order in which they are pushed. If the stack is empty, then it is said to be an Underflow condition.

Top: Returns top element of stack.

 isEmpty: Return true if stack is empty, else false.

The following are the various operations of Stack:

  • Initialize the stack to be empty
  • Determine whether the stack is empty or not
  • Check whether the stack is full or not
  • If the stack is not full, add or insert a new node at the top of the stack. This operation is termed as Push operation.
  • If the stack is not empty, then retrieve the node at its top
  • If the stack is not empty, then we could delete the node at the top. This operation is termed as Pop operation.

Time Complexity of operations on Stack

The push(), pop(), isEmpty and top() methods have time complexity of O(1). As we do not run any loop on any of these operations, the time complexity is O(1).

Stack Implementation

The stack can be implemented in following two ways namely, 

  • Using array
  • Using linked list

Implementation of Stack using Array

The stack can be represented in memory with the use of Arrays. To perform this stack operation, we need to maintain a linear array Stack, a pointer variable top which contains the top element.

Example

The following is the C implementation of stack using Array:

#include <stdio.h>
#include<stdlib.h>

int top = -1;
int stk[5];

void push(int x)
{
    if(top > 4)
    {
        printf("Stack overflow");
        return;
    }

    stk[++top] = x;
    printf("Inserted the value %d\n", x);
}

void pop()
{
    if(top < 0)
    {
        printf("Stack underflow");
        return;
    }
    printf("The deleted element is %d\n", stk[top--]);
}

void display()
{
    if (top < 0)
    {
        printf("Stack is empty\n");
        return;
    }
    for (int i = top; i >= 0; i--)
    {
        printf("%d\t", stk[i]);
    }
}


int main()
{
    int ch;
    int val;
    while (1) {
        printf("\n1.push 2.pop 3.display 4.exit\nEnter ur choice: ");
        scanf("%d", &ch);
        switch (ch) {
        case 1:
            printf("Enter the element: ");
            scanf("%d", &val);
            push(val);
            break;
        case 2:
            pop();
            break;
        case 3:
            display();
            break;
        case 4:
            exit(0);
        }
    }
}

Output

1.push 2.pop 3.display 4.exit
Enter ur choice: 1
Enter the element: 5
Inserted the value 5

1.push 2.pop 3.display 4.exit
Enter ur choice: 1
Enter the element: 10
Inserted the value 10

1.push 2.pop 3.display 4.exit
Enter ur choice: 1
Enter the element: 15
Inserted the value 15

1.push 2.pop 3.display 4.exit
Enter ur choice: 2
The deleted element is 15

1.push 2.pop 3.display 4.exit
Enter ur choice: 3
10      5
1.push 2.pop 3.display 4.exit

Pros – Easy to implement. Memory is saved as pointers are not involved.

Cons – It is not dynamic. It doesn’t grow and shrink depending on needs at runtime.

 

Implementation of Stack using Linked List

The Stack can be implemented using Linked List which can grow and shrink according to the needs at runtime.

Example

The following is the C implementation of Stack using Linked list:

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *link;
}*top;

void push(int x)
{
    struct node *temp;
    temp=(struct node *)malloc(sizeof(struct node));
    temp->data=x;
    temp->link=top;
    top=temp;
}

void pop()
{
    struct node *temp;
    if(top==NULL)
    {
        printf("Stack is empty");
        return;
    }
    temp=top;
    top=top->link;
    free(temp);
}

void print()
{
    struct node *temp=top;
    while(temp!=NULL)
    {
        printf("%d\t",temp->data);
        temp=temp->link;
    }
    printf("\n");
}

void main()
{
    push(2);
    push(3);
    push(6);
    print();
    printf("Pop the top element\n");
    pop();
    printf("Push 10 to the stack\n");
    push(10);
    print();
}

Output

6       3       2
Pop the top element
Push 10 to the stack
10      3       2

Pros – The linked list implementation of Stack can grow and shrink according to the needs at the runtime.

Cons – Requires extra memory due to involvement of pointers.

 

Applications of Stack

The following are the various applications of Stack data structure:

Expression Evaluation – Stack is used to evaluate prefix, postfix and infix expressions.

Expression Conversion – An expression can be represented in prefix, postfix and infix notation. Stack can be used to convert one form of expression to another.

Syntax parsing – Many compilers use stack data structure for parsing the syntax of expressions, program blocks, etc.

Parenthesis checking – Stack is used to check the proper opening and closing of parenthesis.

Backtracking – The stack is used to backtrack the steps while solving some problem. For example, suppose we are finding the solution for Maze problem. We choose a path and after following it we may realize it is wrong. Now we can go back to the beginning of the path and to start with the new path. This can be achieved easily using Stack.

String Reversal – Stack is used to reverse a string. We push the characters of string one by one and finally pop characters from the stack.

Function call – Stack is used to keep track of information about the active functions and subroutines.