某日二師兄參加XXX科技公司的C++工程師開發崗位第26面: > 面試官:`deque`用過嗎? > > 二師兄:說實話,很少用,基本沒用過。 > > 面試官:為什麼? > > 二師兄:因為使用它的場景很少,大部分需要性能、且需要自動擴容的時候使用`vector`,需要隨機插入和刪除的時候可以使用` ...
某日二師兄參加XXX科技公司的C++工程師開發崗位第26面:
面試官:
deque
用過嗎?二師兄:說實話,很少用,基本沒用過。
面試官:為什麼?
二師兄:因為使用它的場景很少,大部分需要性能、且需要自動擴容的時候使用
vector
,需要隨機插入和刪除的時候可以使用list
。面試官:那你知道STL中的
stack
是如何實現的嗎?二師兄:預設情況下,
stack
使用deque
作為其底層容器,但也可以使用vector
或list
作為底層容器。面試官:你覺得為什麼STL中預設使用
deque
作為stack
的底層容器嗎?二師兄:額。。(
stack
也不需要雙端插入啊,不應該vector
更好嗎。。)不是很清楚。。面試官:沒關係。那你知道
deque
是如何實現的嗎?二師兄:與
vector
記憶體空間連續不同,deque
是部分連續的。deque
通常維護了一個map
(不是std::map
),map
的每個元素指向一個固定大小的chunk
。同時維護了兩個指針,指向頭chunk
和尾chunk
。在deque
的頭部或尾部插入元素時,deque
會找到頭部或尾部的指針,並通過指針找到對應的chunk
。如果chunk
中還有未被元素填充的位置,則將元素填充到數組中,如果此指針指向的chunk
已經被元素填滿,則需要重新開闢一塊固定大小的chunk
,並將chunk
記錄在map
中。
面試官:
deque
的查找、插入、刪除的時間複雜度是什麼?二師兄:
dqueue
查找的時間複雜度是O(N)
,插入要分情況,如果是頭插和尾插,時間複雜度為O(1)
,如果是中間插入,則是O(N)
。刪除元素和插入元素的時間複雜度相同。面試官:好的。面試結束,回去等通知吧。
讓我們來看一下二師兄的表現:
為什麼STL中預設使用
deque
作為stack
的底層容器嗎?
STL預設選擇deque
最為stack
的底層容器肯定是有原因的。vector
和list
同樣可以作為deque
的底層容器,讓我們比較一下三個容器的差異:(只考慮頭插和尾插,因為stack不需要隨機插入)
deque | vector | list | |
---|---|---|---|
插入 | O(1) | O(1) | O(1) |
刪除 | O(1) | O(1) | O(1) |
從上表中看到,三種容器的插入和是刪除的時間複雜度相同。
但是如果連續插入時,情況發生變化。vector
的capacity
被耗盡,元素髮生搬移。
list
倒沒有這個顧慮,但是當元素尺寸很小時,list
的空間利用率太低。
deque
雖然遍歷效率不如vector
、隨機插入效率不然list
,但stack
並不需要這兩種操作,所以deque
是stack
底層容器的最佳選擇。
今天的面試分享到這裡就結束了,讓我們繼續期待二師兄的表現吧。
關註我,帶你21天“精通”C++!(狗頭)