Saturday, December 17, 2011

Stack with 2 Queues and Queue with 2 Stacks

Stack using 2 Queues.

http://www.geeksforgeeks.org/implement-stack-using-queue/
Strategy:
Version A:
  • push:
    • enqueue in queue1
  • pop:
    • while size of queue1 is bigger than 1, pipe dequeued items from queue1 into queue2
    • dequeue and return the last item of queue1, then switch the names of queue1 and queue2
Version B:
  • push:
    • enqueue in queue2
    • enqueue all items of queue1 in queue2, then switch the names of queue1 and queue2
  • pop:
    • deqeue from queue1
Queue using 2 STACKS.

Strategy:
A queue can be implemented using two stacks. Let queue to be implemented be q and stacks used to implement q be stack1 and stack2. q can be implemented in two ways:

Method 1 (By making enQueue operation costly)
This method makes sure that newly entered element is always at the top of stack 1, so that deQueue operation just pops from stack1. To put the element at top of stack1, stack2 is used.
enQueue(q, x)
  1) While stack1 is not empty, push everything from satck1 to stack2.
  2) Push x to stack1 (assuming size of stacks is unlimited).
  3) Push everything back to stack1.

dnQueue(q)
  1) If stack1 is empty then error
  2) Pop an item from stack1 and return it
 
Method 2 (By making deQueue operation costly)
In this method, in en-queue operation, the new element is entered at the top of stack1. In de-queue operation, if stack2 is empty then all the elements are moved to stack2 and finally top of stack2 is returned.
enQueue(q,  x)
  1) Push x to stack1 (assuming size of stacks is unlimited).

deQueue(q)
  1) If both stacks are empty then error.
  2) If stack2 is empty
       While stack1 is not empty, push everything from satck1 to stack2.
  3) Pop the element from stack2 and return it.
Method 2 is definitely better than method 1. Method 1 moves all the elements twice in enQueue operation, while method 2 (in deQueue operation) moves the elements once and moves elements only if stack2 empty.

Code:Using Method 2
 #include<stdio.h>
#include<stdlib.h>

struct sNode
{
   int data;
   struct sNode *next;
};

struct queue
{
   struct sNode *stack1;
   struct sNode *stack2;
};

void push(struct sNode** top_ref, int new_data)
{
  struct sNode* new_node =
            (struct sNode*) malloc(sizeof(struct sNode));

  if(new_node == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }        

  new_node->data  = new_data;

  new_node->next = (*top_ref);

  (*top_ref)    = new_node;
}

int pop(struct sNode** top_ref)
{
  int res;
  struct sNode *top;

  if(*top_ref == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }
  else
  {
     top = *top_ref;
     res = top->data;
     *top_ref = top->next;
     free(top);
     return res;
  }
}

void enQueue(struct queue *q, int x)
{
   push(&q->stack1, x);
}

int deQueue(struct queue *q)
{
   int x;

   /* If both stacks are empty then error */
   if(q->stack1 == NULL && q->stack2 == NULL)
   {
      printf("Q is empty");
      getchar();
      exit(0);
   }

   /* Move elements from stack1 to stack 2 only if
       stack2 is empty */
   if(q->stack2 == NULL)
   {
     while(q->stack1 != NULL)
     {
        x = pop(&q->stack1);
        push(&q->stack2, x);
     }
   }

   x = pop(&q->stack2);
   return x;
}

int main()
{
   struct queue *q = (struct queue*)malloc(sizeof(struct queue));
   q->stack1 = NULL;
   q->stack2 = NULL;
   enQueue(q, 1);
   enQueue(q, 2);
   enQueue(q, 3);

   printf("%d  ", deQueue(q));
   printf("%d  ", deQueue(q));
   printf("%d  ", deQueue(q));

   getchar();
   return 0;
}

Queue using a single stack

Strategy:
Queue can be implemented using one user stack and one Function Call Stack.i.e using recursion


enQueue(x)
  1) Push x to stack1.

deQueue:
  1) If stack1 is empty then error.
  2) If stack1 has only one element then return it.
  3) Recursively pop everything from the stack1, store the popped item
    in a variable res,  push the res back to stack1 and return res
The step 3 makes sure that the last popped item is always returned and since the recursion stops when there is only one item in stack1 (step 2), we get the last element of stack1 in dequeue() and all other items are pushed back in step 3.

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

struct sNode
{
   int data;
   struct sNode *next;
};

struct queue
{
  struct sNode *stack1;
};

void push(struct sNode** top_ref, int new_data)
{
  struct sNode* new_node =
            (struct sNode*) malloc(sizeof(struct sNode));

  if(new_node == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }        

  new_node->data  = new_data;

  new_node->next = (*top_ref);

  (*top_ref)    = new_node;
}

int pop(struct sNode** top_ref)
{
  int res;
  struct sNode *top;

  if(*top_ref == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }
  else
  {
     top = *top_ref;
     res = top->data;
     *top_ref = top->next;
     free(top);
     return res;
  }
}

void enQueue(struct queue *q, int x)
{
  push(&q->stack1, x);
}

int deQueue(struct queue *q)
{
   int x, res;

   /* If both stacks are empty then error */
   if(q->stack1 == NULL)
   {
     printf("Q is empty");
     getchar();
     exit(0);
   }
   else if(q->stack1->next == NULL)
   {
      return pop(&q->stack1);
   }
   else
   {

      x = pop(&q->stack1);

      res = deQueue(q);

      push(&q->stack1, x);

      return res;
   }
}

int main()
{
  struct queue *q = (struct queue*)malloc(sizeof(struct queue));
  q->stack1 = NULL;

  enQueue(q, 1);
  enQueue(q, 2);
  enQueue(q, 3); 

  printf("%d  ", deQueue(q));
  printf("%d  ", deQueue(q));
  printf("%d  ", deQueue(q));

  getchar();
}

Two stacks in a single array

Create a data structure twoStacks that represents two stacks. Implementation of twoStacks should use only one array, i.e., both stacks should use the same array for storing elements. Following functions must be supported by twoStacks.

push1(int x) –> pushes x to first stack
push2(int x) –> pushes x to second stack

pop1() –> pops an element from first stack and return the popped element
pop2() –> pops an element from second stack and return the popped element

Implementation of twoStack should be space efficient.

http://www.geeksforgeeks.org/implement-two-stacks-in-an-array/

No comments:

Post a Comment