【数据结构与算法】5. C++中 list、deque、vector对比
C++中l(wèi)ist、deque以及vector對比
C++的容器類包括兩大類:
1.順序存儲結(jié)構(gòu),包括vector、list、deque等等;
2.關(guān)聯(lián)存儲結(jié)構(gòu),包括set、map、multiset等等;
對比vector、list以及deque這三種順序存儲結(jié)構(gòu)
注:
順序存儲結(jié)構(gòu)表明,其中的每個元素之間是有先后順序的,這個順序只和插入/刪除等操作有關(guān),而與元素的值無關(guān)。
一、vector
vector本身是向量的意思,也稱vector是向量數(shù)組。
vector本身是為了解決數(shù)組不能動態(tài)增長,而自己實現(xiàn)的類還需要自己小心翼翼地處理指針和malloc等問題,所以衍生出vector。
vector中的每個元素在內(nèi)存上是連續(xù)的,就像數(shù)組一樣;
vector支持高效的隨機訪問(使用[ ]運算符或者at方法);
什么是隨機訪問?
所謂隨機訪問,是可以直接計算出對應(yīng)元素的地址,假設(shè)起始地址是base,每個元素占空間大小是element_size,那么當(dāng)我存取第n個元素時,我可以直接計算出其對應(yīng)的地址:第六個元素的地址=base+element_size*(n-1),不必要類似鏈表一樣遍歷,效率明顯很高。
vector支持高效的在末尾插入和刪除。
注意:
此處特別強調(diào)是在末尾,想一想,一個數(shù)組,在哪里插入和刪除最為容易?
顯然是末尾。
如果在數(shù)組中間插入或刪除,需要將之后的所有元素都向前/向后移動,無疑增加了開銷。
可以將vector看成是一個數(shù)組,區(qū)別于普通的數(shù)組,vector擁有自動擴展內(nèi)存空間的能力(不必程序員自己管理內(nèi)存空間)。
vector有一個capacity方法,其返回值是當(dāng)前vector已經(jīng)分配了多少個空間用來存儲element。
這些空間不一定全被“裝滿”了,可能只裝了一部分。
在裝滿(vector.size()==vector.capacity())的情況下繼續(xù)裝(vector.push_back(xxx))時,vector自動擴大內(nèi)存:
步驟如下:
首先申請一塊更大的內(nèi)存空間;
其次將vector現(xiàn)有的元素都搬過去;
最后將需要插入的元素插入到末尾。
注意:
在上述的步驟中還要將原來使用的內(nèi)存空間釋放。
程序員無需關(guān)心什么時候釋放等等細(xì)節(jié),vector會自己做的。
程序員只要一個push_back即可。
關(guān)于vector的成員函數(shù)說兩句:
1.szie以及capacity返回的都是元素的個數(shù),是以元素來計數(shù)的,而不是字節(jié)。
2.vector支持在末尾進(jìn)行pop和push,但不支持在首進(jìn)行pop和push。
當(dāng)然,如果一定要在前面插入,vector也是有對應(yīng)的insert和erase的,只是由于必然引起數(shù)據(jù)塊的移動,所以性能很低。
二、list
list是一個非連續(xù)的順序結(jié)構(gòu),每個元素在內(nèi)存上都不是挨著的。
list是一個雙向鏈表,即每個節(jié)點都有兩個指針域:一個指向前驅(qū)節(jié)點,一個指向后繼節(jié)點。
list同普通的鏈表一樣,對待插入刪除這樣的操作可以有很高的效率;
同樣,對于隨機訪問的能力就不盡如人意,效率很差了。
list在存儲大的,復(fù)雜的數(shù)據(jù)時有很不錯的表現(xiàn)。
list有幾個優(yōu)點:
首先list不使用連續(xù)的內(nèi)存;
其次在插入和刪除方面有很好的性能;
最后是可以在兩端進(jìn)行pop和push(vector只能在尾端進(jìn)行pop和push)。
list也有其自己的缺點:
因為其每個節(jié)點有兩個指針域,導(dǎo)致占用空間較大;
list不支持[]操作符和at方法。
注:
不是list不能實現(xiàn)[ ]和at,而是設(shè)計者認(rèn)為list在這方面表現(xiàn)的很不好,隨機訪問也不應(yīng)該是list的用武之地,所以不這么實現(xiàn),但不代表著不能實現(xiàn)。
對于list,清除所有的元素需要依次遍歷,效率很低(如果是vector,因為是一整塊內(nèi)存,可以很方便地進(jìn)行操作)。
三、deque
deque=double-end-queue,意即雙端隊列。
可以將deque看成是list和vector的結(jié)合。(效率接近于vector),而且在插入和刪除方面也表現(xiàn)出很不錯的性能(尤其是在首位進(jìn)行插入刪除,效率接近于list)。
deque還可以類似list那樣在兩端進(jìn)行pop和push。
猜測:
deque可能是下面的存儲結(jié)構(gòu):
每幾個元素時連續(xù)的一個內(nèi)存塊,而每個內(nèi)存塊之間有指針鏈接起來。
當(dāng)隨機訪問時使用一個分段函數(shù)可以相對方便地計算出來地址(當(dāng)然沒有vector那樣方便啦,只是比起list來說好很多了);
當(dāng)在首位進(jìn)行插入刪除時有接近于list的性能表現(xiàn)。
綜上三點,得出以下結(jié)論:
1.如果有大量的隨機訪問,而插入和刪除操作較少,應(yīng)該使用vector;
2.如果有大量的插入和刪除,而隨機訪問較少,應(yīng)該使用list;
3.如果既有很多的插入和刪除,又有很多的隨機訪問,那么deque是個不錯的選擇。
另外一點,如果在不知道內(nèi)存具體需求的時候,一般使用deque要比vector性能好一些。
總結(jié)
以上是生活随笔為你收集整理的【数据结构与算法】5. C++中 list、deque、vector对比的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【多线程】阻塞队列的C++多线程 实现
- 下一篇: s3c2440移植MQTT