[英]C++ default implementation of stack and queue
在C ++ Primer 5th中 ,它表示stack
和queue
的默认实现是deque
。
我想知道为什么他们不使用list
? 堆栈和队列不支持随机访问,总是在两端操作,因此list
应该是实现它们的最直观的方式,并且支持随机访问(具有恒定时间)的deque
在某种程度上是不必要的。
有谁能解释这个实施背后的原因?
使用std::list
作为底层容器,每个std::stack::push
都进行内存分配。 而std::deque
以块的形式分配内存,并且可以重用其备用容量来避免内存分配。
对于小元素,列表节点的存储开销也可能变得很重要。 例如, std::list<int>
节点大小为24字节(在64位系统上),元素只占用4个字节 - 至少83%的存储开销。
我认为问题应该反过来问:如果你可以使用数组,为什么要使用列表?
列表更复杂:更多的分配,更多的资源(用于存储指针)和更多的工作要做(即使它都是在恒定的时间)。 另一方面,首选列表的主要属性也与堆栈和队列无关:恒定时间随机插入和删除。
让我们比较一下序列容器:
std::array
是正确的,它不会改变大小。
std::list
优化迭代器非失效,允许在已知位置插入,并且缺少随机访问。 它具有O(N)空间开销,具有大常量,并且具有错误的缓存局部性。
std::forward_list
是一个更加残缺的list
,空间开销更小
std::deque
优化附加或前置,但不以连续为代价。 它具有O(N)空间开销,具有较小的常量,并且具有中等缓存局部性。
std::vector
优化访问速度,代价是插入/删除除了结尾之外的任何地方。 它具有O(1)空间开销和很好的缓存局部性。
那么这对堆栈和队列意味着什么呢?
std::stack
只需要一端操作。 std::vector
, std::deque
和std::list
都提供了必要的操作
std::queue
需要两端的操作。 std::deque
和std::list
是唯一的候选人。
因此std::deque
作为默认选择是一致的,因为std::vector
通常更适合std::stack
,但不适用于std::queue
。
请注意, std::priority_queue
虽然命名类似于std::queue
,但实际上更类似于std::stack
,只需要在一端进行修改。 它还从std::vector
的原始访问速度中获益更多,保持堆不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.