數(shù)據(jù)結(jié)構(gòu) -- C++ STL中的數(shù)據(jù)結(jié)構(gòu)與算法[1]

數(shù)據(jù)結(jié)構(gòu) -- C++ STL中的數(shù)據(jù)結(jié)構(gòu)與算法[1]

什么是 STL

STL是Standard Template Library的簡稱逾滥,中文名標(biāo)準(zhǔn)模板庫谍夭,惠普實驗室開發(fā)的一系列軟件的統(tǒng)稱讹挎。它是由Alexander Stepanov趴泌、Meng Lee和David R Musser在惠普實驗室工作時所開發(fā)出來的倒戏。從根本上說,STL是一些“容器”與“算法”的集合瞭吃,所謂的這些“容器”無非就是已經(jīng)實現(xiàn)好了數(shù)據(jù)結(jié)構(gòu)碌嘀,能夠讓程序設(shè)計者更為方便的進(jìn)行調(diào)用,“算法”則顧名思義就是已預(yù)先實現(xiàn)好了的算法集合歪架。

STL的目的是標(biāo)準(zhǔn)化組件筏餐,這樣就不用重新開發(fā),可以使用現(xiàn)成的組件牡拇。STL現(xiàn)在是C++的一部分魁瞪,因此不用安裝額外的庫文件。STL的版本很多惠呼,有很多公司或者工作室自定義STL形成各種各樣的自定義標(biāo)準(zhǔn)导俘。。

在C++標(biāo)準(zhǔn)中剔蹋,STL被組織為下面的13個頭文件:<algorithm>旅薄、<deque>、<functional>泣崩、<iterator>少梁、<vector>、<list>矫付、<map>凯沪、<memory>、<numeric>买优、<queue>妨马、<set>挺举、<stack>和<utility>。

STL中包含的幾大內(nèi)容:

1.容器(Container)

是一種數(shù)據(jù)結(jié)構(gòu)烘跺,也是本章節(jié)提的重點湘纵,如list(鏈表),vector(向量數(shù)組)滤淳,stack(棧)梧喷,隊列(queue) ,以模板類的方法提供脖咐,為了訪問容器中的數(shù)據(jù)伤柄,可以使用由容器類輸出的迭代器。

  1. 迭代器(Iterator)

是一種特殊的指針文搂,它提供了訪問容器中對象的方法,在程序設(shè)計中秤朗,它扮演了容器和算法之間的膠合劑煤蹭,利用迭代器可以快速而安全的對容器內(nèi)容進(jìn)行操作,或是進(jìn)行算法模板的使用取视。

  1. 算法(Algorithm)

(部分書籍稱為泛型算法硝皂,generic algorithms),是一類常用的算法模板作谭,既可以對容器進(jìn)行操作稽物,同時其開放性也讓算法類本身可以針對數(shù)組或者是自定義結(jié)構(gòu)體等結(jié)構(gòu)進(jìn)行直接的操作。

  1. *仿函數(shù)(Function object)(又稱為函數(shù)對象折欠,function object)

是一種行為類似函數(shù)贝或,這樣講可能有些抽象,我們可以理解為一種高級的锐秦,重載了()操作符的結(jié)構(gòu)體與類咪奖。

5.*迭代適配器(Iterator Adaptor)

是一種用來修飾容器或者仿函數(shù)的接口,它使得得帶適配器使算法能夠以逆向模式酱床,安插模式進(jìn)行工作羊赵,甚至還可以與流配合,它對容器起到非常大的輔助作用扇谣,同時他還將迭代器進(jìn)行了更高級別的抽象昧捷。

  1. *空間配制器(allocator)

是負(fù)責(zé)空間的配置與管理,重點就是對容器的空間申請和空間釋放進(jìn)行管理罐寨,你可以理解為C的malloc和free函數(shù)靡挥,C++的new和delete關(guān)鍵字。

Vector容器

1. 概念

Vector可以翻譯為向量鸯绿,或向量數(shù)組芹血,至于為什么以向量命名贮泞,可以理解為一維空間也是存在向量的。

Vector是最簡單的序列是容器幔烛,就像數(shù)組一樣啃擦,向量使用連續(xù)的存儲位置作為元素,這意味著它們的元素也可以使用常量指向其元素的偏移來訪問饿悬,與數(shù)組一樣有效令蛉。但與數(shù)組不同,它們的大小可以動態(tài)變化狡恬,其存儲由容器自動處理珠叔。

總結(jié)一下Vector就是一個動態(tài)創(chuàng)建空間,且預(yù)先加載了常用的數(shù)組操作的數(shù)組

2. 相關(guān)文件

頭文件:#include <vector>

3. 初始化

格式為:vector<Data_Types> name;

我們以int類型作為參數(shù)為例弟劲,進(jìn)行創(chuàng)建祷安。

