轉載 C++ STL 幾個容器的底層實現

C++ STL 的實現:
 
1.vector      底層數據結構爲數組 ,支持快速隨機訪問
 
2.list            底層數據結構爲雙向鏈表,支持快速增刪
 
3.deque       底層數據結構爲一箇中央控制器和多個緩衝區,詳細見STL源碼剖析P146,支持首尾(中間不能)快速增刪,也支持隨機訪問
deque是一個雙端隊列(double-ended queue),也是在堆中保存內容的.它的保存形式以下:
[堆1] --> [堆2] -->[堆3] --> ...
每一個堆保存好幾個元素,而後堆和堆之間有指針指向,看起來像是list和vector的結合品.
 
4.stack        底層通常用list或deque實現,封閉頭部便可,不用vector的緣由應該是容量大小有限制,擴容耗時
 
5.queue     底層通常用list或deque實現,封閉頭部便可,不用vector的緣由應該是容量大小有限制,擴容耗時
 
(stack和queue實際上是適配器,而不叫容器,由於是對容器的再封裝)
 
6.priority_queue     的底層數據結構通常爲vector爲底層容器,堆heap爲處理規則來管理底層容器實現
 
7.set                   底層數據結構爲紅黑樹,有序,不重複
 
8.multiset         底層數據結構爲紅黑樹,有序,可重複 
 
9.map                底層數據結構爲紅黑樹,有序,不重複
 
10.multimap    底層數據結構爲紅黑樹,有序,可重複
 
11.hash_set     底層數據結構爲hash表,無序,不重複
 
12.hash_multiset 底層數據結構爲hash表,無序,可重複 
 
13.hash_map    底層數據結構爲hash表,無序,不重複
 
14.hash_multimap 底層數據結構爲hash表,無序,可重複 
http://www.cnblogs.com/hustlijian/p/3611424.html
------------------------------------------------------------------------------------------------------------------------------------------

stl容器區別: vector list deque set map-底層實現

stl容器區別: vector list deque set map (轉)html

在STL中基本容器有: vector、list、deque、set、map前端

set 和map都是無序的保存元素,只能經過它提供的接口對裏面的元素進行訪問數組

set:集合, 用來判斷某一個元素是否是在一個組裏面,使用的比較少
map:映射,至關於字典,把一個值映射成另外一個值,若是想建立字典的話使用它好了
底層採用的是樹型結構,多數使用平衡二叉樹實現,查找某一值是常數時間,遍歷起來效果也不錯, 只是每次插入值的時候,會從新構成底層的平衡二叉樹,效率有必定影響.數據結構

vector、list、deque是有序容器
1.vector
vector就是動態數組.它也是在堆中分配內存,元素連續存放,有保留內存,若是減小大小後,內存也不會釋放.若是新值>當前大小時纔會再分配內存.post

它擁有一段連續的內存空間,而且起始地址不變,所以它能很是好的支持隨即存取,即[]操做符,但因爲它的內存空間是連續的,因此在中間進行插入和刪除會形成內存塊的拷貝,另外,當該數組後的內存空間不夠時,須要從新申請一塊足夠大的內存並進行內存的拷貝。這些都大大影響了vector的效率。

對最後元素操做最快(在後面添加刪除最快 ), 此時通常不須要移動內存,只有保留內存不夠時才須要性能

 

對中間和開始處進行添加刪除元素操做須要移動內存,若是你的元素是結構或是類,那麼移動的同時還會進行構造和析構操做,因此性能不高 (最好將結構或類的指針放入vector中,而不是結構或類自己,這樣能夠避免移動時的構造與析構)。
訪問方面,對任何元素的訪問都是O(1),也就是是常數的,因此vector經常使用來保存須要常常進行隨機訪問的內容,而且不須要常常對中間元素進行添加刪除操做.測試

相比較能夠看到vector的屬性與string差很少,一樣可使用capacity看當前保留的內存,使用swap來減小它使用的內存.url

capacity()返回vector所能容納的元素數量(在不從新分配內存的狀況下)      測試push_back  1000個數據  capacity返回16384

 

總結
須要常常隨機訪問請用vector.net

2.list
list就是雙向鏈表,元素也是在堆中存放,每一個元素都是放在一塊內存中,它的內存空間能夠是不連續的,經過指針來進行數據的訪問,這個特色使得它的隨機存取變的很是沒有效率,所以它沒有提供[]操做符的重載。但因爲鏈表的特色,它能夠以很好的效率支持任意地方的刪除和插入。指針

list沒有空間預留習慣,因此每分配一個元素都會從內存中分配,每刪除一個元素都會釋放它佔用的內存.

list在哪裏添加刪除元素性能都很高,不須要移動內存,固然也不須要對每一個元素都進行構造與析構了,因此經常使用來作隨機操做容器.
可是訪問list裏面的元素時就開始和最後訪問最快
訪問其它元素都是O(n) ,因此若是須要常常隨機訪問的話,仍是使用其它的好

總結
若是你喜歡常常添加刪除大對象的話,那麼請使用list
要保存的對象不大,構造與析構操做不復雜,那麼可使用vector代替
list<指針>徹底是性能最低的作法,這種狀況下仍是使用vector<指針>好,由於指針沒有構造與析構,也不佔用很大內存

3.deque
deque是一個雙端隊列(double-ended queue),也是在堆中保存內容的.它的保存形式以下:
[堆1]
...
[堆2]
...
[堆3]
每一個堆保存好幾個元素,而後堆和堆之間有指針指向,看起來像是list和vector的結合品.

它支持[]操做符,也就是支持隨即存取,可讓你在前面快速地添加刪除元素,或是在後面快速地添加刪除元素,而後還能夠有比較高的隨機訪問速度,和vector的效率相差無幾,它支持在兩端的操做:push_back,push_front,pop_back,pop_front等,而且在兩端操做上與list的效率也差很少。
在標準庫中vector和deque提供幾乎相同的接口,在結構上它們的區別主要在於這兩種容器在組織內存上不同,deque是按頁或塊來分配存儲器的,每頁包含固定數目的元素.相反vector分配一段連續的內存,vector只是在序列的尾段插入元素時纔有效率,而deque的分頁組織方式即便在容器的前端也能夠提供常數時間的insert和erase操做,並且在體積增加方面也比vector更具備效率

總結:
vector是能夠快速地在最後添加刪除元素,並能夠快速地訪問任意元素
list是能夠快速地在全部地方添加刪除元素,可是隻能快速地訪問最開始與最後的元素
deque在開始和最後添加元素都同樣快,並提供了隨機訪問方法,像vector同樣使用[]訪問任意元素,可是隨機訪問速度比不上vector快,由於它要內部處理堆跳轉
deque也有保留空間.另外,因爲deque不要求連續空間,因此能夠保存的元素比vector更大,這點也要注意一下.還有就是在前面和後面添加元素時都不須要移動其它塊的元素,因此性能也很高。

所以在實際使用時,如何選擇這三個容器中哪個,應根據你的須要而定,通常應遵循下面
的原則:
一、若是你須要高效的隨即存取,而不在意插入和刪除的效率,使用vector
二、若是你須要大量的插入和刪除,而不關心隨即存取,則應使用list
三、若是你須要隨即存取,並且關心兩端數據的插入和刪除,則應使用deque。

原文出處http://hi.baidu.com/zhouhq_926/blog/item/b1ee859762cc426754fb9665.html

相關文章
相關標籤/搜索