用栈实现队列
问题分析
用栈实现队列等价于 "后进先出" 的特性实现 "先进先出" 的特性!
解决方案设计
实现思路
准备两个栈用于实现队列: stack_in 和 stack_out
- 当有新元素入队时:将其压入 stack_in
当需要出队时:
- stack_out() == 0 :
- 将 stack_in 中的元素逐一弹出并压入 stack_out
stack_out.size() > 0 :
- 将 stack_out 的栈顶元素弹出
编程实验:用栈实现队列
文件:StackToQueue.h
#include <iostream>
#include "LinkStack.h"
#include "Queue.h"
using namespace std;
using namespace DTLib;
template <typename T>
class StackToQueue : public Queue<T>
{
public:
void add(const T &e) override // O(1)
{
m_stack_in.push(e);
}
void remove() override // O(n)
{
move();
if (m_stack_out.size() > 0)
{
m_stack_out.pop();
}
else
{
THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StackToQueue ...");
}
}
T front() const override // O(n)
{
move();
if (m_stack_out.size() > 0)
{
return m_stack_out.top();
}
else
{
THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StackToQueue ...");
}
}
void clear() override // O(n)
{
m_stack_in.clear();
m_stack_out.clear();
}
int length() const override // O(1)
{
return m_stack_in.size() + m_stack_out.size();
}
~StackToQueue() override // O(n)
{
clear();
}
protected:
mutable LinkStack<T> m_stack_in;
mutable LinkStack<T> m_stack_out;
void move() const // O(n)
{
if (m_stack_out.size() == 0)
{
while (m_stack_in.size() > 0)
{
m_stack_out.push(m_stack_in.top());
m_stack_in.pop();
}
}
}
};
int main()
{
StackToQueue<int> sq;
for (int i=0; i<5; ++i)
{
sq.add(i);
}
while (sq.length() > 0)
{
cout << sq.front() << endl;
sq.remove();
}
return 0;
}
输出:
0
1
2
3
4
队列实现栈
问题分析
本质为,用队列 "先进先出"的特性实现栈 "后进先出" 的特性!
解决方案设计
实现思路
准备两个队列用于实现栈:queue_1[in] 和 queue_2[out]
- 当有新元素入栈时:将其加入队列[in]
当需要出栈时:
- 将队列[in]中的 n-1 个元素出队列,并进入队列[out]中
- 将队列[int]中的最后一个元素出队列(出栈)
- 交换两个队列的角色: queue_1[out] 和 queue_2[int]
编程实验:用队列实现栈
文件:QueueToStack.h
#include <iostream>
#include "LinkQueue.h"
#include "Stack.h"
using namespace std;
using namespace DTLib;
template <typename T>
class QueueToStack : public Stack<T>
{
public:
QueueToStack() // O(1)
{
m_pIn = &m_queue_1;
m_pOut = &m_queue_2;
}
void push(const T &e) override // O(1)
{
m_pIn->add(e);
}
void pop() override // O(n)
{
if (m_pIn->length() > 0)
{
move();
m_pIn->remove();
swap();
}
else
{
THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current QueueToStack ...");
}
}
T top() const override // O(n)
{
if (m_pIn->length() > 0)
{
move();
return m_pIn->front();
}
else
{
THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current QueueToStack ...");
}
}
void clear() override // O(n)
{
m_queue_1.clear();
m_queue_2.clear();
}
int size() const override // O(1)
{
return m_queue_1.length() + m_queue_2.length();
}
protected:
LinkQueue<T> m_queue_1;
LinkQueue<T> m_queue_2;
LinkQueue<T> *m_pIn;
LinkQueue<T> *m_pOut;
void move() const // O(n)
{
int n = m_pIn->length() - 1;
for (int i=0; i<n; ++i)
{
m_pOut->add(m_pIn->front());
m_pIn->remove();
}
}
void swap() // O(1)
{
LinkQueue<T> *temp = nullptr;
temp = m_pIn;
m_pIn = m_pOut;
m_pOut = temp;
}
};
int main()
{
QueueToStack<int> qs;
for (int i=0; i<5; ++i)
{
qs.push(i);
}
while (qs.size() > 0)
{
cout << qs.top() << endl;
qs.pop();
}
return 0;
}
文件:main.cpp
4
3
2
1
0
小结
- 栈和队列在实现上非常相似,可以相互转化实现
- 两个栈 "先进后出" 相互配合得到 "先进先出" 的特性
- 两个对垒 "先进先出" 相互配合得到 "后进先出" 的特性
- 栈和队列相互转化的学习有助于强化本质的理解
以上内容整理于狄泰软件学院系列课程,请大家保护原创!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。