C++ STL詳解

原文地址: https://www.cnblogs.com/CnZyy/p/3317999.html

一、STL簡(jiǎn)介

STL(Standard Template Library,標(biāo)準(zhǔn)模板庫(kù))是惠普實(shí)驗(yàn)室開(kāi)發(fā)的一系列軟件的統(tǒng)稱。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普實(shí)驗(yàn)室工作時(shí)所開(kāi)發(fā)出來(lái)

的。現(xiàn)在雖說(shuō)它主要出現(xiàn)在C++中,但在被引入C++之前該技術(shù)就已經(jīng)存在了很長(zhǎng)的一段時(shí)間。

STL的代碼從廣義上講分為三類:algorithm(算法)、container(容器)和iterator(迭代器),幾乎所有的代碼都采用了模板類和模版函數(shù)的方式,這相比于傳統(tǒng)的由函數(shù)和類

組成的庫(kù)來(lái)說(shuō)提供了更好的代碼重用機(jī)會(huì)。在C++標(biāo)準(zhǔn)中,STL被組織為下面的13個(gè)頭文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、****<list>、<map>、

<memory>****、<numeric>****、<queue>****、<set>****、<stack>****和<utility>。

二、算法

大家都能取得的一個(gè)共識(shí)是函數(shù)庫(kù)對(duì)數(shù)據(jù)類型的選擇對(duì)其可重用性起著至關(guān)重要的作用。舉例來(lái)說(shuō),一個(gè)求方根的函數(shù),在使用浮點(diǎn)數(shù)作為其參數(shù)類型的情況下的可重用性肯定比

使用整型作為它的參數(shù)類性要高。而C++通過(guò)模板的機(jī)制允許推遲對(duì)某些類型的選擇,直到真正想使用模板或者說(shuō)對(duì)模板進(jìn)行特化的時(shí)候,STL就利用了這一點(diǎn)提供了相當(dāng)多的有用

算法。它是在一個(gè)有效的框架中完成這些算法的——你可以將所有的類型劃分為少數(shù)的幾類,然后就可以在模版的參數(shù)中使用一種類型替換掉同一種類中的其他類型。

STL提供了大約100個(gè)實(shí)現(xiàn)算法的模版函數(shù),比如算法for_each將為指定序列中的每一個(gè)元素調(diào)用指定的函數(shù),stable_sort以你所指定的規(guī)則對(duì)序列進(jìn)行穩(wěn)定性排序等等。這樣一來(lái)

,只要我們熟悉了STL之后,許多代碼可以被大大的化簡(jiǎn),只需要通過(guò)調(diào)用一兩個(gè)算法模板,就可以完成所需要的功能并大大地提升效率。

算法部分主要由頭文件<algorithm>,<numeric>和<functional>組成。

<algorithm>****是所有STL****頭文件中最大的一個(gè)(盡管它很好理解),它是由一大堆模版函數(shù)組成的,可以認(rèn)為每個(gè)函數(shù)在很大程度上都是獨(dú)立的,其中常用到的功能范圍涉及到比較、交換、查找、遍歷操作、復(fù)制、修改、移除、反轉(zhuǎn)、排序、合并等等。

<numeric>****體積很小,只包括幾個(gè)在序列上面進(jìn)行簡(jiǎn)單數(shù)學(xué)運(yùn)算的模板函數(shù),包括加法和乘法在序列上的一些操作。

<functional>****中則定義了一些模板類,用以聲明函數(shù)對(duì)象。

三、容器

在實(shí)際的開(kāi)發(fā)過(guò)程中,數(shù)據(jù)結(jié)構(gòu)本身的重要性不會(huì)遜于操作于數(shù)據(jù)結(jié)構(gòu)的算法的重要性,當(dāng)程序中存在著對(duì)時(shí)間要求很高的部分時(shí),數(shù)據(jù)結(jié)構(gòu)的選擇就顯得更加重要。

經(jīng)典的數(shù)據(jù)結(jié)構(gòu)數(shù)量有限,但是我們常常重復(fù)著一些為了實(shí)現(xiàn)向量、鏈表等結(jié)構(gòu)而編寫的代碼,這些代碼都十分相似,只是為了適應(yīng)不同數(shù)據(jù)的變化而在細(xì)節(jié)上有所出入。STL容器

