C++ STL容器底層數(shù)據(jù)結(jié)構(gòu)總結(jié)

STL 就是所謂的標(biāo)準(zhǔn)模板庫(Standard Template Library)矾利,這可能是C++程序員的一大利器尤揣。

總的來說业筏,STL包括幾個部分:容器捻悯,算法(泛型算法)箩朴,迭代器三個主要部分(當(dāng)然還包含仿函數(shù),適配器等其他部分)秋度,下圖說明了三個主要部分之間的關(guān)系(網(wǎng)圖,侵刪)钱床。

STL三個主要部分的關(guān)系示意圖

要是詳細(xì)的總結(jié)荚斯,這肯定是一本類似于《C++ Primer》的大書。本篇文章主要是對于STL中的常用容器的底層數(shù)據(jù)結(jié)構(gòu)進(jìn)行總結(jié)整理。

I事期、vector

1.1 vector底層數(shù)據(jù)結(jié)構(gòu)

vector是我們用到最多的數(shù)據(jù)結(jié)構(gòu)滥壕,其底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,由于數(shù)組的特點兽泣,vector也具有以下特性:
1绎橘、O(1)時間的快速訪問;
2唠倦、順序存儲称鳞,所以插入到非尾結(jié)點位置所需時間復(fù)雜度為O(n),刪除也一樣稠鼻;
3冈止、擴(kuò)容規(guī)則:
當(dāng)我們新建一個vector的時候,會首先分配給他一片連續(xù)的內(nèi)存空間候齿,如std::vector<int> vec熙暴,當(dāng)通過push_back向其中增加元素時,如果初始分配空間已滿慌盯,就會引起vector擴(kuò)容周霉,其擴(kuò)容規(guī)則在gcc下以2倍方式完成:
首先重新申請一個2倍大的內(nèi)存空間;
然后將原空間的內(nèi)容拷貝過來亚皂;
最后將原空間內(nèi)容進(jìn)行釋放俱箱,將內(nèi)存交還給操作系統(tǒng);

測試代碼如下:

#include<iostream>
#include<vector>
using namespace std;

void mycapacity(const vector<int>& vec)
{
    cout << "分配總空間大小為:" << vec.capacity() << endl;
}

void mysize(const vector<int>& vec)
{
    cout << "已用空間大小為:" << vec.size() << endl;
}

void myprint(const vector<int>& vec)
{
    for (int i = 0; i < vec.size(); ++i)
        cout << vec[i] << ",";
    cout << endl;
}


int main()
{
    vector<int> vec;
    cout << "起始狀態(tài):" << endl;
    mycapacity(vec);
    mysize(vec);
    cout << "========================" << endl;

    for (int i = 0; i < 10; ++i) {
        vec.push_back(i);
        cout << "壓入第" << i+1 << "個元素之后:" << endl;
        myprint(vec);
        mycapacity(vec);
        mysize(vec);
        cout << "========================" << endl;
    }

    return 0;
}
測試輸出結(jié)果

從輸出結(jié)果中的三個紅色箭頭可以看出vector的擴(kuò)容規(guī)則孕讳。

4匠楚、注意事項:
根據(jù)vector的插入和刪除特性,以及擴(kuò)容規(guī)則厂财,我們在使用vector的時候要注意芋簿,在插入位置和刪除位置之后的所有迭代器和指針引用都會失效,同理璃饱,擴(kuò)容之后的所有迭代器指針和引用也都會失效与斤。

II、map & multimap & unordered_map & unordered_multimap

2.1 map與multimap底層數(shù)據(jù)結(jié)構(gòu)

map與multimap是STL中的關(guān)聯(lián)容器荚恶、提供一對一key-value的數(shù)據(jù)處理能力撩穿; map與multimap的區(qū)別在于,multimap允許關(guān)鍵字重復(fù)谒撼,而map不允許重復(fù)食寡。

這兩個關(guān)聯(lián)容器的底層數(shù)據(jù)結(jié)構(gòu)均為紅黑樹,關(guān)于紅黑樹的理解可以參考教你透徹了解紅黑樹一文廓潜。

根據(jù)紅黑樹的原理抵皱,map與multimap可以實現(xiàn)O(lgn)的查找善榛,插入和刪除。

