适配器模式:用已有的东西封装转换出我们想要的东西。
迭代器模式:不暴露底层实现细节,封装后提供统一方式访问容器。
#include<vector>
#include<list>
namespace rhl
{
template <class T, class Container = vector<T>>
class stack
{
public:
void push_back(const T& x)
{
_con.push_back(x);
}
void pop()
{
_con.pop_back();
}
const T& top()
{
return _con.back();
}
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
private:
Container _con;
};
}
#include <iostream>
using namespace std;
#include<deque>
#include "stack.h"
//#include "Queue.h"
int main()
{
rhl::stack<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
//d.push_front(10);+
//d.push_front(20);
while (!d.empty())
{
cout << d.top() << endl;
d.pop();
}
return 0;
}
stack的容器为什么缺省值是deque?
deque叫双端队列,但不是真的队列,它兼具vector和list的优点。
举个例子
#pragma once
#include<vector>
#include <list>
namespace bit
{
//template<class T, class Container = list<T>>
template<class T, class Container = deque<T>>
class queue
{
public:
void push(const T& x)
{
_con.push_back(x);
}
void pop()
{
_con.pop_front();
}
const T& front()
{
return _con.front();
}
const T& back()
{
return _con.back();
}
bool empty()
{
return _con.empty();
}
size_t size()
{
return _con.size();
}
private:
Container _con;
};
}
#include <iostream>
using namespace std;
#include<deque>
#include "Stack.h"
#include "Queue.h"
int main()
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_front(10);
d.push_front(20);
for (size_t i = 0; i < d.size(); ++i)
{
cout << d[i] << " ";
}
cout << endl;
return 0;
}
deque底层是小段小段的数组,叫buffer,一般由多个buffer数组构成。有一个中控指针数组,存放每一个buffer的指针,每一个buffer存满后,就开辟新的buffer。
如果要头插数据,就在第一个buffer前面新开辟buffer,并在新buffer的末尾插入数据。
deque随机查找效率较低,如果要随机查找,在第一个buffer中没有找到,就把要查找的第n个数字,的n减去第一个buffer中的数据个数,然后在第二个buffer中查找。
deque下标随机访问,有一定消耗,没有vector快。
中间插入删除也是需要挪动数据的,消耗也较大。相比list的中间插入删除不够快。
但是deque适合作stack和queue的默认容器。
中间插入删除少,头尾插入删除多的情况适合用deque 。
如果要排序的话,如果有头插头删比较频繁,对效率要求不算太高的话可以考虑用deque。