A similar question was asked earlier there, but the question here is the reverse of it, using two queues as a stack. The question...
Given two queues with their sta
As has been mentioned, wouldn't a single queue do the trick? It's probably less practical but is a bit slicker.
push(x):
enqueue(x)
for(queueSize - 1)
enqueue(dequeue())
pop(x):
dequeue()
Here's my solution..
Concept_Behind::
push(struct Stack* S,int data)
::This function enqueue first element in Q1 and rest in Q2
pop(struct Stack* S)
::if Q2 is not empty the transfers all elem's into Q1 and return the last elem in Q2
else(which means Q2 is empty ) transfers all elem's into Q2 and returns the last elem in Q1
Efficiency_Behind::
push(struct Stack*S,int data)
::O(1)//since single enqueue per data
pop(struct Stack* S)
::O(n)//since tranfers worst n-1 data per pop.
#include<stdio.h>
#include<stdlib.h>
struct Queue{
int front;
int rear;
int *arr;
int size;
};
struct Stack {
struct Queue *Q1;
struct Queue *Q2;
};
struct Queue* Qconstructor(int capacity)
{
struct Queue *Q=malloc(sizeof(struct Queue));
Q->front=Q->rear=-1;
Q->size=capacity;
Q->arr=malloc(Q->size*sizeof(int));
return Q;
}
int isEmptyQueue(struct Queue *Q)
{
return (Q->front==-1);
}
int isFullQueue(struct Queue *Q)
{
return ((Q->rear+1) % Q->size ==Q->front);
}
void enqueue(struct Queue *Q,int data)
{
if(isFullQueue(Q))
{
printf("Queue overflow\n");
return;}
Q->rear=Q->rear+1 % Q->size;
Q->arr[Q->rear]=data;
if(Q->front==-1)
Q->front=Q->rear;
}
int dequeue(struct Queue *Q)
{
if(isEmptyQueue(Q)){
printf("Queue underflow\n");
return;
}
int data=Q->arr[Q->front];
if(Q->front==Q->rear)
Q->front=-1;
else
Q->front=Q->front+1 % Q->size;
return data;
}
///////////////////////*************main algo****************////////////////////////
struct Stack* Sconstructor(int capacity)
{
struct Stack *S=malloc(sizeof(struct Stack));
S->Q1=Qconstructor(capacity);
S->Q2=Qconstructor(capacity);
return S;
}
void push(struct Stack *S,int data)
{
if(isEmptyQueue(S->Q1))
enqueue(S->Q1,data);
else
enqueue(S->Q2,data);
}
int pop(struct Stack *S)
{
int i,tmp;
if(!isEmptyQueue(S->Q2)){
for(i=S->Q2->front;i<=S->Q2->rear;i++){
tmp=dequeue(S->Q2);
if(isEmptyQueue(S->Q2))
return tmp;
else
enqueue(S->Q1,tmp);
}
}
else{
for(i=S->Q1->front;i<=S->Q1->rear;i++){
tmp=dequeue(S->Q1);
if(isEmptyQueue(S->Q1))
return tmp;
else
enqueue(S->Q2,tmp);
}
}
}
////////////////*************end of main algo my algo************
///////////////*************push() O(1);;;;pop() O(n);;;;*******/////
main()
{
int size;
printf("Enter the number of elements in the Stack(made of 2 queue's)::\n");
scanf("%d",&size);
struct Stack *S=Sconstructor(size);
push(S,1);
push(S,2);
push(S,3);
push(S,4);
printf("%d\n",pop(S));
push(S,5);
printf("%d\n",pop(S));
printf("%d\n",pop(S));
printf("%d\n",pop(S));
printf("%d\n",pop(S));
}
Version A (efficient push):
Version B (efficient pop):
Python Code Using Only One Queue
class Queue(object):
def __init__(self):
self.items=[]
def enqueue(self,item):
self.items.insert(0,item)
def dequeue(self):
if(not self.isEmpty()):
return self.items.pop()
def isEmpty(self):
return self.items==[]
def size(self):
return len(self.items)
class stack(object):
def __init__(self):
self.q1= Queue()
def push(self, item):
self.q1.enqueue(item)
def pop(self):
c=self.q1.size()
while(c>1):
self.q1.enqueue(self.q1.dequeue())
c-=1
return self.q1.dequeue()
def size(self):
return self.q1.size()
def isempty(self):
if self.size > 0:
return True
else:
return False
The easiest (and maybe only) way of doing this is by pushing new elements into the empty queue, and then dequeuing the other and enqeuing into the previously empty queue. With this way the latest is always at the front of the queue. This would be version B, for version A you just reverse the process by dequeuing the elements into the second queue except for the last one.
Step 0:
"Stack"
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
Queue A Queue B
+---+---+---+---+---+ +---+---+---+---+---+
| | | | | | | | | | | |
+---+---+---+---+---+ +---+---+---+---+---+
Step 1:
"Stack"
+---+---+---+---+---+
| 1 | | | | |
+---+---+---+---+---+
Queue A Queue B
+---+---+---+---+---+ +---+---+---+---+---+
| 1 | | | | | | | | | | |
+---+---+---+---+---+ +---+---+---+---+---+
Step 2:
"Stack"
+---+---+---+---+---+
| 2 | 1 | | | |
+---+---+---+---+---+
Queue A Queue B
+---+---+---+---+---+ +---+---+---+---+---+
| | | | | | | 2 | 1 | | | |
+---+---+---+---+---+ +---+---+---+---+---+
Step 3:
"Stack"
+---+---+---+---+---+
| 3 | 2 | 1 | | |
+---+---+---+---+---+
Queue A Queue B
+---+---+---+---+---+ +---+---+---+---+---+
| 3 | 2 | 1 | | | | | | | | |
+---+---+---+---+---+ +---+---+---+---+---+
We can do this with one queue:
push:
n
is the number of elements in the queue, then remove and insert element n-1
times.pop:
.
push 1
front
+----+----+----+----+----+----+
| 1 | | | | | | insert 1
+----+----+----+----+----+----+
push2
front
+----+----+----+----+----+----+
| 1 | 2 | | | | | insert 2
+----+----+----+----+----+----+
front
+----+----+----+----+----+----+
| | 2 | 1 | | | | remove and insert 1
+----+----+----+----+----+----+
insert 3
front
+----+----+----+----+----+----+
| | 2 | 1 | 3 | | | insert 3
+----+----+----+----+----+----+
front
+----+----+----+----+----+----+
| | | 1 | 3 | 2 | | remove and insert 2
+----+----+----+----+----+----+
front
+----+----+----+----+----+----+
| | | | 3 | 2 | 1 | remove and insert 1
+----+----+----+----+----+----+
Sample implementation:
int stack_pop (queue_data *q)
{
return queue_remove (q);
}
void stack_push (queue_data *q, int val)
{
int old_count = queue_get_element_count (q), i;
queue_insert (q, val);
for (i=0; i<old_count; i++)
{
queue_insert (q, queue_remove (q));
}
}