就為我們提供了這樣的方便,它允許我們重復(fù)利用已有的實(shí)現(xiàn)構(gòu)造自己的特定類型下的數(shù)據(jù)結(jié)構(gòu),通過(guò)設(shè)置一些模版類,STL容器對(duì)最常用的數(shù)據(jù)結(jié)構(gòu)提供了支持,這些模板的參數(shù)

允許我們指定容器中元素的數(shù)據(jù)類型,可以將我們?cè)S多重復(fù)而乏味的工作簡(jiǎn)化。

容器部分主要由頭文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>組成。對(duì)于常用的一些容器和容器適配器(可以看作由其它容器實(shí)現(xiàn)的容器),可以通過(guò)下表總結(jié)一下它們和相應(yīng)頭文件的對(duì)應(yīng)關(guān)系。

向量(vector)連續(xù)存儲(chǔ)的元素<vector>

列表(list)由節(jié)點(diǎn)組成的雙向鏈表,每個(gè)結(jié)點(diǎn)包含著一個(gè)元素<list>

雙隊(duì)列(deque)連續(xù)存儲(chǔ)的指向不同元素的指針?biāo)M成的數(shù)組<deque>

集合(set)由節(jié)點(diǎn)組成的紅黑樹(shù),每個(gè)節(jié)點(diǎn)都包含著一個(gè)元素,節(jié)點(diǎn)之間以某種作用于元素對(duì)的謂詞排列,沒(méi)有兩個(gè)不同的元素能夠擁有相同的次序 <set>

多重集合(multiset) 允許存在兩個(gè)次序相等的元素的集合 <set>

棧(stack)后進(jìn)先出的值的排列 <stack>

隊(duì)列(queue)先進(jìn)先出的執(zhí)的排列 <queue>

優(yōu)先隊(duì)列(priority_queue)元素的次序是由作用于所存儲(chǔ)的值對(duì)上的某種謂詞決定的的一種隊(duì)列 <queue>

映射(map) 由{鍵,值}對(duì)組成的集合,以某種作用于鍵對(duì)上的謂詞排列 <map>

多重映射(multimap)允許鍵對(duì)有相等的次序的映射 <map>

四、迭代器

下面要說(shuō)的迭代器從作用上來(lái)說(shuō)是最基本的部分,可是理解起來(lái)比前兩者都要費(fèi)力一些(至少筆者是這樣)。軟件設(shè)計(jì)有一個(gè)基本原則,所有的問(wèn)題都可以通過(guò)引進(jìn)一個(gè)間接層來(lái)

簡(jiǎn)化,這種簡(jiǎn)化在STL中就是用迭代器來(lái)完成的

。

概括來(lái)說(shuō),迭代器在STL中用來(lái)將算法和容器聯(lián)系起來(lái),起著一種黏和劑的作用。幾乎STL提供的所有算法都是通過(guò)迭代器存取元素序列進(jìn)行工作的,每一個(gè)容器都定義了其本身所專有的迭代器,用以存取容器中的元素。

迭代器部分主要由頭文件<utility>,<iterator>和<memory>組成。

<utility>是一個(gè)很小的頭文件,它包括了貫穿使用在STL****中的幾個(gè)模板的聲明,

<iterator>中提供了迭代器使用的許多方法,而對(duì)于<memory>的描述則十分的困難,它以不同尋常的方式為容器中的元素分配存儲(chǔ)空間,同時(shí)也為某些算法執(zhí)行期間產(chǎn)生的臨時(shí)對(duì)象提供機(jī)制,<memory>中的主要部分是模板類allocator,它負(fù)責(zé)產(chǎn)生所有容器中的默認(rèn)分配器

----------------------------------------------------分割線---------------------------------------------------------------
學(xué)完c++快一年了,感覺(jué)很有遺憾,因?yàn)橐恢睕](méi)有感覺(jué)到c++的強(qiáng)大之處,當(dāng)時(shí)最大的感覺(jué)就是這個(gè)東西的輸入輸出比C語(yǔ)言要簡(jiǎn)單好寫。

后來(lái)我發(fā)現(xiàn)了qt,opencv,opengl,原來(lái),c++好玩的狠。

在這些圖形庫(kù)之外,最常用的可能就是STL,這個(gè)東西由于當(dāng)時(shí)學(xué)c++的時(shí)候迷迷糊糊,完全是一頭霧水,上學(xué)期數(shù)據(jù)結(jié)構(gòu)之后開(kāi)始有點(diǎn)兒開(kāi)竅了,現(xiàn)在把才c++STL中常用的函數(shù),用法貼一下,也是記錄一下,希望能給一樣迷糊的盆友們一些幫助。

