面試總結3--STL問題

1、 爲何mapset的插入刪除效率比用其他序列容器高?

 因爲對於關聯容器來說,不需要做內存拷貝和內存移動。說對了,確實如此。map和set容器內所有元素都是以節點的方式來存儲,其節點結構和鏈表差不多,指向父節點和子節點。因此插入的時候只需要稍做變換,把節點的指針指向新的節點就可以了。刪除的時候類似,稍做變換後把指向刪除節點的指針指向其他節點就OK了。這裏的一切操作就是指針換來換去,和內存移動沒有關係。


2爲何每次insert之後,以前保存的iterator不會失效?

iterator這裏就相當於指向節點的指針,內存沒有變,指向內存的指針怎麼會失效呢(當然被刪除的那個元素本身已經失效了)。相對於vector來說,每一次刪除和插入,指針都有可能失效,調用push_back在尾部插入也是如此。因爲爲了保證內部數據的連續存放,iterator指向的那塊內存在刪除和插入過程中可能已經被其他內存覆蓋或者內存已經被釋放了。即使時push_back的時候,容器內部空間可能不夠,需要一塊新的更大的內存,只有把以前的內存釋放,申請新的更大的內存,複製已有的數據元素到新的內存,最後把需要插入的元素放到最後,那麼以前的內存指針自然就不可用了。特別時在和find等算法在一起使用的時候,牢記這個原則:不要使用過期的iterator。


3、爲何map和set不能像vector一樣有個reserve函數來預分配數據?

引起它的原因在於在map和set內部存儲的已經不是元素本身了,而是包含元素的節點。也就是說map內部使用的Alloc並不是map<Key, Data, Compare, Alloc>聲明的時候從參數中傳入的Alloc。例如:map<int, int, less<int>, Alloc<int> > set、map;這時候在set、map中使用的allocator並不是Alloc<int>, 而是通過了轉換的Alloc,具體轉換的方法時在內部通過Alloc<int>::rebind重新定義了新的節點分配器,詳細的實現參看徹底學習STL中的Allocator。其實你就記住一點,在map和set內面的分配器已經發生了變化,reserve方法你就不要奢望了。


4hash_mapmap的區別在哪裏?什麼時候需要用hash_map,什麼時候需要用map?

構造函數。hash_map需要hash函數,等於函數;map只需要比較函數(小於函數).

存儲結構。hash_map採用hash表存儲,map一般採用 紅黑樹(RB Tree) 實現。因此其memory數據結構是不一樣的。

總體來說,hash_map 查找速度會比map快,而且查找速度基本和數據數據量大小,屬於常數級別;map的查找速度是log(n)級別。並不一定常數就比log(n)小,hash還有hash函數的耗時,明白了吧,如果你考慮效率,特別是在元素達到一定數量級時,考慮考慮hash_map。但若你對內存使用特別嚴格,希望程序儘可能少消耗內存,那麼一定要小心,hash_map可能會讓你陷入尷尬,特別是當你的hash_map對象特別多時,你就更無法控制了,而且hash_map的構造速度較慢

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章