C 容器的一些總結

2021-07-01 18:43:24 字數 4508 閱讀 6792

原部落格:

1、容器的定義

在資料儲存上,有一種物件型別,它可以持有其它物件或指向其它對像的指標,這種物件型別就叫做容器。很簡單,容器就是儲存其它物件的物件,當然這是乙個樸素的理解,這種「物件」

還包含了一系列處理

「其它物件

」的方法。

2、容器的種類

順序容器:是一種各元素之間有順序關係的線性表,是一種線性結構的可序群集。順序性容器中的每個元素均有固定的位置,除非用刪除或插入的操作改變這個位置。順序容器的元素排列次序與元素值無關,而是由元素新增到容器裡的次序決定。順序容器包括:vector(向量)

、list

(列表)、

deque

(佇列)。

關聯容器:關聯式容器是非線性的樹結構,更準確的說是二叉樹結構。各元素之間沒有嚴格的物理上的順序關係,也就是說元素在容器中並沒有儲存元素置入容器時的邏輯順序。但是關聯式容器提供了另一種根據元素特點排序的功能,這樣迭代器就能根據元素的特點「順序地」獲取元素。 元素是有序的集合,預設在插入的時候按公升序排列。關聯容器包括:map(集合)、

set(對映)、

multimap

(多重集合)、

multiset

(多重對映)。

容器介面卡:本質上,介面卡是使一種不同的行為類似於另一事物的行為的一種機制。容器介面卡讓一種已存在的容器型別採用另一種不同的抽象型別的工作方式實現。介面卡是容器的介面,它本身不能直接儲存元素,它儲存元素的機制是呼叫另一種順序容器去實現,即可以把介面卡看作「它儲存乙個容器,這個容器再儲存所有元素」。stl 中包含三種介面卡:棧

stack 

、佇列queue 

和優先順序佇列priority_queue 。

3、各種容器的元素在記憶體中的儲存方式

vector(向量):相當於陣列,但其大小可以不預先指定,並且自動擴充套件。它可以像陣列一樣被操作,由於它的特性我們完全可以將vector 

看作動態陣列。在建立乙個

vector 

後,它會自動在記憶體中分配一塊連續的記憶體空間進行資料儲存,初始的空間大小可以預先指定也可以由

vector 

預設指定,這個大小即

capacity 

()函式的返回值。當儲存的資料超過分配的空間時

vector 

會重新分配一塊記憶體塊,但這樣的分配是很耗時的,效率非常低。

deque(佇列):它不像vector 

把所有的物件儲存在一塊連續的記憶體塊,而是採用多個連續的儲存塊,並且在乙個對映結構中儲存對這些塊及其順序的跟蹤。向

deque 

兩端新增或刪除元素的開銷很小,它不需要重新分配空間。

list(列表):是乙個線性鍊錶結構,它的資料由若干個節點構成,每乙個節點都包括乙個資訊塊(即實際儲存的資料)、乙個前驅指標和乙個後驅指標。它無需分配指定的記憶體大小且可以任意伸縮,這是因為它儲存在非連續的記憶體空間中,並且由指標將有序的元素鏈結起來。

set, multiset, map, multimap 是一種非線性的樹結構,具體的說採用的是一種比較高效的特殊的平衡檢索二叉樹

—— 紅黑樹結構。

4、各種容器優劣分析

vector:

優點:

a、支援隨機訪問,訪問效率高和方便,它像陣列一樣被訪問,即支援[ ] 

操作符和

vector.at()。

b、節省空間,因為它是連續儲存,在儲存資料的區域都是沒有被浪費的,但是要明確一點vector 

大多情況下並不是滿存的,在未儲存的區域實際是浪費的。

缺點:a、在內部進行插入、刪除操作效率非常低。

b、只能在vector 

的最後進行

push 

和pop 

,不能在

vector 

的頭進行

push 

和pop 

。c、 當動態新增的資料超過vector 

預設分配的大小時要進行記憶體的重新分配、拷貝與釋放,這個操作非常消耗效能。

list:

優點:

不使用連續的記憶體空間這樣可以隨意地進行動態操作,插入、刪除操作效率高;

缺點:a、不能進行內部的隨機訪問,即不支援[ ] 

操作符和

vector.at(),訪問效率低。

b、相對於verctor 

占用更多的記憶體。

deque:

優點:

a、支援隨機訪問,方便,即支援[ ] 

操作符和

vector.at() 

,但效能沒有

vector 

好;b、可以在兩端進行push 

、pop 。

缺點:在內部進行插入、刪除操作效率低。

綜合:

