两个队列实现栈:




(一)前提:


//前提已知

typedef struct queue

{

int queuesize;

int head, tail;

int *q;

}Queue;



void InitQueue(Queue *q);

void EnQueue(Queue *q, int key);

int DeQueue(Queue *q);

int SizeOfQueue(Queue *q);

int IsQueueEmpty(Queue *q);

int IsQueueFull(Queue *q);




(二)方法一:




(1)图解:


两个队列实现栈_入栈



(2)解析:


q1是专职进出栈的,q2只是个中转站,(q2不存储数据)。


1)入栈时:直接入队列q1即可


2)出栈时:把q1的除最后一个元素外全部转移到队q2中,然后把刚才剩下q1中的那个元素出队列。之后把q2中的全部元素转移回q1中。




(3)代码实现:


void Push(Queue *q1, Queue *q2, int k)

{

EnQueue(q1, k);

}



int Pop(Queue *q1, Queue *q2)

{

int tmp;

if(IsQueueEmpty(q1) == 1)//队列1为空。

{

printf("Stack Empty!\n");

}

else

{

while(SizeOfQueue(q1) != 1)

{

EnQueue(q2, DeQueue(q1));

}

tmp = DeQueue(q1);//出栈

while(IsQueueEmpty(q2) == 0)

{

EnQueue(q1, DeQueue(q2));

}

return tmp;

}

}


(4)问题:


出栈时最后仍然需要将q2中的数据压入到q1中。




(三)改进:




(1)解析:


定义两个指针:pushtmp:所指专门进栈的队列; tmp:指向临时作为中转站的另一个栈。


1)入栈时:直接入pushtmp所指队列即可


2)出栈时:把pushtmp的除最后一个元素外全部转移到队列tmp中,然后把刚才剩下q1中的那个元素出队列。然后更新pushtmp,tmp。




比较:方法二,转移到另外一个队列后不用返回了,这样减少了转移的次数。




(2)代码实现:

void Push(Queue *q1, Queue *q2, int k)

{

Queue *pushtmp, *tmp;

if(IsQueueEmpty(q1) == 0)//q1非空

{

pushtmp = q1;

tmp = q2;

}

else

{

pushtmp = q2;

tmp = q1;

}

EnQueue(pushtmp, k);

}



int Pop(Queue *q1, Queue *q2)

{

int tmpvalue;

Queue *pushtmp, *tmp;

if(!IsQueueEmpty(q1))//q1非空。

{

pushtmp = q1;

tmp = q2;

}

else

{

pushtmp = q2;

tmp = q1;

}



if(IsQueueEmpty(pushtmp))

{

printf("Stack Empty!\n");

}

else

{

while(SizeOfQueue(pushtmp) != 1)

{

EnQueue(tmp, DeQueue(pushtmp));

}

tmpvalue = DeQueue(pushtmp);

return tmpvalue;

}

}



--------

或者:




思路:




1)若用两个queue实现(可以定义成queue的数组queue q[2]),可以增加一个currentIndex来指向当前选中的queue。


2)入栈操作可以直接把元素加到queue里,即  queue[currentIndex].push(element),时间复杂度为O(1),


3)处理方法是将size()-1个元素从q[currentIndex]转移到空闲队列q[(currentIndex + 1)%2]中,q[currentIndex]最后一个剩下的元素恰对应栈顶元素,之后更新一下currentIndex即可,时间复杂度为O(N)。




4)实现:


#include <iostream>

#include <queue>

#include <cassert>

using namespace std;



template <class T>

class YL_Stack

{

public:

YL_Stack():currentIndex(0)

{



}

void push(const T &element); //入栈

void pop(); //出栈

T top(); //栈顶元素

size_t size() const; //栈的大小

bool empty() const; //判断栈是否为空





private:

int currentIndex;

queue<T> q[2];

};



template <class T>

void YL_Stack<T>::push(const T &element)

{

q[currentIndex].push(element);

}



template <class T>

size_t YL_Stack<T>::size() const

{

return q[0].size()+q[1].size();

}



template <class T>

bool YL_Stack<T>::empty() const

{

return (size()==0);

}



template <class T>

void YL_Stack<T>::pop()

{

assert(!empty());



int index=(currentIndex+1)%2;

while(q[currentIndex].size()>1)

{

T temp=q[currentIndex].front();

q[currentIndex].pop();

q[index].push(temp);

}



q[currentIndex].pop();

currentIndex=index;

}



template <class T>

T YL_Stack<T>::top()

{

assert(!empty());



int index=(currentIndex+1)%2;

T temp;

while(q[currentIndex].size()>0)

{

temp=q[currentIndex].front();

q[currentIndex].pop();

q[index].push(temp);

}



currentIndex=index;

return temp;

}





void main()

{

YL_Stack<int> myStack;

myStack.push(1);

myStack.push(2);

myStack.push(3);

myStack.push(4);

myStack.push(5);

cout<<"1栈的大小为:"<<myStack.size()<<endl;

cout<<"1栈顶元素为:"<<myStack.top()<<endl;

myStack.pop();

myStack.pop();

myStack.pop();

cout<<"2栈的大小为:"<<myStack.size()<<endl;

cout<<"2栈顶元素为:"<<myStack.top()<<endl;



}