【c++】使用两个栈实现一个队列(详细介绍)

使用两个栈实现一个队列

思路一:

我们设定s1是入栈的,s2是出栈的。

入队列,直接压到s1即可

出队列,先把s1中的元素倒入到s2中,弹出s2中的栈顶元素;再把s2的剩余元素全部倒回s1中。

缺点:

每次只要出栈一个元素就要将元素倒来倒去,麻烦!!!

思路2:

入队列时:
如果s1为空,把s2中所有的元素倒出压到s1中。否则直接压入s1

出队列时:
如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素

思路1无条件地每次都要将元素倒来倒去,思路2出队时较思路1简单

思路3:

我们设定s1是入栈的,s2是出栈的

入队列:直接压入元素至s1即可

出队列:如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素

相比于方法2,入队直接压入即可~

那么,我们可以看出,思路三最简单,我们下面看下代码。

代码实现:


#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

#include<assert.h>

//直接实现Stack,也可以用适配器实现栈,或者用库。
//将Stack基本功能实现如下:
template<class T>

class Stack
{
public:
    Stack()
        :_array(NULL)
        , _size(0)
        , _capacity(0)
    {}

    Stack<T>(const Stack<T>& s)
        : _array(new T[s._capacity])
    {
        swap(_array, s._array);
        swap(_size, s._size);
        swap(_capacity, s._capacity);
    }

    Stack<T>& operator=(const Stack<T>& s)
    {
        if (&s != this)
        {
            swap(_array, s._array);
            swap(_size, s._size);
            swap(_capacity, s._capacity);
        }
        return *this;
    }

    ~Stack()
    {
        if (_array)
        {
            delete[] _array;
            _array = NULL;
        }
    }

    void _CheckCapacity()
    {
        if (_size == 0)
        {
            _capacity = 3;
            _array = new T[_capacity];
        }
        if (_size >= _capacity)
        {
            _capacity *= 2;
            T* tmp = new T[_capacity];
            for (int index = 0; index < _size; index++)
            {
                tmp[index] = _array[index];
            }
            delete[] _array;
            _array = tmp;
        }
    }

    void Push(const T& x)
    {
        _CheckCapacity();
        _array[_size++] = x;
    }

    void Pop()
    {
        if (_size == 0)
        {
            return;
        }
        --_size;
    }

    size_t Size()
    {
        return _size;
    }

    bool Empty()
    {
        return Size() == 0;
    }

    T& Top()
    {
        assert(_size > 0);
        return _array[_size - 1];
    }

private:
    T* _array;
    size_t _size;
    size_t _capacity;
};

template<class T>
class Queue
{
public:
    void InQueue(const T& x)
    {
        s1.Push(x);
    }

    void OutQueue()
    {
        //栈s2为空,则将栈s1的元素全部倒入s2中,再弹出最上面的那个元素
        if (s2.Empty())
        {
            while (!s1.Empty())
            {
                s2.Push(s1.Top());
                s1.Pop();
            }
            s2.Pop();
        }

        //栈s2不为空,直接弹出元素
        else
        {
            s2.Pop();
        }
    }

    
    void Print()    //打印队列元素,分四种情况。
    {
        if (s1.Empty() && s2.Empty())
        {
            cout << "The Queue is Empty!";
        }

        else if (!s1.Empty() && s2.Empty())
        {
            while (!s1.Empty())
            {
                s2.Push(s1.Top());
                s1.Pop();
            }

            while (!s2.Empty())
            {
                cout << s2.Top() << "  ";
                s2.Pop();
            }
        }

        else if (s1.Empty() && !s2.Empty())
        {
            while (!s2.Empty())
            {
                cout << s2.Top() << "  ";
                s2.Pop();
            }
        }

        else
        {
            while (!s2.Empty())
            {
                cout << s2.Top() << "  ";
                s2.Pop();
            }

            while (!s1.Empty())
            {
                s2.Push(s1.Top());
                s1.Pop();
            }

            while (!s2.Empty())
            {
                cout << s2.Top() << "  ";
                s2.Pop();
            }
        }
        cout << endl;
    }

private:
    Stack<T> s1;    //入队
    Stack<T> s2;    //出队
};

//测试两个栈实现一个队列
void Test1()
{
    Queue<int> q1;
    q1.InQueue(1);
    q1.InQueue(2);
    q1.InQueue(3);
    q1.InQueue(4);
    /*q1.Print();*/

    q1.OutQueue();
    /*q1.Print();*/
    q1.InQueue(5);
    q1.InQueue(6);
    q1.InQueue(7);

    q1.Print();
}

int main()
{
    Test1();
    system("pause");
    return 0;
}

(1个细节):

注意再将元素倒入另一个栈时,代码并不是先pop,再push。因为这样push后元素就找不到了。因此要先访问到栈顶元素top,再push,而后pop。

时间: 2024-08-25 07:44:31

【c++】使用两个栈实现一个队列(详细介绍)的相关文章

使用两个栈实现一个队列

使用两个栈Stack1和Stack2来实现一个队列.其中一个栈作为主存放数据的,另外一个栈作为临时存放数据的栈.具体操作如下: enqueue: 栈Stack1的入栈操作. dequeue:将Stack1中的元素一个一个地全部依次出栈,并且在Stack1出栈的同时把出栈的元素作为参数对Stack2进行入栈操作.这步完成之后,执行Stack2出栈操作,这时就将原先在Stack1中最先入栈的元素弹出.最后再将Stack2中的元素一个一个地全部依次出栈,填到Stack1中. 实现代码如下: /** *

用两个栈实现一个队列

用两个栈实现一个队列的功能 解析: 假设两个栈A和B,且都为空. 可以认为栈A提供入队列的功能,栈B提供出队列的功能. 入队列:入栈A. 出队列: 如果栈B不为空,直接弹出栈B的数据. 如果栈B为空,则依次弹出栈A的数据,放入栈B中,再弹出栈B的数据. 代码如下: #include<iostream> #include<stack> using namespace std; template<class T> struct MyQueue { void push(T &

两个栈实现一个队列

问题描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解法分析: 首先题目要求用两个栈实现一个队列,那么就要先分析为什么这么做.队列的特点就像排队的"先到先得"一样,即先入队的就先出队:而栈则正好相反,特点是"后进先出",那么问题来了怎么用"后进先出"的得到"先进先出"? 传说中最简单通用但效率不高的方法(其实我还真没想到这么做)是,入队的时候用stack1来存储,当出队的时候,先把

web前端面试系列 - 数据结构(两个栈模拟一个队列)

一. 用两个栈模拟一个队列 思路一: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时将数据压人s1 3. 出队时将s1弹出,并压人s2,然后弹出s2中的顶部数据,最后再将剩余数据弹出s2,并压人s1. 思路二: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时,判断s1, 是否为空,如果不为空,则将数据直接压入s1, 如果为空,则将s2中的数据全部倒入s1,在将数据压人s1. 3. 出队时,判断s2, 是否为空,如果不为空,则直接弹出s2

两个栈实现一个队列,两个队列实现一个栈

1.两个栈实现一个队列 有三种思路: 思路一:将stack1作为存储空间,将stack2作为临时缓冲区,入队时,直接压入stac1,出队时,将stack1中的元素依次出栈压入stack2中,再将stack2的栈顶元素弹出,最后将stack2中的元素再倒回给stack1 思路二:入队时,判断stack1是否为空,如果stack1为空,则将stack2中的所有元素都倒入stack1中,再将元素直接压入stack1,否则,直接压入stack1中 出队时,判断stack2是否为空,如果stack2为空,

013使用两个栈实现一个队列(keep it up)

使用两个栈实现一个队列 队列是先进先出的数据结构(FIFO),栈是先进后出的数据结构(FILO), 用两个栈来实现队列的最简单方式是:进入队列则往第一个栈压栈, 出队列则将第一个栈的数据依次压入第二个栈,然后出栈. 两条规则: 1)进队列,则直接压入第一个栈 2)出队列,若果第二个栈不为空,直接pop(),如过第二个栈为空, 则把第一个栈中的数据全部压入第二个栈(第一个栈此时为空). 实际写代码时注意栈为空的情况. 代码: #include <iostream> #include <st

两个栈实现一个队列和两个队列实现一个栈【算法导论课后题】

关于两个栈实现一个队列和两个队列实现一个栈问题,网上有很多资料.这里只描述自己认为操作最少的方法. 两个栈实现一个队列 思想:假设两个栈分别为s1,s2.对s1进行入队,出队时,先判断s2是否为空,如果是则将s1中元素压入s2并弹出最上面元素,如果不是,则直接弹出s2最上面的元素. <span style="font-size:18px;">EnQueue(s1,s2,k){ push(s1,k)</span><span style="font-

[算法学习]两个栈实现一个队列

问题描述: 用两个栈实现一个队列,实现两个方法:入队appendTail,出队deleteHead 分析: 第一眼就能想到两个做法, (1) 入队麻烦出队容易: 声明两个栈,一个是存数据用的栈(dataStack),一个是辅助用的栈(tempStack). 入队操作时,先将dataStack中的所有元素出栈压入tempStack中,然后将要入队的元素压入tempStack中,再将tempStack所有元素出栈到dataStack,至此入队成功,dataStack栈顶元素就是第一个入队的元素(队头

两个栈模拟一个队列和两个队列模拟一个栈

此为网易的一道笔试题.到时候秀逗,不知所云.后来研究之后记录下,以备以后经常翻阅. 栈:先进后出 push和pop 队列:先进先出 offer和poll (1)两个栈模拟一个队列 即将先进后出实现先进先出.比较容易理解,只要所有数据先往一个栈里push,然后将该栈中的数据依次pop出来再push进第二个队列,则顺序自然颠倒过来了,则每次pop是从第二个队列中取数据. import java.util.*; public class StackQueue{ private Stack<Intege