[C++] STL相關面試題

orchid發表於2014-11-02

(1) 為何map和set的插入刪除效率比用其他序列容器高?

因為map和set的內部資料結構是紅黑樹,它的插入和刪除不需做記憶體的拷貝和移動。(紅黑樹的插入和刪除是log(n)的)。

(2) 為何每次insert之後,以前儲存的iterator不會失效?

iterator這裡就相當於指向節點的指標,記憶體沒有變,指向記憶體的指標怎麼會失效呢(當然被刪除的那個元素本身已經失效了)。相對於vector來說,每一次刪除和插入,指標都有可能失效,呼叫push_back在尾部插入也是如此。因為為了保證內部資料的連續存放,iterator指向的那塊記憶體在刪除和插入過程中可能已經被其他記憶體覆蓋或者記憶體已經被釋放了。即使時push_back的時候,容器內部空間可能不夠,需要一塊新的更大的記憶體,只有把以前的記憶體釋放,申請新的更大的記憶體,複製已有的資料元素到新的記憶體,最後把需要插入的元素放到最後,那麼以前的記憶體指標自然就不可用了。

(3) 向一個vector中新增N個元素,平均的新增的效能是?

看看下面程式碼的輸出:

vector<int> v;

for(int i=0;i<100;i++}

{

  cout << v.capacity() << endl;

  v.push_back(i);

}

可以看到空間的變化是0,1,2,4,8,16... (GCC下是如此,VC下不是..)

這個需要考慮到當空間不夠時,需要開闢新的記憶體並且發生元素的copy. 一般情況下開闢的空間是原來的2倍。那麼平均的新增時間是:(1+2+4+...+(N-logN))/N,也就是有logN個元素新增時需要整體挪動n次,其它的操作代價是1,平均下來依舊是O(N)。

(4) 如何理解容器介面卡,其與順序容器有什麼區別?

adapter原意是插座、介面卡、接合器的意思。現在我需要一個棧結構,我們可以用deque來模擬,只在一端進行元素插入和彈出,另一端不動。但deuqe畢竟不能直接作為一個stack,它並不能直接地嚴格地滿足你的要求,因為你不能防止別人在另一端亂動你的東西。你需要對它進行一些包裝,作一些限制,使之只能在一端進行插入和刪除。也就是說你必須提供一個“插座”,這個“插座”一端插在deque上,另一端插在你的程式中,你就可以使用棧結構了。而stack就是這樣的“插座”,它連線了deque和你的程式。表面上看你使用的是stack,實際上你是通過stack這個“插座”來使用deque(因為stack完全是用deque來實現的,它並沒有任何其他的東西,它只是在deque上面作了一層包裝,相當於一個“插座”的功能)。因此,stack、queue、priority_queue這樣的類一般稱為容器介面卡,它們只是基本容器型別(vector,dequeue,list)的適配。
  實際上,這也介面卡模式的基本思想:將一個類的介面轉換成客戶希望的另外一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。也就是說,在一個類的介面上提供一個“插座”類,使它變成你希望使用的介面。

 

相關文章