【C++】STL各容器的實現,時間復雜度,適用情況分析


一.vector

1.概述

動態數組,在內存中具有連續的儲存空間,在堆上分配內存,支持快速隨機訪問,在中間插入和刪除慢,但在末尾插入和刪除快

2.特點

1)擁有一段連續的內存空間,並且起始地址不變,因此能非常好的支持隨機存取,但由於其內存空間是連續的,所以在中間插入和刪除會造成內存塊的拷貝,另外,當該數組的內存空間不夠時,需要重新申請一塊足夠大的內存並進行內存拷貝,這些都大大的影響了vector的效率

2)對頭部和中間的元素進行插入刪除需要移動內存,如果元素是結構體或者類,那么移動時還會進行析構和構造操作,所以性能不高

3)對末尾的元素的操作最快,此時一般不需要移動內存,只有剩余內存不夠時才需要

3.時間復雜度分析:

頭部插入刪除:O(N)

尾部插入刪除:O(1)

中間插入刪除:O(N)

查找:O(N)

4.優缺點及適用場景

優點:支持隨機儲存,查詢效率高

缺點:在頭部和中間插入刪除元素效率低,需要移動內存

適用場景:適用於元素結構簡單,變化小,並且頻繁隨機訪問的場景

5.結論

vector常用來保存需要經常進行隨機訪問的內容,並且不需要對中間元素進行添加和刪除操作

二.雙向隊列deque

1.概述

deque是double ended queue的縮寫,是一個動態數組,可以向兩端發展(雙向開口的連續線性空間),因此無論在頭部或者尾部安插元素都十分迅速,在中間按插元素則比較費時,因為必須移動其他元素

雙端隊列的元素被表示為一個分段數組,容器中的元素分段存放在一個個大小固定的數組中,此外,容器還需要維護一個存放這些數組首地址的索引數組,如下圖所示

image

deque原理圖

由於分段數組的大小是固定的,並且他們的首地址被連續存放在索引數組中,因此可以對其進行隨機訪問,但是效率比vector低很多

向兩端加入新元素時,如果這一端的分段數組未滿,則可以直接加入,如果這一端的分段數組已滿,只需要創建新的分段數組,並把該分段數組的地址加入到索引數組中即可,這樣就不需要對已有的元素進行移動,因此在雙端隊列的兩端加入新的元素都具有較高的效率

當雙端隊列刪除首尾元素時,也不需要移動,所以效率也比較高

雙端隊列中間插入元素時,需要將插入點到某一端之間的所有元素向容器的這一端移動,因此向中間插入元素的效率較低,而且往往插入的位置越靠近中間,效率越低,刪除隊列中元素時,情況也類似

2.特點

1)按照頁或者塊來分配存儲器,每頁包含固定數目的元素

2)支持隨機儲存

3)頭尾刪除插入元素效率高

3.時間復雜度分析

頭部尾部插入刪除:O(1)

中間插入刪除:O(N)

查找:O(N)

4.優缺點及適用場景

優點:頭部尾部插入刪除快

缺點:不適合中間插入刪除操作,占用內存多

適用場景:適用於既要頻繁隨機儲存,又要關心兩端數據的插入與刪除操作,並且不需要頻繁對中間元素進行插入刪除的場景

三.雙向鏈表list

1.概述

list由雙向鏈表實現,元素存放在堆中,每個元素都是存放在一塊內存中,它的內存空間可以是不連續的,通過指針來進行數據訪問,這個特點使得它的隨機儲存變得非常的沒有效率,但是由於鏈表的特點,它可以很有效率的支持任意地方的插入和刪除操作

2.特點

1)沒有預留空間的習慣,所以每分配一個元素都會從內存中分配,每釋放一個元素都會釋放其占用的內存

2)任何地方插入刪除的效率都很高,不需要移動內存,也就不需要在移動過程中對每個元素進行構造和析構,常用來做隨機插入和刪除的容器

3)訪問首尾元素最快

3.時間復雜度分析

任何位置的插入刪除:O(1)(假設告訴了你插入刪除的位置,不需要你線查找再刪除)

頭尾查詢:O(1)

其他位置查詢:O(N)

4.優缺點及適用場景

優點:內存不連續,動態操作,在任意位置插入和刪除的效率都高

缺點:不支持隨機訪問,相比於vector占用內存多

適用場景:適用於經常進行插入和刪除並且不經常隨機訪問的場景

關於vector,deque,list的總結:

vector

特點:快速的隨機儲存,快速的在最后插入刪除元素

適用:需要高效隨機儲存,需要高效的在末尾插入刪除元素,不需要高效的在其他地方插入和刪除元素

deque

特點:比較快速的隨機存儲(比vector的慢),快速的在頭尾插入刪除元素

適用:需要隨機儲存,需要高效的在頭尾插入刪除元素的場景

list

特點:快速在任意位置插入刪除元素,快速訪問頭尾元素

適用:需要大量插入刪除操作,不關心隨機儲存的場景

deque可以看作是vector和list的折中方案

四.set

1.概述

set由紅黑樹實現,其內部元素依照其值自動排序,每個元素只出現一次,不允許重復(紅黑樹是平衡二叉樹的一種)

2.特點

1)元素有序

2)無重復元素

3)插入刪除操作的效率比序列容器高,因為對於關聯容器來說,不需要做內存的拷貝和內存的移動

3.時間復雜度分析

增刪改查近似:O(log N)

4.優缺點及適用場景

優點:使用平衡二叉樹實現,便於元素查找,而且保持了元素的唯一性,支持自動排序

缺點:每次插入元素,都需要調整紅黑樹,效率有一定的影響

適用場景:適用與經常查找一個元素是否在某集群中並且不要排序的場景

五.multiset

multiset和set相同,只不過它允許重復元素,也就是說multiset可包括多個數值相同的元素。這里不再做過多介紹。

六.map

1.概述

map由紅黑樹實現,其元素都是鍵值對,每個元素的鍵是排序的准則,每個鍵只能出現一次,不允許重復

2.特點

1)元素為鍵值對形式,鍵和值可以是任意類型

2)因為key有序,所以可以通過二分對key進行快速查找

3)增加和刪除結點對迭代器的影響很小,除了當前結點是迭代器指向的結點

4)對於迭代器來說,可以修改值,但是不能修改key

3.時間復雜度分析

增刪改查基本是O(log N)

4.優缺點和適用場景

優點:適用平衡二叉樹實現,便於元素查找,而且可以把值映射到另外一個值,可以創建字典

缺點:每次插入都需要調整紅黑樹,對效率存在一定的影響

適用場景:適用於需要儲存一個字典,並要求方便的根據key找value的場景

七.multimap

multimap和map相同,但允許重復元素,也就是說multimap可包含多個鍵值(key)相同的元素。這里不再做過多介紹。

ps:stack,queue,prioroty_queue都屬於容器配接器,是由容器按照特殊的邏輯實現的


小結:

1)如果需要高效的隨機存取,不在乎插入和刪除的效率,使用vector。

2)如果需要大量的插入和刪除元素,不關心隨機存取的效率,使用list。
3)如果需要隨機存取,並且關心兩端數據的插入和刪除效率,使用deque。
4)如果打算存儲數據字典,並且要求方便地根據key找到value,一對一的情況使用map,一對多的情況使用multimap。
5)如果打算查找一個元素是否存在於某集合中,唯一存在的情況使用set,不唯一存在的情況使用multiset。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM