栈的原则是后进先出,即插入与删除元素均在栈顶进行。 (获取栈顶元素:s.top() )
队列的原则是先进先出,即插入数据在队尾进行,删除数据在队头进行。 (获取队头元素:q.front() )
-
用两个栈实现一个队列
思路:用两个栈,一个栈用来进队,一个栈用来出队,当数据进入队列的时候,我们将其压入一个栈,当数据出队的时候,我们将保存在栈内的数据pop出来,将其按照出栈的顺序压入另外一个栈,然后pop栈顶的数据就实现了出队的操作。当我们进行入队操作的时候,可以直接将数据压入第一个栈。
示意图:
实现流程:
1.stack1用来push数据:将数据push到s1前需要先将s2腾空,即把s2中的数据插入到s1中,保证stack2为空。
2.stack2用来pop数据:
当stack1不为空时,将stack1中的数据全部pop出来,按照出栈的顺序压入stack2中,然后拿到s2的栈顶元素并将其pop即可
当stack2不为空时,直接pop stack2的栈顶元素即可。
代码实现:(注意:两个栈都为空的时候是不能进行出队操作的)
class MyQueue {
public:
MyQueue()
{}
~MyQueue()
{}
//入队
void push(int x) { //设置插入到s1中
while(!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
s1.push(x);
}
//出队
int pop() {
//注意:s1,s2为空则return
if(s1.empty() && s2.empty())
return -1;
while(!s1.empty()) //将s1中元素插入s2中
{
s2.push(s1.top());
s1.pop();
}
int ret = s2.top(); //拿到s2的top
s2.pop();
return ret;
}
//获取队头(即获取转移后的栈顶元素)
int peek() {
if(s2.empty())
{
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
int ret = s2.top();
return ret;
}
//判空
bool empty() {
return s1.empty() && s2.empty();
}
private:
stack<int> s1;
stack<int> s2;
};
-
用两个队列实现一个栈
思路:要实现一个栈,那么后进入的数据一定是先出去的。利用两个队列来进行数据顺序的调整。当数据进入一个栈时,可以先将数据push到一个队列当中;当需要删除数据时,因为队列是先进先出的,所以我们可以将队尾的元素保留下来,其余元素按照出队的顺序入队到另外一个队列当中,然后pop第一个队列的最后剩下的一个元素,这样就实现了栈的删除操作。
示意图:
实现步骤:
1.push数据:在插入数据的时候,需要对队列进行判断,将数据插入到非空的队列当中(都为空则默认插入q1)。这样的话pop时我们分情况讨论的时候只用分队列为空和不为空两种情况,有利于代码的编写。
2.pop数据:在删除数据时,我们需要将非空队列的队尾数据保存下来最后进行pop,其余数据入队到另外一个队列当中。就这样利用两个队列来对数据进行来回交换实现栈。
代码实现:(注意:当两个队列都为空的时候是没有办法pop数据的)
class MyStack {
public:
MyStack()
{}
~MyStack()
{}
//入栈
void push(int x) { //插入非空队列(都为空默认插入q1)
if(!q2.empty())
q2.push(x);
else
q1.push(x);
}
//出栈
int pop() {
if(q1.empty()&&q2.empty()) //都为空无法pop
return -1;
int ret;
if(!q1.empty()) //q1不为空,将q1中的size-1个元素插入q2
{
while(q1.size()!=1)
{
q2.push(q1.front());
q1.pop();
}
ret = q1.front(); //拿到q1中仅剩的一个元素
q1.pop();
}
else //q2不为空,将q2中的size-1个元素插入q1
{
while(q2.size()!=1)
{
q1.push(q2.front());
q2.pop();
}
ret = q2.front(); //拿到q2中仅剩的一个元素
q2.pop();
}
return ret;
}
//获取栈顶元素
int top() { //返回非空队列的队尾元素
if(!q1.empty())
return q1.back();
else
return q2.back();
}
//判空
bool empty() {
return q1.empty() && q2.empty();
}
private:
queue<int> q1;
queue<int> q2;
};