剑指offer 用两个栈实现队列

1.题目

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

来源:剑指offer
链接:https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

2.我的题解

栈的特点是先入后出,队列的特点是先入先出。
考虑使用一个栈(记为s1)响应push操作,另一个栈(记为s2)响应pop操作。
push()时直接入s1pop()时首先检查s2是否是空,非空直接pop(),为空则将s1的元素逐一弹出到s2中。
如果s1,s2均为空,还要调用pop()函数,那肯定就会出错了。也可以自己添加一个empty()方法。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        int res = stack2.top();
        stack2.pop();
        return res;
    }
    
    bool empty(){
        return stack1.empty() && stack2.empty();
    }

private:
    stack<int> stack1;//入
    stack<int> stack2;//出
};

3.别人的题解

一个java版本的解法是这样的:

链接:https://www.nowcoder.com/questionTerminal/54275ddae22f475981afa2244dd448c6?answerType=1&f=discussion
来源:牛客网

import java.util.Stack;
 
public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
 
    public void push(int node) {
        stack1.push(node);
    }
 
    public int pop() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
}

于是我突然开始羡慕java,这个pop()多“人性化”啊,返回值为栈顶元素,一行代码就可以解决原先的两行代码,对比一下:

#c++
stack2.push(stack1.top());
stack1.pop();

#java
stack2.push(stack1.pop());

总感觉自己这样写很蠢啊,先访问栈顶元素,再pop(),一般来讲pop()的时候也需要得到栈顶元素的值,那么直接一步到位,pop()返回栈顶元素多好了?但我觉得事情远没有那么简单,我一个小白怎么敢质疑STL的设计,果然我找到了以下原因1
(1)安全性考虑。假如pop()返回栈顶元素时发生异常,那么栈顶元素将丢失;
(2)高效性考虑。top()返回引用即可,而pop()如果返回栈顶元素必须返回实例。

具体解释一下(1),假如有以下的栈和代码:

class Stack
{
    public:
    T pop();    //let pop to change the stack's internal state and return the top element.

}; 
Stack stack;
stack.push(object);
Object obj=stack.pop() ;//这里调用Object的构造函数,假如此时发生异常,则栈顶元素将丢失。

另贴一份类似于官方说明文档的话:

One might wonder why pop() returns void, instead of value_type. That is, why must one use top() and pop() to examine(检查) and remove the top element, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the top element,it would have to return by value rather than by reference: return by reference would create adangling pointer(悬空指针). Return by value, however, is inefficient: it involves at least one redundantcopy constructor call. Since it is impossible for pop() to return a value in such a way as tobe both efficient and correct, it is more sensible(明智的) for it to return no value at all and torequire clients to use top() to inspect the value at the top of the stack.

4.总结与反思

(1)C++ STL的栈pop()函数返回值为void


  1. 为什么C++中stack的pop()函数不返回值而返回void. ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值