c 容器簡介與比較

2021-05-27 11:40:29 字數 3140 閱讀 8543

最近從網上找了一些資料,自己簡單整理了一下.

1 概要介紹

vector用來代替陣列,也就是,要經常用下標運算的地方

list是鍊錶,多用表經常使用插入刪除的地方

map是圖,比如做乙個字典了,**薄了,會用到

queue很少用,比如排隊買火車票的佇列,就是這種結構

set更少用,指的是乙個無序集合

vectorintvalues(10);是10個元素的1個向量

vectorintvalues[10];是陣列,含10個空向量

map是雜湊表;  

list是鏈式儲存的線性表,也叫「鍊錶」; 

vector是可動態改變大小的順序儲存的線性表,也叫「動態陣列」。 vector和陣列差不多,就是大小是變數,在記憶體是連續儲存;  

list是佇列,每個物件都有前向指標和後象指標,在記憶體裡也不一定是連續儲存;    map也是使用指標

vector是序列容器,記憶體分配時占用連續空間,因為採用的是隨機迭代器,所以得到某一位置的值非常快 ,但是插入和刪除比較慢,因為涉及到大塊記憶體的賦值貼上.  

list也是容器,但是記憶體分配是零散的,採用的是雙向迭代器,得到某一位置的值並不快,但插入和刪除效率很高.

map底層採用的是樹型結構,多數使用平衡二叉樹實現,查詢某一值是常數時間,遍歷起來效果也不錯, 只是每次插入值的時候,會重新構成底層的平衡二叉樹,效率有一定影響. 

2 分類介紹

在stl中基本容器有: string、vector、list、deque、set、map

set 和map都是無序的儲存元素,只能通過它提供的介面對裡面的元素進行訪問

set:集合, 用來判斷某乙個元素是不是在乙個組裡面,使用的比較少

map:對映,相當於字典,把乙個值對映成另乙個值,如果想建立字典的話使用它好了

string、vector、list、deque、set 是有序容器

2.1.string

string 是basic_string的實現,在記憶體中是連續存放的.為了提高效率,都會有保留記憶體,如string s= "abcd",這時s使用的空間可能就是255, 當string再次往s裡面新增內容時不會再次分配記憶體.直到內容》255時才會再次申請記憶體,因此提高了它的效能.

當內容》255時,string會先分配乙個新記憶體,然後再把內容複製過去,再複製先前的內容.

對string的操作,如果是新增到最後時,一般不需要分配記憶體,所以效能最快;

如果是對中間或是開始部分操作,如往那裡新增元素或是刪除元素,或是代替元素,這時需要進行記憶體複製,效能會降低.

如果刪除元素,string一般不會釋放它已經分配的記憶體,為了是下次使用時可以更高效.

由於string會有預保留記憶體,所以如果大量使用的話,會有記憶體浪費,這點需要考慮.還有就是刪除元素時不釋放過多的記憶體,這也要考慮.

string中記憶體是在堆中分配的,所以串的長度可以很大,而char是在棧中分配的,長度受到可使用的最大棧長度限制.

如果對知道要使用的字串的最大長度,那麼可以使用普通的char,實現而不必使用string.

string用在串長度不可知的情況或是變化很大的情況.

如果string已經經歷了多次新增刪除,現在的尺寸比最大的尺寸要小很多,想減少string使用的大小,可以使用:

string s = "abcdefg";

string y(s); // 因為再次分配記憶體時,y只會分配與s中內容大一點的記憶體,所以浪費不會很大

s.swap(y); // 減少s使用的記憶體

如果記憶體夠多的話就不用考慮這個了capacity是檢視現在使用記憶體的函式

大家可以試試看string分配乙個一串後的capacity返回值,還有其它操作後的返回值

2.2.vector

vector就是動態陣列.它也是在堆中分配記憶體,元素連續存放,有保留記憶體,如果減少大小後記憶體也不會釋放.如果新值》當前大小時才會再分配記憶體

對最後元素操作最快(在後面新增刪除最快 ), 此時一般不需要移動記憶體,只有保留記憶體不夠時才需要

對中間和開始處進行新增刪除元素操作需要移動記憶體,如果你的元素是結構或是類,那麼移動的同時還會進行構造和析構操作,所以效能不高.

訪問方面,對任何元素的訪問都是o(1),也就是是常數的,所以vector常用來儲存需要經常進行隨機訪問的內容,並且不需要經常對中間元素進行新增刪除操作.

相比較可以看到vector的屬性與string差不多,同樣可以使用capacity看當前保留的記憶體,使用swap來減少它使用的記憶體.

總結需要經常隨機訪問請用vector

2.3.list

list就是鍊錶,元素也是在堆中存放,每個元素都是放在一塊記憶體中

list沒有空間預留習慣,所以每分配乙個元素都會從記憶體中分配,每刪除乙個元素都會釋放它占用的記憶體,這與上面不同,可要看好了

list在**新增刪除元素效能都很高,不需要移動記憶體,當然也不需要對每個元素都進行構造與析構了,所以常用來做隨機操作容器.

但是訪問list裡面的元素時就開始和最後訪問最快

訪問其它元素都是o(n) ,所以如果需要經常隨機訪問的話,還是使用其它的好

總結如果你喜歡經常新增刪除大物件的話,那麼請使用list

要儲存的物件不大,構造與析構操作不複雜,那麼可以使用vector代替

list《指標》完全是效能最低的做法,這種情況下還是使用vector《指標》好,因為指標沒有構造與析構,也不占用很大記憶體

2.4.deque

雙端佇列,也是在堆中儲存內容的.它的儲存形式如下:

[堆1]

[堆2]

[堆3]

每個堆儲存好幾個元素,然後堆和堆之間有指標指向,看起來像是list和vector的結合品,不過確實也是如此

deque可以讓你在前面快速地新增刪除元素,或是在後面快速地新增刪除元素,然後還可以有比較高的隨機訪問速度

總結vector是可以快速地在最後新增刪除元素,並可以快速地訪問任意元素

list是可以快速地在所有地方新增刪除元素,但是只能快速地訪問最開始與最後的元素

deque在開始和最後新增元素都一樣快,並提供了隨機訪問方法,像vector一樣使用訪問任意元素,但是隨機訪問速度比不上vector快,因為它要內部處理堆跳轉

deque也有保留空間.另外,由於deque不要求連續空間,所以可以儲存的元素比vector更大,這點也要注意一下.還有就是在前面和後面新增元素時都不需要移動其它塊的元素,所以效能也很高

c 容器類簡介

net framework 的容器 自從我發現了stl,再編寫c 程式,就離不開它了。stl提供的容器和演算法極大的方便了c 程式設計。最近在對比研究c 中的泛型 標準容器和演算法,看看它是如何實現類似stl的功能的。先總結一下c 中的標 準容器。我使用的是 visual c 2005。c 中主要有...

C 順序容器簡介

順序容器型別 功能標頭檔案 vector 可變長度的陣列,也叫向量 vector deque 雙端佇列,也就是可以兩頭插入和刪除的佇列。實際上也支援隨機訪問 deque list 乙個雙向鍊錶 list forward list 乙個單項鍊表 forward list array 固定大小的陣列,和...

C 容器類簡介(摘抄)

c 中的容器類包括 順序儲存結構 和 關聯儲存結構 前者包括vector,list,deque等 後者包括set,map,multiset,multimap等。若需要儲存的元素數在編譯器間就可以確定,可以使用陣列來儲存,否則,就需要用到容器類了。1 vector 連續儲存結構,每個元素是在記憶體上是...