算法-两个栈实现队列

题目: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数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;
};

解题思路: 首先这个题目要完成两个栈实现队列,其次还涉及到C++类和模板的一些知识,先说前面: 我们知道,是一种后入先出的结构,而队列恰恰相反,是一种先入先出的结构,需要用栈实现队列,这意味着我们有现成的push和pop可以用,以实现入队和出队。

现在有两个栈stack1和stack2,我们向stack1依次压入a,b,c三个值,stack2为空:

此时出栈的话,顺序为c,b,a,但是出队的顺序应该是a,b,c,为了实现想要的出队顺序,我们可以把stack1里面的内容依次压入stack2中:

此时再将stack2内的内容做出栈,将弹出a:

下面讨论再次入队的情况,将d压入stack1,此时两个栈的情况:

此时出队的话,在stack2中还有值的话,直接出栈stack2,弹出b,c。此时stack2中已经没有值了,需要再次从stack1中出栈到stack2中入栈,然后再次stack2的出栈,弹出d。这与队列的出队形式完全相同:

我们可以根据上面的实验整理出一个编程思路,如果stack2中没有值,就做stack1到stack2的压栈,如果有就做stack2的出栈,而不管stack1有没有值都可以做入栈。

下面需要考虑的是C++的模板,使用模板的目的就是能够编写与类型无关的代码,在上面例子中使用了a,b,c,d,那么在实例化对象时T就行该是char,比如实例化一个叫做queue的对象:

CQueue<char> queue;

此外,由于deleteHead函数return不为空,所以他的类型是T,此外appendTail和deleteHead都是在类内声明,类外定义的函数,所以在定义函数时要加类名。

代码实现

template <typename T> CQueue<T>::~CQueue(void)
{
}

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

template<typename T> T CQueue<T>::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;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Golang的反射reflect深入理解和示例

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和...

1376
来自专栏技术总结

《Objective-C高级编程》温故知新之"Blocks"

在计算机科学中,此概念也称为闭包(Closure)、lambda计算等。Swift中称作闭包

1234
来自专栏跟着阿笨一起玩NET

C# 中用 yield return 关键字实现获取树型数据结构的所有子节点

通常,我们在获取树形结构数据所有子节点时,需要写一个递归调用的方法,循环调用,这是数据结构算法里的通用写法。

722
来自专栏恰同学骚年

剑指Offer面试题:6.用两个栈实现队列

  原文是使用C++结合模板实现的定义,这里我们采用C#结合泛型来实现这个队列的定义,我们要实现的就是两个方法:AppendTail与DeleteHead

411
来自专栏阿杜的世界

Java Web技术经验总结(十五)

662
来自专栏blackheart的专栏

[C#1] 3-基元类型、引用类型和值类型、装箱拆箱

1.基元类型 编译器直接支持的数据类型成为基元类型。基元类型与FCL中的类型有直接的映射关系[int=Int32],这样我们可以简化的方式书写代码,并且编译后的...

1845
来自专栏小灰灰

SPI框架实现之旅二:整体设计

SPI框架实现之旅二:整体设计 上一篇简单的说了一下spi相关的东西, 接下来我们准备开动,本篇博文主要集中在一些术语,使用规范的约定和使用方式 设计思路 下...

2308
来自专栏DHUtoBUAA

《剑指Offer》附加题_用两个队列实现一个栈_C++版

  在《剑指Offer》中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即“用两个队列实现一个栈”。   在计算机数据结构中,栈的特点是后进先出,即最后...

2715
来自专栏高性能服务器开发

什么是B+Tree

B+Tree的定义 B+Tree是B树的变种,有着比B树更高的查询性能,来看下m阶B+Tree特征: 1、有m个子树的节点包含有m个元素(B-Tree中是m-1...

2938
来自专栏Java编程技术

并发队列中迭代器弱一致性原理探究

并发队列里面的Iterators是弱一致性的,next返回的是队列某一个时间点或者创建迭代器时候的状态的反映。当创建迭代器后,其他线程删除了该元素时候并不会抛出...

841

扫码关注云+社区