整理自《ACM程序設(shè)計(jì)》

迭代器(iterator)

個(gè)人理解就是把所有和迭代有關(guān)的東西給抽象出來(lái)的,不管是數(shù)組的下標(biāo),指針,for里面的、list里面的、vector里面的,抽象一下變成了iterator

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    for(int i = 0; i < 10; ++i )
    {
        v.push_back(i);
    }
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

求和(<numeric> accumulate)

accumulate(v.begin(),v.end(),0),把從 v.begin() 開(kāi)始到 v.end()結(jié)束所有的元素加到 0上面去

#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

int main()
{
    vector<int> v;
    for(int i = 0; i < 10; ++i )
    {
        v.push_back(i);
    }
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
    cout << accumulate(v.begin(),v.end(),0) << endl;
    return 0;
}

vector(動(dòng)態(tài)數(shù)組)

vector有內(nèi)存管理的機(jī)制,也就是說(shuō)對(duì)于插入和刪除,vector可以動(dòng)態(tài)調(diào)整所占用的內(nèi)存空間。

vector相關(guān)函數(shù)

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    v.push_back(3);  //數(shù)組尾部插入3
    v.push_back(2);
    v.push_back(1);
    v.push_back(0);
    cout << " 下標(biāo) " << v[3] << endl;
    cout << " 迭代器 " << endl;
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;
    //在第一個(gè)元素之前插入111  insert begin+n是在第n個(gè)元素之前插入
    v.insert(v.begin(),111);
    //在最后一個(gè)元素之后插入222 insert end + n 是在n個(gè)元素之后插入
    v.insert(v.end(),222);

    for(vector<int>::iterator i = v.begin();i!= v.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;

    vector<int> arr(10);
    for(int i = 0; i < 10; i++)
    {
        arr[i] = i;
    }
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;

    //刪除 同insert
    arr.erase(arr.begin());

    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
     {
        cout << *i << " " ;
     }
    cout << endl ;

    arr.erase(arr.begin(),arr.begin()+5);

    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
    {
        cout << *i << " " ;
    }
    cout << endl ;
    return 0 ;
 }

數(shù)組轉(zhuǎn)置 (<algorithm> reverse)

reverse(v.begin(),v.end())

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main()
{
    vector<int> v;
    for(int i = 0; i < 10; ++i)
    {
        v.push_back(i);
    }
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    reverse(v.begin(),v.end());


    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

排序(<algorithm> sort)

sort(v.begin(),v.end())

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

bool Comp(const int &a,const int &b)
{
    return a>b;
}

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(3);
    v.push_back(2);
    v.push_back(55);
    v.push_back(-1);
    v.push_back(0);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);

    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    //默認(rèn)升序
    sort(v.begin(),v.end());


    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    //用降序 需要自定義一個(gè)降序函數(shù)
    sort(v.begin(),v.end(),Comp);


    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

字符串(<string>)

輸入

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;

int main()
{
    string s1;
    s1 = "hello";

    string s2;
    char s[1024];
    //scanf 輸入速度比cin快的多
    //scanf 是C函數(shù),不可以輸入string
    scanf("%s",s);
    s2 = s;

    cout << s1 << endl;
    cout << s2 << endl;

    return 0;
}
#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    s = "0123456789";
    cout << s << endl;

    string::iterator it = s.begin();

    //刪除s[3]
    s.erase(it+3);
    cout << s << endl;

    //刪除s[1]~s[3]
    s = "0123456789";
    s.erase(it + 1,it + 4);
    cout << s << endl;

    //全部刪除
    s.clear();
    cout << "clear : " << s << endl;

    return 0;
}

查找(find)

用find找到string里面第一個(gè)要找到元素(char或者串),找到返回?cái)?shù)組下標(biāo),找不到返回end()迭代器

string和vector有很多相同的東西,比如length(),size(),empty(),reverse(),相對(duì)也容易,就不一一說(shuō)了。

數(shù)字化處理(string)

經(jīng)常會(huì)遇到這樣一種情況,有一個(gè)數(shù)字,需要把每一位給提取出來(lái),如果用取余數(shù)的方法,花費(fèi)的時(shí)間就會(huì)很長(zhǎng),所以可以當(dāng)成字符串來(lái)處理,方便、省時(shí)。

