俩个栈实现一个队列
如图所示我们有俩个栈A和B
我们首先把1,2,3依次入栈之后,如果此时我们需要"出队"我们的做法是把A栈中的元素依次出栈后放入栈B。
然后我们把B的栈顶元素弹出即可以达到队列的先进先出的特点
把栈A中元素弹出放到栈B中
把栈B中的栈顶元素弹出
此时我们再向栈中添加元素时还是向栈A加入元素
只要栈B不为空,我们便一直在栈B中弹出元素
一旦栈B为空我们就把元素从A中向B中"倒",直到A中元素被"倒"完成之后再把栈B的栈顶元素弹出。
根据这个思路实现的相关代码:
首先实现一个简单栈
template<typename T>
class Stack
{
private:
int _top;
size_t _size;
T *_data;
void expand()
{
T *nTmp = new T[_size * 2];
for (int i = 0; i < _top; i++)
nTmp[i] = _data[i];
delete[]_data;
_data = nTmp;
_size *= 2;
}
public:
Stack(size_t size = 10)
{
_data = new T[10];
_top = 0;
_size = size;
}
~Stack() { delete[]_data; }
void push(const T&val)
{
if (full())
expand();
_data[_top++] = val;
}
Stack(const Stack &obj) = delete;
void operator=(const Stack &obj) = delete;
T pop()
{
if (empty())
throw "stack is empty";
return _data[--_top];
}
bool full()const
{
return _top == _size;
}
bool empty()const
{
return _top == 0;
}
size_t size()const
{
return _size;
}
void show()const
{
for (int i = 0; i < _top; i++)
cout << _data[i] << " ";
cout << endl;
}
};
用上述栈实现俩个栈模拟队列的类
template<typename T>
class STQ
{
private:
Stack<T> _stack_push;//需要push时使用的栈
Stack<T> _stack_pop;//需要pop时使用的栈
public:
STQ() {}
~STQ() {}
STQ(const STQ<T>&src) = delete;
void operator=(const STQ<T>&src) = delete;
void push(const T&val)
{
_stack_push.push(val);
}
T pop()
{
if (!_stack_pop.empty())
return _stack_pop.pop();
else
{
if (_stack_push.empty() && _stack_pop.empty())
throw STQEMPTY;
while (!_stack_push.empty())
_stack_pop.push(_stack_push.pop());
return _stack_pop.pop();
}
}
};
俩个队列实现一个栈
如图
第一步:我们在队列A中加入三个元素1,2,3
第二步:然后比如我们现在要弹出元素,那么我们的做法是,把队列A的最后一个元素"3"之前的所有元素,出队然后再入队B)如图:
第三步:此时我们把"3"弹出给用户,之后我们要再加入元素需要向不为空的队列入队(此时的队列B)
之后的步骤重复从"第一步"到这里。
根据如上所述的代码
简单队列实现
template<typename T>
class Queue
{
private:
T *_data;
int _head;
int _rear;
size_t _size;
void expand()
{
T *nTmp = new T[_size * 2];
for (int i = 0; i < _size; i++)
nTmp[i] = _data[i];
delete[]_data;
_data = nTmp;
_size *= 2;
}
public:
Queue(size_t size = 10)
:_size(size)
,_head(0)
,_rear(0)
{
_data = new T[size];
}
~Queue() { delete[]_data;}
Queue(const Queue&src) = delete;
void operator=(const Queue&src) = delete;
void push(const T&val)
{
if (full())
expand();
_data[_rear++] = val;
}
T pop()
{
if (empty())
throw "queue is empty";
T res = _data[0];
for (int i = 1; i < _rear; i++)
_data[i - 1] = _data[i];
_rear--;
return res;
}
bool full()const { return _rear == _size; }
bool empty()const { return _rear == 0; }
size_t size()const { return _rear - _head; }
void show()const
{
for (int i = 0; i < _rear; i++)
cout << _data[i] << " ";
cout << endl;
}
};
使用俩个队列模拟栈的特性
template<typename T>
class QTS
{
private:
Queue<T> que1;
Queue<T> que2;
public:
QTS() {}
~QTS() {}
QTS(const QTS&src) = delete;
void operator=(const QTS&src) = delete;
void push(const T &val)
{
//直往一个队列中放元素,保
if (que1.empty())//向另外一个为空或者不为空的队列中放元素
que2.push(val);
else
que1.push(val);
}
T pop()
{
if (que1.empty() && que2.empty())
throw QTSEMPTY;
//首先不为空的队列一直pop到空的队列中直到最后一个为止,把最后一个元素pop给用户
T last;
Queue<T> *Full = que1.empty() ? &que2 : &que1;
Queue<T> *Empty = Full == &que1 ? &que2 : &que1;
//(除了最后一个元素)把非空的队列中的元素全部入队到另外一个队列
while (Full->size() != 1)
Empty->push(Full->pop());
return Full->pop();
}
};
下面是所有的代码结合和测试用例
(如果有什么错误的地方,或者可以改进的地方欢迎指出讨论)
#include <iostream>
#include <string.h>
enum error_type{ STQEMPTY, QTSEMPTY };
using namespace std;
template<typename T>
class Stack
{
private:
int _top;
size_t _size;
T *_data;
void expand()
{
T *nTmp = new T[_size * 2];
for (int i = 0; i < _top; i++)
nTmp[i] = _data[i];
delete[]_data;
_data = nTmp;
_size *= 2;
}
public:
Stack(size_t size = 10)
{
_data = new T[10];
_top = 0;
_size = size;
}
~Stack() { delete[]_data; }
void push(const T&val)
{
if (full())
expand();
_data[_top++] = val;
}
Stack(const Stack &obj) = delete;
void operator=(const Stack &obj) = delete;
T pop()
{
if (empty())
throw "stack is empty";
return _data[--_top];
}
bool full()const
{
return _top == _size;
}
bool empty()const
{
return _top == 0;
}
size_t size()const
{
return _size;
}
void show()const
{
for (int i = 0; i < _top; i++)
cout << _data[i] << " ";
cout << endl;
}
};
template<typename T>
class Queue
{
private:
T *_data;
int _head;
int _rear;
size_t _size;
void expand()
{
T *nTmp = new T[_size * 2];
for (int i = 0; i < _size; i++)
nTmp[i] = _data[i];
delete[]_data;
_data = nTmp;
_size *= 2;
}
public:
Queue(size_t size = 10)
:_size(size)
,_head(0)
,_rear(0)
{
_data = new T[size];
}
~Queue() { delete[]_data;}
Queue(const Queue&src) = delete;
void operator=(const Queue&src) = delete;
void push(const T&val)
{
if (full())
expand();
_data[_rear++] = val;
}
T pop()
{
if (empty())
throw "queue is empty";
T res = _data[0];
for (int i = 1; i < _rear; i++)
_data[i - 1] = _data[i];
_rear--;
return res;
}
bool full()const { return _rear == _size; }
bool empty()const { return _rear == 0; }
size_t size()const { return _rear - _head; }
void show()const
{
for (int i = 0; i < _rear; i++)
cout << _data[i] << " ";
cout << endl;
}
};
void Test_Stack_Queue()
{
Stack<int> st;
for (int i = 0; i < 20; i++)
st.push(rand() % 100 + 1);
st.show();
while (!st.empty())
cout << st.pop() << " ";
cout << endl;
cout << "+++++++++++++++++++++++++++++" << endl;
Queue<int> que;
for (int i = 0; i < 20; i++)
que.push(rand() % 100 + 1);
que.show();
while (!que.empty())
cout << que.pop() << " ";
cout << endl;
}
template<typename T>
class STQ
{
private:
Stack<T> _stack_push;//需要push时使用的栈
Stack<T> _stack_pop;//需要pop时使用的栈
/*void expand()
{
}*/
public:
STQ() {}
~STQ() {}
STQ(const STQ<T>&src) = delete;
void operator=(const STQ<T>&src) = delete;
void push(const T&val)
{
_stack_push.push(val);
}
T pop()
{
if (!_stack_pop.empty())
return _stack_pop.pop();
else
{
if (_stack_push.empty() && _stack_pop.empty())
throw STQEMPTY;
while (!_stack_push.empty())
_stack_pop.push(_stack_push.pop());
return _stack_pop.pop();
}
}
};
template<typename T>
class QTS
{
private:
Queue<T> que1;
Queue<T> que2;
public:
QTS() {}
~QTS() {}
QTS(const QTS&src) = delete;
void operator=(const QTS&src) = delete;
void push(const T &val)
{
//直往一个队列中放元素,保
if (que1.empty())//向另外一个为空或者不为空的队列中放元素
que2.push(val);
else
que1.push(val);
}
T pop()
{
if (que1.empty() && que2.empty())
throw QTSEMPTY;
//首先不为空的队列一直pop到空的队列中直到最后一个为止,把最后一个元素pop给用户
T last;
Queue<T> *Full = que1.empty() ? &que2 : &que1;
Queue<T> *Empty = Full == &que1 ? &que2 : &que1;
//(除了最后一个元素)把非空的队列中的元素全部入队到另外一个队列
while (Full->size() != 1)
Empty->push(Full->pop());
return Full->pop();
}
};
int main()
{
//栈模拟队列测试代码
STQ<int> stq;
for (int i = 0; i < 20; i++)
{
int tmp = rand() % 100 + 1;
stq.push(tmp);
cout << tmp << " ";
}
cout << endl;
for (int i = 0; i < 20; i++)
cout << stq.pop() << " ";
cout << endl;
try {
cout << stq.pop() << endl;
}
catch (error_type e)
{
if(e == STQEMPTY)
cout << "the queue is empty\n" << endl;
}
//队列模拟栈测试代码
QTS<int> qts;
for (int i = 0; i < 20; i++)
{
int tmp = rand() % 100 + 1;
qts.push(tmp);
cout << tmp << " ";
}
cout << endl;
for (int i = 0; i < 20; i++)
cout << qts.pop() << " ";
cout << endl;
try {
cout << qts.pop() << endl;
}
catch (error_type e)
{
if (e == QTSEMPTY)
cout << "the stack is empty\n" << endl;
}
return 0;
}