在 C ++ Primer 5th 中,它表示stack
和queue
的默认实现是deque
。
我想知道为什么他们不使用list
? Stack and Queue不支持随机访问,总是在两端都运行,因此list
应该是实现它们的最直观的方式,而deque
支持随机访问(具有固定时间)没必要。
任何人都可以解释这种实现背后的原因吗?
答案 0 :(得分:10)
使用std::list
作为基础容器,每个std::stack::push
进行内存分配。 std::deque
会按块分配内存,并且可以重用其备用容量以避免内存分配。
使用小元素,列表节点的存储开销也可能变得很大。例如。 std::list<int>
节点大小为24个字节(在64位系统上),元素仅占用4个字节-至少有83%的存储开销。
答案 1 :(得分:4)
答案 2 :(得分:4)
我认为应该反过来问:如果可以使用数组,为什么要使用列表?
该列表更加复杂:更多的分配,更多的资源(用于存储指针)和更多的工作(即使都是固定的时间)。另一方面,首选列表的主要属性也与堆栈和队列无关:恒定时间随机插入和删除。
答案 3 :(得分:0)
让我们比较序列容器:
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
的原始访问速度,从而使堆保持不变。