C++中的容器類

君若隱發表於2020-10-07

順序容器

vector的特點

(1)指定一塊如同陣列一樣的連續儲存,但空間可以動態擴充套件。即它可以像陣列一樣操作,並且可以進行動態操作。通常體現在push_back()和pop_back()。

(2)隨機訪問方便,它像陣列一樣被訪問。

(3)節省空間,因為它是連續儲存,在儲存資料的區域都是沒有被浪費的,但是要明確一點:vector大多情況下並不是滿存的,在未儲存的區域實際是浪費的。

(4)在內部進行插入、刪除操作效率非常低,這樣的操作基本上是被禁止的。vector被設計成只能在後端進行追加和刪除操作,其原因是vector內部的實現是按照順序表的原理。

(5)只能在vector的最後進行push和pop,不能在vector的頭進行push和pop。

(6)當動態新增的資料超過vector預設分配的大小時要進行記憶體的重新分配、拷貝與釋放,這個操作非常消耗效能。所以要vector達到最優的效能,最好在建立vector時就指定其空間大小

list的特點

(1)不使用連續的記憶體空間,這樣可以隨意地進行動態操作。

(2)可以在內部任何位置快速地插入或刪除,當然也可以在兩端進行push和pop。

(3)不能進行內部的隨機訪問。

(4)相對於vector佔用更多的記憶體。

deque的特點

(1)隨機訪問方便,即支援[ ]操作符,但效能沒有vector好。

(2)可以在內部進行插入和刪除操作,但效能不及list。

(3)可以在兩端進行push和pop。

三者的比較

vector是一段連續的記憶體塊,而deque是多個連續的記憶體塊,list是所有資料元素分開儲存,可以是任何兩個元素沒有連續。vector的查詢效能最好,並且在末端增加資料的效能也很好,除非它重新申請記憶體段;適合高效地隨機儲存。list是一個連結串列,任何一個元素都可以是不連續的,但它都有兩個指向上一元素和下一元素的指標。所以它對插入、刪除元素效能是最好的,而查詢效能非常差;適合大量地插入和刪除操作而不關心隨機存取的需求。deque是介於兩者之間,它兼顧了陣列和連結串列的優點,它是分塊的連結串列和多個陣列的聯合。所以它有比list更好的查詢效能,有比vector更好的插入和刪除效能。如果使用者需要隨機存取又關心兩端資料的插入和刪除,那麼deque是最佳之選。

關聯容器

關聯容器之間的差別

(1)set又稱集合,實際上就是一組元素的集合,但其中所包含的元素的值是唯一的,且是按一定順序排列的,集合中的每個元素被稱作集合中的例項。因為其內部是通過連結串列的方式來組織,所以在插入的時候比vector快,但在查詢和末尾新增資料時比vector慢。

(2)multiset是多重集合,其實現方式和set是相似的,只是它不要求集合中的元素是唯一的,也就是說集合中的同一個元素可以出現多次。

(3)map提供一種“鍵-值”關係的一對一的資料儲存能力。其“鍵”在容器中不可重複,且按一定順序排列。由於其是按連結串列的方式儲存,它也繼承了連結串列的優缺點。

(4)multimap和map的原理基本相似,它允許“鍵”在容器中可以不唯一。

關聯容器的特點

(1)其內部實現是採用非線性的二叉樹結構,具體地說是以紅黑樹的結構原理實現的。

(2)set和map保證了元素的唯一性,mulset和mulmap擴充套件了這一屬性,可以允許元素不唯一。

(3)元素是有序的集合,預設在插入的時候按升序排列。

容器介面卡

STL中包含三種介面卡:棧stack、佇列queue和優先順序priority_queue。

介面卡是容器的介面,它本身不能直接儲存元素,它儲存元素的機制是呼叫另一種順序容器去實現,即:介面卡儲存一個容器,這個容器再儲存所有元素.STL中提供的三種介面卡可以由某一種順序容器去實現。預設下stack和queue基於deque容器實現,priority_queue則基於vector容器實現。當然在建立一個介面卡時也可以指定具體的實現容器,建立介面卡時在第二個引數上指定具體的順序容器可以覆蓋介面卡的預設實現。由於介面卡的特點,一個介面卡不是由任一個順序容器都可以實現的。

棧stack

棧stack的特點是後進先出,所以它關聯的基本容器可以是任意一種順序容器,因為這些容器型別結構都可以提供棧的操作要求,它們都提供了push_back、pop_back和back操作。

佇列queue

佇列queue的特點是先進先出,介面卡要求其關聯的基礎容器必須提供pop_front操作,因此其不能建立在vector容器上。

優先順序佇列priority_queue

優先順序佇列priority_queue介面卡要求提供隨機訪問功能,因此不能建立在list容器上。

相關文章