例子:求一個(gè)整數(shù)各位數(shù)的和

#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    s = "123456789";
    int sum = 0;
    for(int i = 0; i < s.size(); ++i)
    {
        switch(s[i])
        {
            case '1': sum += 1;break;
            case '2': sum += 2;break;
            case '3': sum += 3;break;
            case '4': sum += 4;break;
            case '5': sum += 5;break;
            case '6': sum += 6;break;
            case '7': sum += 7;break;
            case '8': sum += 8;break;
            case '9': sum += 9;break;
        }
    }
    
    cout << sum << endl;
    
    return 0;
}

string與char *

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;

int main()
{
    string s_string;
    char s_char[1000];
    scanf("%s",s_char);

    s_string = s_char;

    //printf輸出char* 時(shí)用c_str處理
    printf(s_string.c_str());
    cout << endl;

    printf("%s",s_char);
    cout << endl;

    cout << s_char << endl;
    cout << s_string << endl;
    return 0;
}

sscanf

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;

int main()
{
    string s1,s2,s3;
    char sa[100],sb[100],sc[100];
    sscanf("abc 123 wcd","%s%s%s",sa,sb,sc);
    s1 = sa;
    s2 = sb;
    s3 = sc;
    cout << s1 << " " << s2 << " " << s3 << endl;

    //將字符串分離成數(shù)字,分隔符為',''$'
    int a,b,c;
    sscanf("4,5$6","%d,%d$%d",&a,&b,&c);
    cout << a << " " << b << " " << c << endl;
    return 0;
}

string與數(shù)值相互轉(zhuǎn)換( sprintf <sstream> )

#include<iostream>
#include<string>
#include<sstream>
#include<cstdio>

using namespace std;

//c++ 方法 把數(shù)轉(zhuǎn)換為string
string converToString(double x)
{
    ostringstream o;
    if( o << x)
    {
        // str()沒(méi)有'\0' c_str有
        return o.str();
    }
    return "error";
}

double converFromString(const string &s)
{
    istringstream i(s);
    double x;
    if( i >> x)
    {
        return x;
    }
    //if error
    return 0.0;
}
int main()
{
    char b[100];
    string s1;

    //c語(yǔ)言方法
    sprintf(b,"%d",1987);
    s1 = b;
    cout << s1 << endl;

    string s2 = converToString(1954);
    cout << s2 << endl;

    string s3 = "202";
    int c = converFromString(s3);
    cout << c << endl;

    string s4 = "casacsa6";
    int d = converFromString(s4);
    cout << d << endl;

    string s5 = "21abf4";
    int f = converFromString(s5);
    cout << f << endl;

    return 0;
}

set容器

set是用紅黑樹(shù)的平衡二叉索引樹(shù)的數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)的,插入時(shí),它會(huì)自動(dòng)調(diào)節(jié)二叉樹(shù)排列,把元素放到適合的位置,確保每個(gè)子樹(shù)根節(jié)點(diǎn)的鍵值大于左子樹(shù)所有的值、小于右子樹(shù)所有的值,插入重復(fù)數(shù)據(jù)時(shí)會(huì)忽略。set迭代器采用中序遍歷,檢索效率高于vector、deque、list,并且會(huì)將元素按照升序的序列遍歷。set容器中的數(shù)值,一經(jīng)更改,set會(huì)根據(jù)新值旋轉(zhuǎn)二叉樹(shù),以保證平衡,構(gòu)建set就是為了快速檢索(python中的set一旦建立就是一個(gè)常量,不能改的)。



  multiset,與set不同之處就是它允許有重復(fù)的鍵值。

正反遍歷,迭代器iterator、reverse_iterator

#include<iostream>
#include<set>

using namespace std;

