Welcome to   Click to listen highlighted text! Welcome to
QUEUE USING STACKQUEUE USING STACK

A queue is a data structure that follows the First In First Out (FIFO) principle, which means that the first element that is added to the queue will be the first one to be removed. A stack is a data structure that follows the Last In First Out (LIFO) principle, which means that the last element that is added to the stack will be the first one to be removed.

It is possible to implement a queue using a stack by using two stacks. One stack will be used to enqueue elements, and the other stack will be used to dequeue elements.

When an element is added to the queue, it is pushed onto the enqueue stack. When an element is removed from the queue, it is popped from the dequeue stack.

If the dequeue stack is empty, all elements are popped from the enqueue stack and pushed onto the dequeue stack before the element is popped. This allows the queue to maintain the correct order of the elements while using the LIFO structure of the stack to store and retrieve them.

Queue implementation using stack:

1.By making dequeue operation costly

It is possible to implement a queue using a stack by making the dequeue operation more costly than the enqueue operation. This can be done by using two stacks, one for enqueuing elements and one for dequeuing elements.

When an element is added to the queue, it is pushed onto the enqueue stack. When an element is removed from the queue, the dequeue stack is checked to see if it is empty. If the dequeue stack is empty, all elements are popped from the enqueue stack and pushed onto the dequeue stack before the element is popped.

This allows the queue to maintain the correct order of the elements while using the LIFO structure of the stack to store and retrieve them.

Making the dequeue operation more costly in this way has the advantage of reducing the time complexity of the enqueue operation to O(1) in the best case and O(1) in the worst case.

However, it increases the time complexity of the dequeue operation to O(n) in the best case and O(n) in the worst case, where n is the number of elements in the queue. This means that enqueuing elements is very fast, but dequeuing elements becomes slower as the queue grows larger.

The space complexity of this implementation is also O(n), where n is the number of elements in the queue, because both stacks must be able to hold all of the elements in the queue in order to maintain the correct order of the elements.

QUEUE USING STACK

Implementing queue using stack by making dequeue costly using dynamic array in C

#include<stdio.h>
 #include<conio.h>
 #include<stdlib.h>
 void main()
 {
 int *stack1,*stack2,x=0,top1=-1,top2=-1,i,count=0,size,value,
 choice;
     printf("enter size of arrayn");
     scanf("%d",&size);
     stack1= malloc(size*sizeof(int));
     stack1= malloc(size*sizeof(int));
 while(x<1)  
 {
         printf("n 1.ENQUEUE");
         printf("n 2.DEQUEUE");
         printf("n 3.DISPLAY");
         printf("n 4.EXIT ");
         printf("n ENTER YOUR CHOICE n");
         scanf(" %d",&choice);
         switch (choice)
         {
         case 1:
             if(top1==size-1)
             {
                 printf("overflown");
                 break;
                
             }
             else
             {
                 printf("enter the value");
                 scanf("%d",&value);
                 printf("nCurrent stack1 top1 value=%d",top1);
                 top1=top1+1;
                 printf("nstack1 top1 become=%d",top1);
                 stack1[top1]=value;
                 count=count+1;
                 printf("nValue enqueue successfully");
             }
             break;
         case 2:  
                 if(top1==-1)
                 {
                     printf("underflown");
                         break;
                 }
                 else
                 {
                     printf("stack1 current top1 value=%d n",top1);
                     printf("starting dequeuen");
                     for(i=0;i<count;i++)
                     {
                         top2=top2+1;
                         printf("copy top1=%d to stack2n",top1);
                         stack2[top2]=stack1[top1];
                         top1=top1-1;  
                     }
                     printf("stack 1 is copyied to stack 2 successfullyn");
                     stack2[top2--];
                     count=count-1;
                     printf("first item of stack1 or top item of stack2 is poped");
                     printf("nAgain copying stack 2 to stack 1");
                     printf("ncurrent value of stack1 top1 =%d n",top1);
                     for(i=0;i<count;i++)
                     {
                         top1=top1+1;
                         printf("nstack1 top1 value become=%d n",top1);
                         stack1[top1]=stack2[top2];
                         top2=top2-1;
                         printf("stack2 %d value is copyied to stack1",top2);
                        
                     }
                     printf("nstack2 copyied successfully to stack1");
                     printf("nstack2 top2 current value=%d",top2);
                     printf("nstack1 top1 value=%d n",top1);
                 }
             break;
         case 3:
         printf("Current queue valuen");
         if(top1==-1)
         {
             printf("empty queuen");
             break;
         }
         else
         printf("QUEUE=");
             for(i=0;i<=top1;i++)
             {
                 printf("[%d]",stack1[i]);
             }
         break;
         case 4:
         stack1=NULL;
         stack2=NULL;
         free(stack1);
         free(stack2);
         x=x+1;
         break;
    
         default:
         printf("invalid choice");

}

}

}


Here in output we have shown every case of enqueue and dequeue.

OUTPUT

enter size of array

3

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT 

 ENTER YOUR CHOICE 

3

Current queue value

empty queue        

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT 

 ENTER YOUR CHOICE 

1

enter the value5

Current stack1 top1 value=-1

stack1 top1 become=0        

Value enqueue successfully  

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT 

 ENTER YOUR CHOICE 

3

Current queue value

QUEUE=[5]

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT 

 ENTER YOUR CHOICE

1

enter the value6

Current stack1 top1 value=0

stack1 top1 become=1

Value enqueue successfully

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

1

enter the value7

Current stack1 top1 value=1

stack1 top1 become=2

Value enqueue successfully

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

3

Current queue value

