在c++中,容器指的是可以容納各類數據類型的通用數據數據結構,是類模板。 好比set類模板:c++
template <class _Key, class _Compare = less<_Key>,算法
class _Allocator = allocator<_Key> >編程
class _LIBCPP_TYPE_VIS_ONLY set數組
C++的容器主要分爲三種:順序容器、關聯容器和容器適配器。數據結構
而訪問容器元素咱們須要迭代器(引入容器頭文件就能夠了,不須要單獨由於頭文件),迭代器有如下幾個屬性:less
1.用於指向順序容器和關聯容器的元素編程語言
2.用法和指針相似函數
3.有const(容器類名::iterator 變量名)和非const兩種(容器類名::const_iterator 變量名)性能
4.經過迭代器能夠讀取它指向的元素學習
5.非const迭代器和能夠修改其指向的元素
何爲順序容器,也就是說元素的位置是順序插入的,插入位置與元素的值無關,核心是容器沒有排序。 順序容器都具備如下10個成員函數:
#返回迭代器
begin
end
rbegin //返回指向最後一個元素的迭代器
rend
#返回元素引用
front
back
#其餘
erase(刪除區間時返回被刪除元素後面的迭代器;也可刪除一個或幾個元素)
clear
push_back
pop_back
順序容器有如下三種:
1.vector動態數組 頭文件<vetor>
元素在內存中是連續存放的。
隨機存取時間:常數時間(由於能夠經過下標直接訪問到地址)。
在尾部增刪元素一般是常數時間(正常是常數時間,若是超出了默認分配的元素個數,會從新分配存儲空間,此時會消耗更多時間)。
在中間或者頭部增刪元素:o(n)(會移動其餘元素的位置)。
迭代器類型:隨機訪問(支持下標訪問、隨機移動,例:a[i])。
查詢時間:o(n)(由於沒有排序,只能現行查找,效率較低)。
可見vector在中間或者頭部增刪元素性能較低。
優勢:內存和C徹底兼容、高效隨機訪問、節省空間
缺點:內部插入刪除元素代價巨大、動態大小查過自身容量須要申請大量內存作大量拷貝。
構造函數:
vector();
vector(int n);
vector(int n, const T &a); //把n個元素初始化爲a
vector(iterator first,iterator last); //初始化爲其餘容器上區間[first,last)一致的內容
經常使用成員函數
void pop_back();
void push_back(const T &val);
int size();
T & font();
T & back();
deque[讀:dek,以前常常讀dkju:]雙向隊列 頭文件<deque>
元素在內存中連續存放(連續內存的容器有個明顯的缺點,就是有新元素插入或老元素刪除的時候,爲了給新元素騰出位置或者填充老元素的空缺,同一塊內存中的其餘數據須要進行總體的移位,這種移位的拷貝代價有時是很是巨大的。deque其實是分配到不一樣內存塊,經過鏈表把內存塊連在一塊兒,再進行連續存放,是list與vector的折中)。
隨機存取時間:常數時間(僅次於vector,由於有可能存在尾部的內存位置在頭部以前的場景)。
在兩端增刪元素一般是常數時間。(deque不像vector沒有容量,不須要從新分配內存空間。這是由於deque由動態分配的連續空間,即緩衝區,組合而成,隨時能夠增長一段新的空間連接起來。它沒有必要像vector那樣「因舊空間不足而從新分配2倍的空間,而後複製元素,再釋放舊空間」。當從新分配緩衝區時,耗時增長)。
在中間插入:時間複雜度較高。
迭代器類型:隨機訪問(效率低於vector)。
查詢時間:o(n)(緣由同上)。
優勢:高效隨機訪問、內部插入刪除元素效率方便、兩端push、pop效率很高 。
缺點:內存佔用比較高 。
list雙向鏈表 頭文件<list>
元素在內存中不連續分配(由於指針能夠獲取先後元素的地址),因此不支持隨機存取。
在任何位置增刪元素時間:常數時間。
查詢時間:o(n)(緣由同上)。
迭代器類型:雙向(不支持下標訪問,不支持迭代器的比較運算符,和+-運算符)
優勢:任意位置插入刪除元素常量時間複雜度、兩個容器融合是常量時間複雜度
缺點:不支持隨機訪問、比vector佔用更多的存儲空間
經常使用成員函數:(注意這些在順序容器中都是list獨有的)
push_front
pop_front
sort //不支持STLsort算法
remove
unique
merge
reverse
splice
特別說明,list的sort函數有無參和compare兩個版本
list<T> classname
classname.sort(compare); //compare自定義
classname.sort();
關聯的意思就是元素是排序的。
插入與檢索元素時間: o(log(N))(由於經過紅黑二叉樹實現,時間與平衡二叉樹一致)。
須要注意的是,STL中有些算法好比sort,binary_search須要經過隨機訪問迭代器訪問容器中的元素,所以list以及關聯容器就不能支持該算法!
主要包括如下4種:
set
multiset
map
multimap
除了個容器都有的成員函數外,它們都有如下成員函數
find
lower_bound
upper_bound
equal_range
count
insert
map與set的不一樣點在於,map中存放的元素有且僅有兩個成員變量,first(相似於key),second(相似於value),map能夠根據first對元素排序和檢索。
set與multiset的不一樣在於,後者容許存在相同值的元素。 map與multimap的不一樣在於,後者容許存在相同的first值的元素。
這個概念聽起來有點抽象,其實就是STL幫咱們抽象了實際工做中所須要的數據操做方式。舉個栗子,交流電能夠有任意的傳輸電壓,可是實際生活中咱們只須要220v就夠了,變壓器幫咱們實現了這個基本的功能。同理,容器的操做方式多種多樣,可是其實咱們只須要他們按照實際的一些規範來操做便可。
他們都有如下3個成員函數:
push
top
pop
STL中的排序,查找,變序算法都不適合容器適配器(由於容器適配器的元素位置不可隨意改變,而且訪問有必定的訪問規則,不支持隨機訪問)。
stack 棧 頭文件<stack>
是一個有限序列,並知足序列中被刪除、檢索和修改的項只能是最近插入序列的項(棧頂項)。也即,先進先出LIFO。
能夠用vector,deque,list(性能最差)實現,編譯器缺省是用deque實現的。
好比,在程序調試中,錯誤堆棧就是一種應用。
queue 隊列 頭文件 <queue>
插入只能夠在尾部進行,刪除、檢索和修改只容許從頭部進行。先進先出FIFO。
queue因爲pop,push發生在對頭,因此不能用vector實現,能夠用list,deque實現,編譯器缺省用deque實現。
好比,應用於須要保證消息順序性的場景,如消息隊列。
priority_queue 優先級隊列 頭文件<queue>
最高優先級元素老是第一個出列。
它需採用堆排序來保證元素老是在最前面,所以要求隨機訪問,因此不能使用list實現,能夠用vector和deque實現,編譯器缺省狀況下用vector實現。
好比,操做系統的線程的調度算法,有的是按照優先級來調度的。
1.若是須要隨機訪問,用vector;
2.若是存儲元素的數目已知,用vector;
3.須要任意位置隨機插入刪除,用list;
4.常常在容器的首部尾部插入刪除元素,用deque;
5.元素結構複雜用list,也能夠用vector存儲指針(須要額外的精力去維護內存),看需求;
6.若是操做是基於鍵值,用set/map;
7.若是須要常常的搜索,用map/set。
C語言就是一個既能夠強化思惟能力,又能夠打好編程基礎的編程語言,對這個感興趣的同窗來小編這裏學學吧。即便是零基礎的學習者,均可以一塊兒成長進步。