【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)

原创 2016年05月30日 17:18:28

使用两个栈实现一个队列


思路一:

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


入队列,直接压到s1即可


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


wKioL1cMpjajUzcyAABT0frZ3KM694.png

缺点:

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



思路2:

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

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


wKiom1cMppLwMd0QAAB3LagChFk387.png



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



思路3:

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

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

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


wKioL1cMp8HR1m6aAABLlSxXUHE848.png


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

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


代码实现:

1)我们直接调用库里的stack来实现。(一般调用库里的就行了

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
//两个栈实现一个队列
#include<stack>

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

    void deleteHead()
    {
          if (s2.empty())
          {
              while (!s1.empty())
              {
                  s2.push(s1.top());
                  s1.pop();
              }
              cout << s2.top() << "  ";
              s2.pop();
          }
          else
          {
               cout << s2.top() << "  ";
               s2.pop();          
          } 
    }
private:
    stack<T> s1;
    stack<T> s2;
    
};


void Test()
{
    Queue<int> q;
    q.appendTail(1);
    q.appendTail(2);
    q.appendTail(3);
    q.appendTail(4);
    q.deleteHead();
    q.deleteHead();
    q.deleteHead();
    q.deleteHead();
}

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



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。

本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1763006

C++算法之 两个队列实现一个栈

题目:用两个队列实现一个栈 算法思路: 现有两个队列q1与q2,入栈:如果q1与q2都为空,那么我们选择q1入栈也就是入队列,比如q1入栈 1 2 3 4 ;现在要出栈,后进先出那么4要出栈。但是...
  • djb100316878
  • djb100316878
  • 2014年12月09日 10:48
  • 9795

【C++面试题】利用两个栈实现1个队列

1、题目   利用两个栈实现一个队列    2、要求   只能使用栈的pop(),top()和push(),以及测试栈是否为空empty()四个操作. 来实现队列的empty(), ...
  • liulongling
  • liulongling
  • 2016年02月19日 11:03
  • 1863

两个栈实现一个队列以及两个队列实现一个栈(Java)

两个栈实现一个队列import java.util.Stack;public class Demo07 { Stack stack1 = new Stack(); Stack stac...
  • scgaliguodong123_
  • scgaliguodong123_
  • 2015年09月02日 10:51
  • 4707

【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)

http://blog.csdn.net/hanjing_1995/article/details/51539578 使用两个栈实现一个队列 思路一: 我们设定s1是...
  • sinat_35297665
  • sinat_35297665
  • 2018年01月05日 14:09
  • 18

【数据结构】栈面试题--两个栈实现一个队列

首先我们必须清楚,栈先进后出,队列先进先出。这道他们各自的特点之后,我们用两个栈来实现一个队列。 下边给出图片: 下边给出代码: 恩...
  • peiyao456
  • peiyao456
  • 2016年09月21日 19:08
  • 1010

数据结构面试题:两个堆栈实现一个队列

1、用两个堆栈实现一个队列 http://www.cnblogs.com/wanghui9072229/archive/2011/11/22/2259391.html   两年前从网上看...
  • yuluohaibin
  • yuluohaibin
  • 2013年03月16日 14:08
  • 458

程序员面试题精选100题(18)-用两个栈实现队列[数据结构]

题目:某队列的声明如下: template class CQueue { public: CQueue() {} ~CQueue() {} void appen...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年02月22日 21:00
  • 441

【数据结构】栈面试题--一个数组实现两个栈

一个数组实现两个栈,有以下几种方法: 1.数组的奇数位置存储一个栈的元素,偶数位置存储另一个栈的元素; 2.两个栈分别从数组的中间向两头增长; 3.两个栈分别从数组的两头开始增长。 从...
  • peiyao456
  • peiyao456
  • 2016年10月03日 20:17
  • 832

数据结构-使用两个栈实现一个队列

1.使用两个栈实现一个队列 思路一: 假设一个s1是栈的s2是出栈的 入队时,直接先把s1是入栈的,s2是出栈的。 入队时,直接压到s1即可。出栈时,把s1的元素全部倒入s2中,然后弹出s2的栈顶元素...
  • qq1010234991
  • qq1010234991
  • 2016年04月13日 10:19
  • 257

数据结构与算法分析(Java 语言描述)(36)—— 使用两个队列实现一个栈

思路:入栈操作: 直接对 queue_1 进行 add 操作 出栈操作: 若 queue_1 的长度 > 1,对 queue_1 进行 remove 操作,将这些数据放入 queue_2 中,直到 q...
  • HeatDeath
  • HeatDeath
  • 2017年12月11日 16:20
  • 176
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)
举报原因:
原因补充:

(最多只允许输入30个字)