提示:熟悉栈和队列基础,利用栈实现队列,利用队列实现栈
一、题目分析
STL容器知识补充:
顺序容器:可变长动态数组 vector、双端队列 deque、双向链表 list。
关联容器:set、multiset、map、multimap
容器适配器:栈stack、队列queue、优先级队列priority_queue
栈:先进后出
概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口
构造函数:
stack stk; //stack采用模板类实现, stack对象的默认构造形式
stack(const stack &stk); //拷贝构造函数
赋值操作:
stack& operator=(const stack &stk); //重载等号操作符
数据存取:
push(elem); //向栈顶添加元素
pop(); //从栈顶移除第一个元素
top(); //返回栈顶元素
大小操作:
empty(); //判断堆栈是否为空
size(); //返回栈的大小
队列:先进先出
概念:Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口,队列容器允许从一端新增元素,从另一端移除元素
构造函数:
queue que; //queue采用模板类实现,queue对象的默认构造形式
queue(const queue &que); //拷贝构造函数
赋值操作:
queue& operator=(const queue &que); //重载等号操作符
数据存取:
push(elem); //往队尾添加元素
pop(); //从队头移除第一个元素
back(); //返回最后一个元素
front(); //返回第一个元素
大小操作:
empty(); //判断堆栈是否为空
size(); //返回栈的大小
利用栈实现队列
使用栈实现队列的下列操作:
push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。
思路分析
利用两个栈来实现队列,一个输入栈模拟队列输入,一个输出栈模拟队列输出。
在push数据的时候,只要数据放进输入栈就好,
但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
队列的首部元素即为自定义的队列的pop()元素
最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。
利用队列实现栈
使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
思路分析
用上面的思路无法进行,因为队列再多,先进先出则使所有的队列都是一样的,
但这里仍然使用两个队列,另一队列用来备份非弹出数据
大概就是每次将原队列弹出只剩末尾一个元素,这个元素就是待弹出元素,然后将该元素之前的数据都存在备份队列中,当最后一个元素弹出后,将备份队列的数据重新赋给原队列
栈顶元素即队列的末尾元素
栈是否为空可通过原队列是否为空判断
二、代码实现
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
class myQueue {
stack<int> stIn;
stack<int> stOut;
public:
//队列入队
void push(int val) {
stIn.push(val);
}
//队列出队
int pop() {
if (this->empty()) {
cout << "队列已空,无法出队" << endl;
return 0;
}
if (stOut.empty()) {
while (!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
//返回队列首部元素
int peek() {
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
//判断队列是否为空
bool empty() {
return stIn.empty() && stOut.empty();
}
};
class myStack{
queue<int> que1;
queue<int> que2; //备份队列
public:
//入栈
void push(int val) {
que1.push(val);
}
//出栈
int pop() {
int size = que1.size() - 1;
while (size--) {
que2.push(que1.front());
que1.pop();
}
int result = que1.front();
que1.pop();
que1 = que2;
while (!que2.empty()) {
que2.pop();
}
return result;
}
//栈头部
int peek() {
return que1.back();
}
//栈是否为空
bool empty() {
return que1.empty();
}
};
//测试代码
int main(){
int n;
cin >> n;
//测试
//myQueue test;
myStack test;
for (int i = 0; i < n; i++) {
test.push(i);
cout << i << " ";
}
cout << endl;
while (!test.empty()) {
int tmp = test.pop();
cout << tmp << " ";
}
cout << endl;
test.push(n);
test.push(n + 1);
int top = test.peek();
cout << top << endl;
system("pause");
return 0;
}
三、总结
这里用栈实现队列,以及用队列实现栈,主要是为了熟悉栈和队列的结构和区别,加深对栈和队列的认识。