vector<int> v1;          //創(chuàng)建一個空的向量v1
vector<int> v2(10);      //創(chuàng)建一個向量v2,其已開辟10個元素的空間兔乞,相當(dāng)于int v[10];
vector<int> v3(10,5);    //創(chuàng)建一個向量v3汇鞭,其已開辟10個元素的空間并全部賦值為5
vector<int> v4(v3.begin(),v3.end());    //創(chuàng)建一個向量v3,其內(nèi)容為向量v3的內(nèi)容
vector<int> v5(v4);      //創(chuàng)建一個向量v5,其包含了v4的全部內(nèi)容

4. 迭代器

顧名思義庸追,迭代器是一種安全的訪問控制器霍骄,它本身是一種指針,用于直接的元素訪問淡溯。其遍歷訪問的大致思路是读整,創(chuàng)建容器的迭代器,讓迭代器指向第一個元素咱娶,逐步向后移動并最終指向最后一個元素結(jié)束米间。

遍歷代碼舉例:

vector<int> v;       //創(chuàng)建一個向量vs
vector<int>::iterator it;   //C98標(biāo)準(zhǔn)
for(it=v.begin();it!=v.end();it++){
    cout<<*it<<' ';
}

當(dāng)然,遍歷也可以直接使用下標(biāo)訪問:

 for(int i=0;i<v.size();i++){
        cout<<v[i]<<' ';
 }

5.常用接口(常用的)

Vector的接口有非常多膘侮,不同的C++語言標(biāo)準(zhǔn)也不同车伞,這里只提供一些常用的進(jìn)行簡介,具體的使用可以翻閱官方文檔(英文)喻喳,或是別人的翻譯稿另玖。

我們使用 vector<int> v; 預(yù)先創(chuàng)建了一個向量。

a) 向量尾插入push_back()

在向量的末尾添加一個新元素val表伦,并自動讓容器大小增大一個谦去。

函數(shù)原型:

void push_back (const value_type& val);

使用舉例:

v.push_back(10); //插入一個數(shù)據(jù)10

b) 向量尾刪除pop_back()

移除向量尾的最后一個元素,并且將容器大小減小一個蹦哼,

函數(shù)原型:void pop_back();

使用舉例:

v.pop_back();

c) 插入insert()

插入元素到指定位置鳄哭,通過在元素之前在指定位置插入新元素來擴(kuò)展向量,從而有效地增加容器大小所插入的元素數(shù)量纲熏。

函數(shù)原型:

插入單一數(shù)據(jù)到指定位置:

iterator insert (iterator position, const value_type& val);

插入一段數(shù)據(jù)到指定位置:

void insert (iterator position, size_type n, const value_type& val);

插入一段別的容器的數(shù)據(jù)到指定位置:

*template *

void insert (iterator position, InputIterator first, InputIterator last);

使用舉例:

 v.insert(v.begin(),10);     //在向量最前端插入數(shù)據(jù)10
 v.insert(v.begin(),5,20);   //在向量最前端插入5個數(shù)據(jù)20
  
 vector<int> k(2,50);   //創(chuàng)建一個新的向量k,其擁有2個元素內(nèi)容均為50
 v.insert(v.begin(),k.begin(),k.end());  //在向量v最前端插入向量K的全部內(nèi)容

d) 刪除erase()

刪除一個元素妆丘,或者是一段區(qū)間的元素锄俄,將會自動縮減空間使用。

函數(shù)原型:

iterator erase (iterator position);

iterator erase (iterator first, iterator last);

使用舉例

v.erase(v.begin());     //刪除第一個元素
v.erase(v.begin(),v.begin()+4); //刪除從第一個開始后4個元素(包括第一個)

List容器

1.概念

鏈表是線性表 勺拣,STL鏈表是單鏈表的形式奶赠。

2.頭文件

頭文件:#include <list>

3.初始化

格式為:explicit list (const allocator_type& alloc = allocator_type());

我們以int類型作為參數(shù)為例進(jìn)行創(chuàng)建,其創(chuàng)建方法與vector無異

    list<int> l1;           //創(chuàng)建一個空鏈表
    list<int> l2(10);       //創(chuàng)建一個鏈表其有10個空元素
    list<int> l3(5,20);     //創(chuàng)建一個鏈表其有5個元素內(nèi)容為20
    list<int> l4(l3.begin(),l3.end());  //創(chuàng)建一個鏈表其內(nèi)容為l3的內(nèi)容
    list<int> l5(l4);               //創(chuàng)建一個鏈表其內(nèi)容為l4的內(nèi)容

4. 迭代器

遍歷代碼舉例(其方法和vector版本無異只是更加精簡):

    list<int> li;
    for(list<int>::iterator it=li.begin();it!=li.end();it++){
        cout<<*it<<' ';
    }