vector 的查詢效能最好,並且在末端增加資料也很好,除非它重新申請記憶體段;適合高效地隨機儲存。 

list 是乙個鍊錶,任何乙個元素都可以是不連續的,但它都有兩個指向上一元素和下一元素的指標。所以它對插入、刪除元素效能是最好的,而查詢效能非常差;適合 大量地插入和刪除操作而不關心隨機訪問的需求。

deque 是介於兩者之間,它兼顧了陣列和鍊錶的優點,它是分塊的鍊錶和多個陣列的聯合。所以它有被

list 

好的查詢效能,有被

vector 

好的插入、刪除效能。 如果你需要隨即訪問又關心兩端資料的插入和刪除,那麼

deque 

是最佳之選。

關聯容器的特點是明顯的,相對於順序容器,有以下幾個主要特點:

a, 其內部實現是採用非線性的二叉樹結構,具體的說是紅黑樹的結構原理實現的;

b, set 

和map 

保證了元素的唯一性,

mulset 

和mulmap 

擴充套件了這一屬性,可以允許元素不唯一;

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

基於以上特點,

a, 關聯容器對元素的插入和刪除操作比vector 

要快,因為

vector 

是順序儲存,而關聯容器是鏈式儲存;比

list 

要慢,是因為即使它們同是鏈式結構,但

list 

是線性的,而關聯容器是二叉樹結構,其改變乙個元素涉及到其它元素的變動比

list 

要多,並且它是排序的,每次插入和刪除都需要對元素重新排序;

b, 關聯容器對元素的檢索操作比vector 

慢,但是比

list 

要快很多。

vector 

是順序的連續儲存,當然是比不上的,但相對鏈式的

list 

要快很多是因為

list 

是逐個搜尋,它搜尋的時間是跟容器的大小成正比,而關聯容器 查詢的複雜度基本是

log(n) 

,比如如果有

1000 

個記錄,最多查詢

10 次,

1,000,000 

個記錄,最多查詢

20 次。容器越大,關聯容器相對

list 

的優越性就越能體現;

c, 在使用上set 

區別於vector,deque,list 

的最大特點就是

set 

是內部排序的,這在查詢上雖然遜色於

vector 

,但是卻大大的強於

list 

。d, 在使用上map 

的功能是不可取代的,它儲存了「鍵

- 值」關係的資料,而這種鍵值關係採用了類陣列的方式。陣列是用數字型別的下標來索引元素的位置,而

map 

是用字元型關鍵字來索引元素的位置。在使用上

map 

也提供了一種類陣列操作的方式,即它可以通過下標來檢索資料,這是其他容器做不到的,當然也包括

set 

。(stl 

中只有vector 

和map 

可以通過類陣列的方式操作元素,即如同

ele[1] 

方式)5、關於容器的sizeof

、size()

、capacity

問題vectorivec;

cout<

cout<

cout<

for(int i=0;i<10;i++)

ivec.push_back(1);

cout<

cout<

cout<

這是container

的實現問題,

container

肯定有些資料成員什麼的,這可以是

auto_ptr

或者是普通的

ptr指向一塊記憶體區域,或者還有可能(應該)包括這個記憶體區域的長度,現在已經用的長度。

sizeof

操作符統計的只是資料成員的長度,不會與堆裡面的資料長度有關,所以會出現你看到的結果。即作

sizeof

操作的大小是相同的。而

vector::size()

操作,才反映了具體資料長度。capacity求的是容器(

vector

)的容量。

C STL 容器的一些總結

容器中的元素為有序排列,可以指定元素插入位置.順序儲存,初始化過程會分配一定量空間,在尾部插入會很快,但是在中間插入元素,會把之後所有元素向後平移,所以較慢 中間刪除元素同理 如果元素個數超過當前限制,會重新分配更大空間,再把原容器中所有元素都拷貝到新的容器中.同vector類似,最大的好處是在頭尾...

c 的一些總結

1 typedef可以將變數重新命名,並且可以是幾個,中間用 隔開。2 enum 列舉型別 列舉型別就是將可能出現的結果一起儲存,每次操作只會出現乙個結果。每乙個列舉值都可對應乙個整型的資料,預設從0開始,可以顯示的說明從幾開始 eg enum 4 前向引用宣告 只能說明這是乙個類,而不能宣告物件。...

stl一些容器

deque a deque deque n,elem n個elem初始化的deque deque beg,end 雙指標初始化 v.push front 取出第乙個元素 棧,先進後出。通過top 方法返回棧頂元素,push 壓棧,pop 出棧。效率很高,不能遍歷,不支援隨機訪問。q.front q....