[英]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.