5. 常用接口

a)判斷是否為空empty()

返回一個bool類型的值药有,只存在真和假毅戈,當(dāng)鏈表為空時為真,不為空時為假

函數(shù)原型

bool empty() const;

b)獲取大小size()

返回鏈表元素的個數(shù)

函數(shù)原型

size_type size() const;

c) 鏈表前插入push_front() &&刪除 pop_front()

push_front()表示在鏈表最前端插入一個數(shù)據(jù)愤惰,pop_front()表示在鏈表最前端刪除一個數(shù)據(jù)苇经。

函數(shù)原型

void push_front (const value_type& val);

void pop_front();

d) 鏈表后插入push_back() &&刪除 pop_back()

push_back()表示在鏈表尾插入一個數(shù)據(jù),pop_back()表示將鏈表尾刪除一個數(shù)據(jù)宦言。

函數(shù)原型:

void push_back (const value_type& val);

void pop_back();

e) 插入insert()

插入元素到指定位置扇单,通過在元素之前在指定位置插入新元素來擴(kuò)展向量,從而有效地增加容器大小所插入的元素數(shù)量奠旺。

函數(shù)原型:

插入單一數(shù)據(jù)到指定位置:

iterator insert (iterator position, const value_type& val);

插入一段數(shù)據(jù)到指定位置:

void insert (iterator position, size_type n, const value_type& val);

插入一段別的容器的數(shù)據(jù)到指定位置:

template <class InputIterator>

void insert (iterator position, InputIterator first, InputIterator last);

f) 刪除erase()

刪除一個元素蜘澜,或者是一段區(qū)間的元素,將會自動縮減空間使用凉倚。

函數(shù)原型:

iterator erase (iterator position);

iterator erase (iterator first, iterator last);

stack棧容器

1. 棧

回顧一下之前所學(xué)的棧,棧是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)嫂沉,而實現(xiàn)方式需要創(chuàng)建多個結(jié)構(gòu)體稽寒,通過鏈?zhǔn)降姆绞竭M(jìn)行實現(xiàn),這是標(biāo)準(zhǔn)的棧的思路趟章,而在STL中椥硬冢可以以更為簡單的方式實現(xiàn)。

2. 頭文件

頭文件 #include<stack>

3. 初始化

格式為:explicit stack (const container_type& ctnr = container_type());

我們以int類型作為參數(shù)為例進(jìn)行創(chuàng)建蚓土,其創(chuàng)建方法與vector無異

stack<int> s;
stack<int> v(s);

標(biāo)準(zhǔn)的棧創(chuàng)建方法是直接創(chuàng)建空棧宏侍,由于棧的特殊性質(zhì),讓他擁有其他容器的參數(shù)可以這樣創(chuàng)建蜀漆,這種多參數(shù)的方式可能有一些復(fù)雜谅河,一般也很少這樣使用。

    vector<int> v(3,100);           
    stack<int,vector<int> > s(v);  //注意确丢,> >符號之間需要有一個空格隔開

通過標(biāo)準(zhǔn)的方式創(chuàng)建向量數(shù)組绷耍,然后通過復(fù)制構(gòu)造函數(shù)的方式進(jìn)行創(chuàng)建,其內(nèi)容就是vector數(shù)組的全部內(nèi)容鲜侥。

4. 迭代器

棧和隊列都屬于一種特殊的數(shù)據(jù)結(jié)構(gòu)褂始,只能通過訪問頂層數(shù)據(jù)并不斷剔除數(shù)據(jù)的方法進(jìn)行全部訪問,因此沒有直接的迭代器描函。

5. 常用接口

我們使用stack<int> s 預(yù)先創(chuàng)建了一個棧崎苗,命名為s狐粱,方便舉例

a)大小size()

返回鏈表元素的個數(shù)

函數(shù)原型:size_type size() const;

b) 返回棧頂元素top()

返回棧頂元素內(nèi)容

函數(shù)原型:

reference& top();

const_reference& top() const;

c) 入棧push()

往棧頂中插入一個元素。

函數(shù)原型: void push (const value_type& val);

d)出棧pop()

將棧頂元素釋放胆数,注意pop()函數(shù)是沒有返回值的肌蜻,如果要想訪問后刪除需要先top再pop使用。

函數(shù)原型:void pop();

s.pop();

e) 判空empty()

返回一個bool類型的值幅慌,只存在真和假宋欺,當(dāng)棧為空時為真,不為空時為假

函數(shù)原型

bool empty() const;

Queue容器

1. 再談隊列

回顧一下之前所學(xué)的隊列胰伍,隊列和棧不同齿诞,隊列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),STL的隊列內(nèi)容極其重要骂租,雖然內(nèi)容較少但是請務(wù)必掌握祷杈,STL的隊列是快速構(gòu)建搜索算法以及相關(guān)的數(shù)論圖論的狀態(tài)存儲的基礎(chǔ)。

