1.前言
和stack一样,队列也没有把他放在容器的一栏里面,而是把他放在容器适配器的一栏。这也是因为queue是使用了别人的相关接口,空间然后来封装自己的内容,最后再给上层用户使用。
2.队列
队列的性质就是先进先出,他只能从队列的一端加入,另一端取出
队列定义的方式
方式一:使用默认的适配器来定义队列
queue<int> q;
方式二:使用特定的适配器来进行定义队列
queue<int,vector<int>> q;
queue<int,list<int>> q;
PS:这里为什么能够使用vector和list来做队列的适配器呢?
queue是先进先出的特殊线性数据结构,只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如vector 和list。
但是STL中对stack和 queue默认选择deque作为其底层容器,主要是因为:
1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
2. 在stack和queue中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。
结合了deque的优点,而完美的避开了其缺陷。
queue函数的常见接口
#include <iostream>
#include <list>
#include <queue>
using namespace std;
int main()
{
queue<int, list<int>> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
cout << q.size() << endl; //4
while (!q.empty())
{
cout << q.front() << " ";
q.pop();
}
cout << endl; //1 2 3 4
return 0;
}
3.队列的模拟实现
queue.h如下:
#pragma once
#include <iostream>
#include <queue>
using namespace std;
namespace njust
{
template<class T,class Container=std::deque<T>>
class Queue
{
public:
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
T& front()
{
return _con.front();
}
T& back()
{
return _con.back();
}
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
void Swap(Queue<T, Container>& lt)
{
_con.swap(lt._con);
}
private:
Container _con;
};
}
4.总结
队列的模拟实现比较简单,因为他是直接使用别人封装好的东西,来充实自己。这样就是说不用自己去造一个轮子,而是把别人的造好轮子直接拿过来改改,然后改出自己想要的轮子,就好了。