首先,我们得了解队列和栈的基本原理。
队列是一个“先进先出“的一个结构。队列的定义是在队尾插入,在队头删除,这就要求要用一种在尾部插入容易的,在头部删除容易的结构,你一定会想到单链表,对,库的实现就是用一个链表实现的。
栈,相信大家都不会陌生,函数栈帧等的实现,它是一种”先进后出“的结构。栈的插入删除都是在尾部进行的。
所以要用队列实现一个栈,要解决的问题就是在删除时要删除最后插入的那个元素。
我们先来模拟一下出栈和入栈的情况:
(1)入栈:Q1:1,2,3,4入队列(相当于入栈);
(2)出栈:Q1:1,2,3出队列,Q2:1,2,3入队列;(此时Q1只剩4,正是我们要出栈的元素)
(3)
1>入栈:Q1:5入队列(每次入栈都用Q1入队列实现,而不入队列Q2,这样会提高效率,后面会说到)
2>出栈:判断:如果Q1队列不为空就用(1)(2)步的方法出栈最后一个元素。否则,出栈Q2队列的最后一个元素。
我们首先来搭建这个栈的结构:
#pragma once #include<iostream> #include<queue> #include<string> #include<assert.h> using namespace std; template<class T> class MYStack { public: MYStack() :_size(0) { } ~MYStack() { } void Push(const T& x); void Pop(); bool Empty(); size_t Size(); void Print(); private: queue<T> q1; queue<T> q2; size_t _size; };
一个栈具有的功能我们都实现一下,Psh(),Pop(),Empty(),Size()等等。
在这个结构中数据成员是两个队列的对象,因为我们是用两个队列来实现的,还有一个_size用来记录栈中元素的个数。
下面是函数具体实现:
template<class T> void MYStack<T>::Push(const T& x) { q1.push(x); ++_size; } template<class T> void MYStack<T>::Pop() { //assert(_size > 0); //size_t plen = q1.size(); //while (plen != 1) //{ // T tmp = q1.front(); // q2.push(tmp); // q1.pop(); // --plen; //} //q1.pop(); //plen = q2.size(); //while (plen) //{ // T tmp = q2.front(); // q1.push(tmp); // q2.pop(); // --plen; //} //--_size; assert(_size > 0); size_t plen = q1.size(); if (plen == 0) { //if (q2.size() == 0) // return; plen = q2.size(); while (plen != 1) { T tmp = q2.front(); q1.push(tmp); q2.pop(); --plen; } q2.pop(); } else { size_t plen = q1.size(); while (plen != 1) { T tmp = q1.front(); q2.push(tmp); q1.pop(); --plen; } q1.pop(); } --_size; } template<class T> bool MYStack<T>::Empty() { return _size ? false : true; } template<class T> size_t MYStack<T>::Size() { return _size; } template<class T> void MYStack<T>::Print() { //size_t plen = q1.size(); //while (plen--) //{ // cout << q1.front() << " "; // q1.pop(); //} size_t plen = q2.size(); while (plen--) { cout << q2.front() << " "; q2.pop(); } plen = q1.size(); while (plen--) { cout << q1.front() << " "; q1.pop(); } }
注释掉的部分也可以实现,它的原理是不管第(3)步是出栈还是入栈,都把剩下的元素从Q2出栈入栈到Q1,输出的时候只用输出Q1中的元素。但是它的效率较低。如果有这种情况:1,2,3.....100000入栈,然后1,2,3......100000出栈,这会导致Q1和Q2频繁的出栈和入栈,效率非常之低。
优化方法就是没有注释部分。它的实现就是入栈都是Q1入队列,出栈后不把Q2的元素移到Q1,这样的话效率就会提高,只是在输出的时候要先输出Q2里的元素,再输出Q1里的元素。因为Q1里的元素总是栈顶的元素。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。