int main()
{
    set<int> v;
    v.insert(1);
    v.insert(3);
    v.insert(5);
    v.insert(2);
    v.insert(4);
    v.insert(3);

    //中序遍歷 升序遍歷
    for(set<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    for(set<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
    {
        cout << *rit << " ";
    }
    cout << endl;

    return 0;
}

  自定義比較函數(shù),insert的時(shí)候,set會(huì)使用默認(rèn)的比較函數(shù)(升序),很多情況下需要自己編寫比較函數(shù)。

1、如果元素不是結(jié)構(gòu)體,可以編寫比較函數(shù),下面這個(gè)例子是用降序排列的(和上例插入數(shù)據(jù)相同):

#include<iostream>
#include<set>

using namespace std;

struct Comp
{
    //重載()
    bool operator()(const int &a, const int &b)
    {
        return a > b;
    }
};
int main()
{
    set<int,Comp> v;
    v.insert(1);
    v.insert(3);
    v.insert(5);
    v.insert(2);
    v.insert(4);
    v.insert(3);
  
    for(set<int,Comp>::iterator it = v.begin(); it != v.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    for(set<int,Comp>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
    {
        cout << *rit << " ";
    }
    cout << endl;

    return 0;
}

  2、元素本身就是結(jié)構(gòu)體,直接把比較函數(shù)寫在結(jié)構(gòu)體內(nèi)部,下面的例子依然降序:

#include<iostream>
#include<set>
#include<string>

using namespace std;

struct Info
{
    string name;
    double score;

    //重載 <
    bool operator < (const Info &a) const
    {
        return a.score < score;
    }
};
int main()
{
    set<Info> s;
    Info info;

    info.name = "abc";
    info.score = 123.3;
    s.insert(info);

    info.name = "EDF";
    info.score = -23.53;
    s.insert(info);


    info.name = "xyz";
    info.score = 73.3;
    s.insert(info);
    
    for(set<Info>::iterator it = s.begin(); it != s.end(); ++it)
    {
        cout << (*it).name << ":" << (*it).score << endl;
    }
    cout << endl;

    for(set<Info>::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit)
    {
        cout << (*rit).name << ":" << (*rit).score << endl;
    }
    cout << endl;

    return 0;
}

multiset與set的不同之處就是key可以重復(fù),以及erase(key)的時(shí)候會(huì)刪除multiset里面所有的key并且返回刪除的個(gè)數(shù)。


2.png

map

map也是使用紅黑樹(shù),他是一個(gè)鍵值對(duì)(key:value映射),便利時(shí)依然默認(rèn)按照key程序的方式遍歷,同set。


#include<iostream>
#include<map>
#include<string>

using namespace std;

int main()
{
    map<string,double> m;

    //聲明即插入
    m["li"] = 123.4;
    m["wang"] = 23.1;
    m["zhang"] = -21.9;
    m["abc"] = 12.1;
    for(map<string,double>::iterator it = m.begin(); it != m.end(); ++it)
    {
        //first --> key second --> value
        cout << (*it).first << ":" << (*it).second << endl;
    }
    cout << endl;
    return 0;
}

  用map實(shí)現(xiàn)數(shù)字分離

string --> number

之前用string進(jìn)行過(guò)數(shù)字分離,現(xiàn)在使用map

#include<iostream>
#include<map>
#include<string>

using namespace std;

int main()
{
    map<char,int> m;

    m['0'] = 0;
    m['1'] = 1;
    m['2'] = 2;
    m['3'] = 3;
    m['4'] = 4;
    m['5'] = 5;
    m['6'] = 6;
    m['7'] = 7;
    m['8'] = 8;
    m['9'] = 9;
    /*
        等價(jià)于
        for(int i = 0; i < 10; ++i)
        {
            m['0' + i] = i;
        }
    */

    string sa;
    sa = "9876543210";
    int sum = 0;
    for( int i = 0; i < sa.length(); ++i)
    {
        sum += m[sa[i]];
    }
    cout << sum << endl;
    return 0;
}

  number --> string

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<int,char> m;

    for(int i = 0; i < 10; ++i)
    {
        m[i] = '0' + i;
    }

    int n = 7;

    string out = "the number is :";
    cout << out + m[n] << endl;

    return 0;
}

  multimap

multimap由于允許有重復(fù)的元素,所以元素插入、刪除、查找都與map不同。

插入insert(pair<a,b>(value1,value2))

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main()
{
    multimap<string,double> m;

    m.insert(pair<string,double>("Abc",123.2));
    m.insert(pair<string,double>("Abc",123.2));
    m.insert(pair<string,double>("xyz",-43.2));
    m.insert(pair<string,double>("dew",43.2));

    for(multimap<string,double>::iterator it = m.begin(); it != m.end(); ++it )
    {
        cout << (*it).first << ":" << (*it).second << endl;
    }
    cout << endl;

    return 0;
}

至于刪除和查找,erase(key)會(huì)刪除掉所有key的map,查找find(key)返回第一個(gè)key的迭代器

deque

deque和vector一樣,采用線性表,與vector唯一不同的是,deque采用的分塊的線性存儲(chǔ)結(jié)構(gòu),每塊大小一般為512字節(jié),稱為一個(gè)deque塊,所有的deque塊使用一個(gè)Map塊進(jìn)行管理,每個(gè)map數(shù)據(jù)項(xiàng)記錄各個(gè)deque塊的首地址,這樣以來(lái),deque塊在頭部和尾部都可已插入和刪除元素,而不需要移動(dòng)其它元素。使用push_back()方法在尾部插入元素,使用push_front()方法在首部插入元素,使用insert()方法在中間插入元素。一般來(lái)說(shuō),當(dāng)考慮容器元素的內(nèi)存分配策略和操作的性能時(shí),deque相對(duì)vectore更有優(yōu)勢(shì)。(下面這個(gè)圖,我感覺(jué)Map塊就是一個(gè)list< map<deque名字,deque地址> >)



  插入刪除

遍歷當(dāng)然可以使用下標(biāo)遍歷,在這里使用迭代器。

#include <iostream>
#include <deque>

using namespace std;

int main()
{
    deque<int> d;

    //尾部插入
    d.push_back(1);
    d.push_back(3);
    d.push_back(2);
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl << endl;

    //頭部插入
    d.push_front(10);
    d.push_front(-23);
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl << endl;

    d.insert(d.begin() + 2,9999);
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl << endl;

    //反方向遍歷
    for(deque<int>::reverse_iterator rit = d.rbegin(); rit != d.rend(); ++rit )
    {
        cout << (*rit) << " ";
    }
    cout << endl << endl;

    //刪除元素pop pop_front從頭部刪除元素 pop_back從尾部刪除元素 erase中間刪除 clear全刪
    d.clear();
    d.push_back(1);
    d.push_back(2);
    d.push_back(3);
    d.push_back(4);
    d.push_back(5);
    d.push_back(6);
    d.push_back(7);
    d.push_back(8);
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl;

    d.pop_front();
    d.pop_front();
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl;

    d.pop_back();
    d.pop_back();
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl;

    d.erase(d.begin() + 1);
    for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
    {
        cout << (*it) << " ";
    }
    cout << endl;
    return 0;
}

list

list<int> l

插入:push_back尾部,push_front頭部,insert方法前往迭代器位置處插入元素,鏈表自動(dòng)擴(kuò)張,迭代器只能使用++--操作,不能用+n -n,因?yàn)樵夭皇俏锢硐噙B的。

遍歷:iterator和reverse_iterator正反遍歷

刪除:pop_front刪除鏈表首元素;pop_back()刪除鏈表尾部元素;erase(迭代器)刪除迭代器位置的元素,注意只能使用++--到達(dá)想刪除的位置;remove(key) 刪除鏈表中所有key的元素,clear()清空鏈表。

查找:it = find(l.begin(),l.end(),key)

排序:l.sort()

刪除連續(xù)重復(fù)元素:l.unique() 【2 8 1 1 1 5 1】 --> 【 2 8 1 5 1】

bitset

從來(lái)沒(méi)用過(guò),上兩幅圖吧就:




  stack(后進(jìn)先出)

這個(gè)印象深刻,學(xué)數(shù)據(jù)結(jié)構(gòu)的時(shí)候做表達(dá)式求值的就是用的棧。


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

int main()
{

    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(4);
    s.push(5);

    cout << s.size() << endl;

    while(s.empty() != true)
    {
        cout << s.top() << endl;
        s.pop();
    }
    return 0;
}

stack然我唯一費(fèi)解之處在于,貌似它沒(méi)有iterator,可以試試s.begin()編譯器報(bào)錯(cuò)的。

queue(先進(jìn)先出)



  queue有入隊(duì)push(插入)、出隊(duì)pop(刪除)、讀取隊(duì)首元素front、讀取隊(duì)尾元素back、empty,size這幾種方法

priority_queue(最大元素先出)



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

int main()
{

    priority_queue<int> pq;

    pq.push(1);
    pq.push(3);
    pq.push(2);
    pq.push(8);
    pq.push(9);
    pq.push(0);

    cout << "size: " << pq.size() << endl;

    while(pq.empty() != true)
    {
        cout << pq.top() << endl;
        pq.pop();
    }
    return 0;
}

  重載操作符同set重載操作符。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容