目录
容器比较
vector和list
stack和queue称为容器适配器,可以用容器进行适配。
三种容器:vector,list,deque,下面对他们进行比较。
vector优点:下标随机访问,cpu高速缓存命中率高。
vector缺点:扩容代价大,需要拷贝数据;二倍增容有空间浪费;随机插入删除效率低。
因此,使用vector适配stack比较理想。
list优点:按需申请释放空间;支持任意位置O(1)插入删除。
list缺点:不支持随机访问,cpu高速缓存命中率低。
因此,使用list适配queue比较理想。
总结:vector和list各有缺点,但他们是优缺互补的。
deque
deque称为双端队列,支持任意位置插入删除和随机访问,这么一说,deque融合了vector和list的优点,所以它更适合做stack和queue的容器。
deque每次扩容开辟一小段空间,由中控数组进行管理,头插头删,尾插尾删效率高,当小段空间内数据删除完毕后,会将这一小段空间直接释放,所以空间浪费少,但是它的随机访问需要进行计算,寻找位置。
deque和vector
deque对比vector优点:扩容代价小,不需要拷贝数据;空间浪费少。
deque对比vector缺点:随机访问需要计算位置,高频随机访问不如vector。
deque和list
deque对比list优点:空间相对集中,cpu高速缓存命中率高;一次开一小段空间,不用频繁申请,所以效率高。
deque对比list缺点:中间段插入删除效率低。
总结
deque适合头尾插入删除和随机访问,因此它作为stack和queue的容器是完胜的。
但是它高频随机访问不如vector,任意位置插入删除不如list,所以它不能取代vector和list的王位。
stack模拟实现
使用容器适配,所以stack和queue的函数可以直接调用容器的成员函数。
template<class T, class Container = deque<T>>
class stack
{
public:
bool empty()const
{
return _con.empty();
}
const T& top()const
{
return _con.back();
}
size_t size()const
{
return _con.size();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
private:
Container _con;
};
queue模拟实现
template<class T, class Container = deque<T>>
class queue
{
public:
bool empty()const
{
return _con.empty();
}
T& front()
{
return _con.front();
}
const T& front()const
{
return _con.front();
}
T& back()
{
return _con.back();
}
const T& back()const
{
return _con.back();
}
size_t size()const
{
return _con.size();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
private:
Container _con;
};