C++实现用两个栈模拟一个队列

  • 问题描述

用两个栈来实现一个队列,队列的声明如下,实现其中的两个函数,分别完成在队列尾部插入节点和在队列头部删除节点的操作。

声明:

template  class CQueue
{
public:
    CQueue(void);
    ~CQueue(void);

    void appendTail(const T& element)
    T deleteHead();

privite:
    stack  stack1;
    stack  stack2;    
}

其中appendTail函数是队列尾部插入节点函数,deleteHead是删除队列头部节点函数。

  • 问题分析

众所周知栈是一种先进后出的结构,而队列是先进先出的。如果我们需要使用两个FILO的结构实现FIFO,不妨这么思考:

分别给两个栈编号,叫做stack1和stack2.我们插入数据时,先将数据都按顺序给stack1里压栈。比如我传入的数据是1,2,3,按照 队列来说输出也应该是1,2,3.我们先将1,2,3压入stack1,那么此时stack1从栈底到栈顶分别为1,2,3.接着,我们将stack1全部出栈,并且每出一个就向stack2压栈。完成这步操作之后,stack2中的数据从栈底到栈顶就是3,2,1了。此时对stack2进行出栈操作,顺序就和队列的完全一样了。

那么,如果我们现在已经将stack1中的数据全部压栈进入stack2了,这时又插入了一个数据,该怎么处理呢?

我们只需将新插入的数据压入stack1,并且只要stack2非空的话,stack1就不用向stack2压栈。这样就保证了即使新插入数据,也不会对模拟队列造成影响。

对于题中要求的两个函数:首先第一个要求在队列尾插入数据。我们经过上面的分析相信你也体会到了,其实stack1就是我们模拟队列的队尾。只不过“队尾”中的节点需要出栈再压入stack2才能用于出队。所以具体实现只需要stack1.push(element)。

第二个问题:先判断stack2是否空,为空的话就从stack1中拿节点压栈。如果stack1也为空的话,队列就是真正的空队,无法进行pop操作了。否则,定义一个T类型的变量,记录stack2.top()用于返回,然后stack2调用一次pop函数即可。

具体代码:

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

template  T CQueue::deleteHead()
{
    if(stack2.size() <= 0)
    {
        while(stack1.size() > 0)
        {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    if(stack2.size() == 0)
    {
        throw new exception("Queue is empty.");
    }

    T head = stack2.top();
    stack2.pop();
    return head;
}

 

你可能感兴趣的:(数据结构,杂谈)