deque文档
stack文档
deque文档
文章目录
- 🍅1. deque容器
- 🍒deque底层
- 🍒deque的优势
- 🍒deque的劣势
- 🫐2. stack模拟实现
- 🥝3. queue模拟实现
🍅1. deque容器
查看文档可发现,栈和队列都采用的是容器适配器,如果不指定,则默认为deque
这个容器
🍒deque底层
我们来看一下deque
容器的配置:
这个deque
的功能十分齐全,相比vector
,支持头插头删;相比list
,它可以用[]
访问,看起来是一个非常棒的结构,那为何在平时不常见呢?
我们先来看一下deque
的底层结构:
deque
底层类似一个动态的二维数组,定义一个中控器,从中间开始指向对于的内存空间,这样就十分便于头插头删、尾插尾删,但这对于迭代器设计,也就比较复杂。
🍒deque的优势
deque
这样的设计,十分适用于需要频繁头插头删、尾插尾删的地方。
所以库里面就采用了deque
作为了stack
和queue
的适配器,stack
和queue
不需要遍历(没有迭代器),所以使用deque
作为适配器,效率高、内存效率也高
🍒deque的劣势
deque
有一个致命的缺陷,就是不便于遍历,每次遍历都十分麻烦,需要频繁检查某段空间的边界,这导致访问的开销十分之大。
如果在指定位置插入数据,计算十分繁琐,相当的头疼。
一百万个随机数据排序速度对比:
这里发现vector
的效率是明显高于list
和deque
的,因为vector
的存储空间是连续的,缓存命中率高于list
和deque
🫐2. stack模拟实现
STL库里面采用的容器适配器,那就不需要手搓轮子了
namespace mystack
{
template<class T, class Container = deque<T>>
class stack
{
public:
bool empty() const
{
return _con.empty();
}
size_t size() const
{
return _con.size();
}
T& top()
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
private:
Container _con;
};
}
🥝3. queue模拟实现
namespace myqueue
{
template<class T,class Container = deque<T>>
class queue
{
public:
bool empty() const
{
return _con.empty();
}
size_t size() const
{
return _con.size();
}
T& front()
{
return _con.front();
}
T& back()
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_front();
}
private:
Container _con;
};
}
Tips:
stack
是LIFO(后进先出)可以采用vector
或者是list
,因为vector
和list
都有头尾插入删除操作而对于
queue
是FIFO(先进先出),vector
不支持头插头删操作,所以并不适配queue
,STL库里面也没有这样支持
那本期分享就到这里咯,我们下期再见,如果还有下期的话。