QUEUE=[5][6][7]

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

1

overflow

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

2

stack1 current top1 value=2 

starting dequeue

copy top1=2 to stack2

copy top1=1 to stack2

copy top1=0 to stack2

stack 1 is copyied to stack 2 successfully

first item of stack1 or top item of stack2 is poped

Again copying stack 2 to stack 1

current value of stack1 top1 =-1

stack1 top1 value become=0

stack2 0 value is copyied to stack1

stack1 top1 value become=1

stack2 -1 value is copyied to stack1

stack2 copyied successfully to stack1

stack2 top2 current value=-1

stack1 top1 value=1

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

3

Current queue value

QUEUE=[6][7]

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

2

stack1 current top1 value=1 

starting dequeue

copy top1=1 to stack2

copy top1=0 to stack2

stack 1 is copyied to stack 2 successfully

first item of stack1 or top item of stack2 is poped

Again copying stack 2 to stack 1

current value of stack1 top1 =-1

stack1 top1 value become=0

stack2 -1 value is copyied to stack1

stack2 copyied successfully to stack1

stack2 top2 current value=-1

stack1 top1 value=0

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

2

stack1 current top1 value=0 

starting dequeue

copy top1=0 to stack2

stack 1 is copyied to stack 2 successfully

first item of stack1 or top item of stack2 is poped

Again copying stack 2 to stack 1

current value of stack1 top1 =-1

stack2 copyied successfully to stack1

stack2 top2 current value=-1

stack1 top1 value=-1

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

2

underflow

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

3

Current queue value

empty queue

 1.ENQUEUE

 2.DEQUEUE

 3.DISPLAY

 4.EXIT

 ENTER YOUR CHOICE

4

This program is implemented by making dequeue operation costly.So this program complexity is:-

Time Complexity:

1)Enqueue =O(1)

2)Dequeue =O(n)

2. By making enqueue costly

It is possible to implement a queue using a stack in such a way that enqueuing elements is more expensive than dequeuing elements. This can be achieved by using only one stack and enqueuing elements at the bottom of the stack rather than at the top.

When an element is added to the queue, it is pushed onto the stack. However, in order to maintain the correct order of the elements in the queue, the element must be pushed to the bottom of the stack.

To do this, all of the elements in the stack must be popped and pushed back onto the stack in the reverse order, with the new element being pushed onto the bottom of the stack.

This ensures that the element is added to the correct position in the queue, but it also increases the time complexity of enqueuing an element to O(n) in the worst case, where n is the number of elements in the queue.

Dequeuing elements from the queue is still done in O(1) time by simply popping the top element from the stack. However, because enqueuing elements is more expensive, this implementation of a queue using a stack is only efficient if the number of dequeues is much greater than the number of enqueues.

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

#define MAX_SIZE 100

// Stack data structure
typedef struct stack
{
    int top;
    int data[MAX_SIZE];
} stack;

// Queue data structure
typedef struct queue
{
    stack enqueue_stack;
    stack dequeue_stack;
} queue;

// Push element onto stack
void push(stack *s, int element)
{
    if (s->top == MAX_SIZE - 1)
    {
        printf("Error: Stack is full.\n");
        return;
    }

    s->data[++s->top] = element;
}

// Pop element from stack
int pop(stack *s)
{
    if (s->top == -1)
    {
        printf("Error: Stack is empty.\n");
        return -1;
    }

    return s->data[s->top--];
}

// Enqueue element onto queue
void enqueue(queue *q, int element)
{
    // Push all elements from enqueue stack to dequeue stack
    while (q->enqueue_stack.top != -1)
    {
        int e = pop(&q->enqueue_stack);
        push(&q->dequeue_stack, e);
    }

    // Push element onto enqueue stack
    push(&q->enqueue_stack, element);
}

// Dequeue element from queue
int dequeue(queue *q)
{
    // If dequeue stack is empty, pop all elements from enqueue stack and push to dequeue stack
    if (q->dequeue_stack.top == -1)
    {
        while (q->enqueue_stack.top != -1)
        {
            int e = pop(&q->enqueue_stack);
            push(&q->dequeue_stack, e);
        }
    }

    // Pop element from dequeue stack
    return pop(&q->dequeue_stack);
}

// Initialize queue
void init_queue(queue *q)
{
    q->enqueue_stack.top = -1;
    q->dequeue_stack.top = -1;
}

int main()
{
    queue q;
    init_queue(&q);

    // Enqueue elements onto queue
    enqueue(&q, 1);
    enqueue(&q, 2);
    enqueue(&q, 3);

    // Dequeue elements from queue
    printf("%d\n", dequeue(&q)); // 1
    printf("%d\n", dequeue(&q)); // 2
    printf("%d\n", dequeue(&q)); // 3

    return 0;
}

Time complexity

The time complexity of enqueuing and dequeuing elements in a queue implemented using a stack is O(1) in the best case and O(n) in the worst case, where n is the number of elements in the queue.

The best-case time complexity occurs when the dequeue stack is not empty, and the element can be popped from the stack in O(1) time.

The worst-case time complexity occurs when the dequeue stack is empty and all elements must be popped from the enqueue stack and pushed onto the dequeue stack before the element can be popped, which takes O(n) time.

Space complexity

The space complexity of a queue implemented using a stack is O(n), where n is the number of elements in the queue. This is because both the enqueue and dequeue stacks must be able to hold all of the elements in the queue in order to maintain the correct order of the elements.

In the worst case, when the queue is full, both stacks will have n elements, resulting in a space complexity of O(n).

For more competative programming check our other post too

Click to listen highlighted text!