2.2 unordered_map 與unordered_multimap底層數(shù)據(jù)結(jié)構(gòu)

unordered_map與unordered_multimap 對比2.1中的兩種map在于其2.1中的兩個容器實現(xiàn)了以key為序排列呻畸,也就是說map與multimap為有序的移盆。

而unordered_map與unordered_multimap中key為無序排列,其底層實現(xiàn)為hash table伤为,因此其查找時間復(fù)雜度理論上達(dá)到了O(n)咒循,之所以說理論上是因為在理想無碰撞的情況下,而真實情況未必如此绞愚。

III叙甸、set & multiset & unordered_set & unordered_multiset

以上四種容器也都是關(guān)聯(lián)容器,set系與map系的區(qū)別在于map中存儲的是<key-value>爽醋,而set可以理解為關(guān)鍵字即值蚁署,即只保存關(guān)鍵字的容器。

3.1 set & multiset底層數(shù)據(jù)結(jié)構(gòu)

set與multiset有序存儲元素蚂四,這兩種容器的底層實現(xiàn)與map一樣都是紅黑樹光戈,所以能實現(xiàn)O(lgn)的查找,插入遂赠,刪除操作久妆。

set與multiset的區(qū)別在于是否允許重復(fù);

3.2 unordered_set & unordered_multiset

與unordered_map & unordered_multimap相同跷睦,其底層實現(xiàn)為hash table筷弦;

IV、 priority_queue

4.1 priority_queue

優(yōu)先級隊列相當(dāng)于一個有權(quán)值的單向隊列queue抑诸,在這個隊列中烂琴,所有元素是按照優(yōu)先級排列的。

priority_queue根據(jù)的處理規(guī)則來調(diào)整元素之間的位置蜕乡,關(guān)于堆的原理奸绷,可以參考

根據(jù)堆的特性层玲,優(yōu)先級隊列實現(xiàn)了取出最大最小元素時間復(fù)雜度為O(1),對于插入和刪除号醉,其最壞情況為O(lgn)。

V辛块、 其他數(shù)據(jù)結(jié)構(gòu)

list的底層數(shù)據(jù)結(jié)構(gòu)為雙向鏈表畔派,特點是支持快速的增刪。
queue為單向隊列润绵,為先入先出原則线椰。
deque為雙向隊列,其對比queue可以實現(xiàn)在頭尾兩端高效的插入和刪除操作尘盼。

歡迎轉(zhuǎn)載憨愉,轉(zhuǎn)載請注明出處wenmingxing 你好呀 C++

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呜魄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子莱衩,更是在濱河造成了極大的恐慌,老刑警劉巖娇澎,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笨蚁,死亡現(xiàn)場離奇詭異,居然都是意外死亡趟庄,警方通過查閱死者的電腦和手機(jī)括细,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來戚啥,“玉大人奋单,你說我怎么就攤上這事∶ㄊ” “怎么了览濒?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拖云。 經(jīng)常有香客問我贷笛,道長,這世上最難降的妖魔是什么宙项? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任乏苦,我火速辦了婚禮,結(jié)果婚禮上尤筐,老公的妹妹穿的比我還像新娘汇荐。我一直安慰自己,他們只是感情好盆繁,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布掀淘。 她就那樣靜靜地躺著,像睡著了一般改基。 火紅的嫁衣襯著肌膚如雪繁疤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天秕狰,我揣著相機(jī)與錄音稠腊,去河邊找鬼。 笑死鸣哀,一個胖子當(dāng)著我的面吹牛架忌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播我衬,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼叹放,長吁一口氣:“原來是場噩夢啊……” “哼饰恕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起井仰,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤埋嵌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俱恶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雹嗦,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年合是,在試婚紗的時候發(fā)現(xiàn)自己被綠了了罪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡聪全,死狀恐怖泊藕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情难礼,我是刑警寧澤娃圆,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站鹤竭,受9級特大地震影響踊餐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜臀稚,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一吝岭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吧寺,春花似錦窜管、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赖条,卻和暖如春失乾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纬乍。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工碱茁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仿贬。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓纽竣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蜓氨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345