2.相關(guān)文件

頭文件:#include<queue>

3.初始化

格式為:

explicit queue (const container_type& ctnr = container_type());

我們以int類型作為參數(shù)為例進(jìn)行創(chuàng)建渗饮。

queue<int> q;    //創(chuàng)建一個空的沒有數(shù)據(jù)的隊列q
queue<int> qoo(q);    //創(chuàng)建一個隊列其元素為q的全部內(nèi)容

標(biāo)準(zhǔn)的隊列創(chuàng)建方法是直接創(chuàng)建空隊列再進(jìn)行其他的操作但汞,由于隊列的特殊性質(zhì),擁有其他容器的參數(shù)可以這樣創(chuàng)建互站,這種多參數(shù)的方式可能有一些復(fù)雜私蕾,一般也很少這樣使用。

vector<int> v(3,100);           
queue<int,vector<int> > s(v);  //注意胡桃,> >符號之間需要有一個空格隔開

通過標(biāo)準(zhǔn)的方式創(chuàng)建向量數(shù)組踩叭,然后通過復(fù)制構(gòu)造函數(shù)的方式進(jìn)行創(chuàng)建,其內(nèi)容就是vector數(shù)組的全部內(nèi)容翠胰。

4. 迭代器

棧和隊列都屬于一種特殊的數(shù)據(jù)結(jié)構(gòu)容贝,只能通過訪問頂層數(shù)據(jù)并不斷剔除數(shù)據(jù)的方法進(jìn)行全部訪問,因此沒有直接的迭代器之景。

5. 常用接口

我們預(yù)先通過queue<int> q創(chuàng)建了一個隊列斤富,命名為q,方便舉例锻狗。

a)大小size()

返回鏈表元素的個數(shù)

函數(shù)原型:size_type size() const;

b) 入隊push()

進(jìn)行入隊操作满力,在隊尾處進(jìn)行插入

函數(shù)原型:void push (const value_type& val);

q.push(100);

c) 出隊pop()

進(jìn)行出隊操作,在對頭出進(jìn)行彈出

函數(shù)原型:void pop();

q.pop();

d)訪問隊頭元素front()

訪問對頭元素轻纪,可以返回其數(shù)值脚囊,也可以進(jìn)行相應(yīng)的操作,這里更加建議多使用front()訪問隊頭數(shù)據(jù)桐磁,因為我們進(jìn)行出隊操作均是從隊頭進(jìn)行出隊的悔耘。

函數(shù)原型:

value_type& front();

const value_type& front() const;

q.front()+=500;   //對隊頭元素進(jìn)行修改

e) 訪問隊尾元素back()

訪問隊尾元素,較為少用我擂。

函數(shù)原型:

value_type& back();

const value_type& back() const;

q.back()+=500;   //對隊尾元素進(jìn)行修改

f) 判空empty()

返回一個bool類型的值衬以,只存在真和假缓艳,當(dāng)隊列為空時為真,不為空時為假

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末看峻,一起剝皮案震驚了整個濱河市阶淘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌互妓,老刑警劉巖溪窒,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異冯勉,居然都是意外死亡澈蚌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門灼狰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宛瞄,“玉大人,你說我怎么就攤上這事交胚》莺梗” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵蝴簇,是天一觀的道長杯活。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任上炎,我火速辦了婚禮,結(jié)果婚禮上均践,老公的妹妹穿的比我還像新娘晤锹。我一直安慰自己摩幔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布鞭铆。 她就那樣靜靜地躺著或衡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪车遂。 梳的紋絲不亂的頭發(fā)上封断,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機(jī)與錄音舶担,去河邊找鬼坡疼。 笑死,一個胖子當(dāng)著我的面吹牛衣陶,可吹牛的內(nèi)容都是我干的柄瑰。 我是一名探鬼主播闸氮,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼教沾!你這毒婦竟也來了蒲跨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤授翻,失蹤者是張志新(化名)和其女友劉穎或悲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堪唐,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡巡语,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了羔杨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捌臊。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兜材,靈堂內(nèi)的尸體忽然破棺而出理澎,到底是詐尸還是另有隱情,我是刑警寧澤曙寡,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布糠爬,位于F島的核電站,受9級特大地震影響举庶,放射性物質(zhì)發(fā)生泄漏执隧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一户侥、第九天 我趴在偏房一處隱蔽的房頂上張望镀琉。 院中可真熱鬧,春花似錦蕊唐、人聲如沸屋摔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钓试。三九已至,卻和暖如春副瀑,著一層夾襖步出監(jiān)牢的瞬間弓熏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工糠睡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留挽鞠,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像信认,于是被迫代替她去往敵國和親串稀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容