面试题9:用两个栈实现队列

// 面试题9:用两个栈实现队列
// 题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail
// 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
相关类和函数定义如下:
template <typename T> class CQueue
{
public:
    CQueue(void);
    ~CQueue(void);
    
    // 在队列末尾添加一个结点
    void appendTail(const T& node);

    // 删除队列的头结点
    T deleteHead();

private:
    stack<T> stack1;
    stack<T> stack2;
};

解题思路:

栈和队列是截然不同的两种结构,栈是后进先出,先进栈的元素会被压到栈底。

队列则是先进先出。

队列末尾添加节点很简单直接在stack1入栈即可。

删除队列的头结点的话,因为头结点被压在stack1的栈底,所以应该全部出栈再压入stack2,stack2栈顶元素出栈即可。

主要是所有情况都要考虑到。

1)队列为空,即stack1和stack2均为空,这个时候应该抛出异常

2)stack1不为空,stack2为空。直接stack1所有元素出栈,再压入stack2,然后stack2栈顶元素出栈即可。

3)stack1不为空/为空,stack2不为空。不管stack1是不是有元素,只要stack2不为空,说明stack2中元素都是顺着排的,像队列一样,

也就不再需要stack1出栈入栈了,直接stack1栈顶元素出栈。

代码可以这样写,只要stack2为空就开始转移stack1的元素,转移完后如果stack2还是空,抛出异常;

否则就直接stack2栈顶元素出栈并返回即可。

伪代码:

template<typename T> void CQueue<T>::appendTail(const T& element)
{
    将element压入stack1;
} 
template<typename T> T CQueue<T>::deleteHead()
{

    if(stack2为空){
        while(stack1不为空){
            保存stack1栈顶元素;
            stack1栈顶元素出栈;
            stack1原栈顶元素压入stack2;
        }
    }

    if(stack2为空)
        throw exception("队列为空");

    保存stack2栈顶元素;
    stack2栈顶元素出栈;
    return stack2原栈顶元素;
}

c/c++:

 

template<typename T> void CQueue<T>::appendTail(const T& element)
{
    stack1.push(element);
} 

template<typename T> T CQueue<T>::deleteHead()
{
    //stack2不为空,开始搬运元素
    if(stack2.size()<= 0)
    {
        while(stack1.size()>0)
        {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    //搬运后stack2仍为空,抛出异常
    if(stack2.size() == 0)
        throw new exception("queue is empty");

    //stack2栈顶元素出栈,返回
    T head = stack2.top();
    stack2.pop();

    return head;
}

参考资料:

剑指offer第二版面试题9

posted @ 2018-08-06 19:18  朕蹲厕唱忐忑  阅读(174)  评论(0编辑  收藏  举报