[英]C++ default implementation of stack and queue
In C++ Primer 5th , it says that the default implementation of stack
and queue
is deque
. 在C ++ Primer 5th中 ,它表示stack
和queue
的默认实现是deque
。
I'm wondering why they don't use list
? 我想知道为什么他们不使用list
? Stack and Queue doesn't support random access, always operate on both ends, therefore list
should be the most intuitive way to implement them, and deque
, which support random access (with constant time) is somehow not necessary. 堆栈和队列不支持随机访问,总是在两端操作,因此list
应该是实现它们的最直观的方式,并且支持随机访问(具有恒定时间)的deque
在某种程度上是不必要的。
Could anyone explain the reason behind this implementation? 有谁能解释这个实施背后的原因?
With std::list
as underlying container each std::stack::push
does a memory allocation. 使用std::list
作为底层容器,每个std::stack::push
都进行内存分配。 Whereas std::deque
allocates memory in chunks and can reuse its spare capacity to avoid the memory allocation. 而std::deque
以块的形式分配内存,并且可以重用其备用容量来避免内存分配。
With small elements the storage overhead of list nodes can also become significant. 对于小元素,列表节点的存储开销也可能变得很重要。 Eg std::list<int>
node size is 24 bytes (on a 64-bit system), with only 4 bytes occupied by the element - at least 83% storage overhead. 例如, std::list<int>
节点大小为24字节(在64位系统上),元素只占用4个字节 - 至少83%的存储开销。
the main reason is because deque is faster than the list in average for front and back insertions and deletions 主要原因是因为前后插入和删除的deque比平均列表更快
deque is faster because memory is allocated by chunks were as list need allocation on each elements and allocation are costly operations. deque更快,因为内存是由块分配的,因为列表需要在每个元素上分配,并且分配是昂贵的操作。
I think the question should be asked the other way around: Why use a list if you can use an array? 我认为问题应该反过来问:如果你可以使用数组,为什么要使用列表?
The list is more complicated: More allocations, more resources (for storing pointers) and more work to do (even if it is all in constant time). 列表更复杂:更多的分配,更多的资源(用于存储指针)和更多的工作要做(即使它都是在恒定的时间)。 On the other hand, the main property for preferring lists is also not relevant to stacks and queues: constant-time random insertion and deletion. 另一方面,首选列表的主要属性也与堆栈和队列无关:恒定时间随机插入和删除。
Let's compare the sequence containers: 让我们比较一下序列容器:
std::array
is right out, it doesn't change size. std::array
是正确的,它不会改变大小。
std::list
optimises for iterator non-invalidation, allows insertion at known positions, and lacks random access. std::list
优化迭代器非失效,允许在已知位置插入,并且缺少随机访问。 It has O(N) space overhead, with a large constant, and it has bad cache locality. 它具有O(N)空间开销,具有大常量,并且具有错误的缓存局部性。
std::forward_list
is an even more crippled list
with smaller space overhead std::forward_list
是一个更加残缺的list
,空间开销更小
std::deque
optimises for appending or prepending, at the expense of not being contiguous. std::deque
优化附加或前置,但不以连续为代价。 It has O(N) space overhead, with a smaller constant, and it has mediocre cache locality. 它具有O(N)空间开销,具有较小的常量,并且具有中等缓存局部性。
std::vector
optimises for access speed, at the expense of insertion / removal anywhere but the end. std::vector
优化访问速度,代价是插入/删除除了结尾之外的任何地方。 It has O(1) space overhead, and the great cache locality. 它具有O(1)空间开销和很好的缓存局部性。
So what does this mean for stack and queue? 那么这对堆栈和队列意味着什么呢?
std::stack
only requires operations at one end. std::stack
只需要一端操作。 std::vector
, std::deque
and std::list
all provide the necessary operations std::vector
, std::deque
和std::list
都提供了必要的操作
std::queue
requires operations at both ends. std::queue
需要两端的操作。 std::deque
and std::list
are the only candidates. std::deque
和std::list
是唯一的候选人。
The choice of std::deque
as the default is then one of consistency, as std::vector
is generally better for std::stack
, but inapplicable for std::queue
. 因此std::deque
作为默认选择是一致的,因为std::vector
通常更适合std::stack
,但不适用于std::queue
。
Note that std::priority_queue
, whilst named similar to std::queue
, is actually more akin to std::stack
in requiring only modification at one end. 请注意, std::priority_queue
虽然命名类似于std::queue
,但实际上更类似于std::stack
,只需要在一端进行修改。 It also benefits more from the raw access speed of std::vector
, maintaining the heap invariant. 它还从std::vector
的原始访问速度中获益更多,保持堆不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.