1. 程式人生 > >C++ STL詳解

C++ STL詳解

轉載自:http://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html

 一、STL簡介

STL(Standard Template Library,標準模板庫)是惠普實驗室開發的一系列軟體的統稱。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普實驗室工作時所開發出來

的。現在雖說它主要出現在C++中,但在被引入C++之前該技術就已經存在了很長的一段時間。

 

STL的程式碼從廣義上講分為三類:algorithm(演算法)、container(容器)和iterator(迭代器),幾乎所有的程式碼都採用了模板類和模版函式的方式,這相比於傳統的由函式和類

 

組成的庫來說提供了更好的程式碼重用機會。在C++標準中,STL被組織為下面的13個頭檔案:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、

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

二、演算法

大家都能取得的一個共識是函式庫對資料型別的選擇對其可重用性起著至關重要的作用。舉例來說,一個求方根的函式,在使用浮點數作為其引數型別的情況下的可重用性肯定比

使用整型作為它的引數類性要高。而C++通過模板的機制允許推遲對某些型別的選擇,直到真正想使用模板或者說對模板進行特化的時候,STL就利用了這一點提供了相當多的有用

演算法。它是在一個有效的框架中完成這些演算法的——你可以將所有的型別劃分為少數的幾類,然後就可以在模版的引數中使用一種型別替換掉同一種類中的其他型別。

STL提供了大約100個實現演算法的模版函式,比如演算法for_each將為指定序列中的每一個元素呼叫指定的函式,stable_sort以你所指定的規則對序列進行穩定性排序等等。這樣一來

,只要我們熟悉了STL之後,許多程式碼可以被大大的化簡,只需要通過呼叫一兩個演算法模板,就可以完成所需要的功能並大大地提升效率。

 

演算法部分主要由標頭檔案<algorithm>,<numeric>和<functional>組成。

<algorithm>是所有STL標頭檔案中最大的一個(儘管它很好理解),它是由一大堆模版函式組成的,可以認為每個函式在很大程度上都是獨立的,其中常用到的功能範圍涉及到比較、交換、查詢、遍歷操作、複製、修改、移除、反轉、排序、合併等等。

 

<numeric>體積很小,只包括幾個在序列上面進行簡單數學運算的模板函式,包括加法和乘法在序列上的一些操作。

 

<functional>中則定義了一些模板類,用以宣告函式物件。

 

三、容器

在實際的開發過程中,資料結構本身的重要性不會遜於操作於資料結構的演算法的重要性,當程式中存在著對時間要求很高的部分時,資料結構的選擇就顯得更加重要。

經典的資料結構數量有限,但是我們常常重複著一些為了實現向量、連結串列等結構而編寫的程式碼,這些程式碼都十分相似,只是為了適應不同資料的變化而在細節上有所出入。STL容器

就為我們提供了這樣的方便,它允許我們重複利用已有的實現構造自己的特定型別下的資料結構,通過設定一些模版類,STL容器對最常用的資料結構提供了支援,這些模板的引數

允許我們指定容器中元素的資料型別,可以將我們許多重複而乏味的工作簡化。

 

容器部分主要由標頭檔案<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>組成。對於常用的一些容器和容器介面卡(可以看作由其它容器實現的容器),可以通過下表總結一下它們和相應標頭檔案的對應關係。

 

向量(vector) 連續儲存的元素<vector>

列表(list)       由節點組成的雙向連結串列,每個結點包含著一個元素<list>

雙佇列(deque) 連續儲存的指向不同元素的指標所組成的陣列<deque>

集合(set) 由節點組成的紅黑樹,每個節點都包含著一個元素,節點之間以某種作用於元素對的謂詞排列,沒有兩個不同的元素能夠擁有相同的次序 <set>

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

棧(stack) 後進先出的值的排列 <stack>

佇列(queue) 先進先出的執的排列 <queue>

優先佇列(priority_queue) 元素的次序是由作用於所儲存的值對上的某種謂詞決定的的一種佇列 <queue>

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

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

 

四、迭代器

 

下面要說的迭代器從作用上來說是最基本的部分,可是理解起來比前兩者都要費力一些(至少筆者是這樣)。軟體設計有一個基本原則,所有的問題都可以通過引進一個間接層來

簡化,這種簡化在STL中就是用迭代器來完成的

概括來說,迭代器在STL中用來將演算法和容器聯絡起來,起著一種黏和劑的作用。幾乎STL提供的所有演算法都是通過迭代器存取元素序列進行工作的,每一個容器都定義了其本身所專有的迭代器,用以存取容器中的元素。

 

迭代器部分主要由標頭檔案<utility>,<iterator>和<memory>組成。

<utility>是一個很小的標頭檔案,它包括了貫穿使用在STL中的幾個模板的宣告,

<iterator>中提供了迭代器使用的許多方法,而對於<memory>的描述則十分的困難,它以不同尋常的方式為容器中的元素分配儲存空間,同時也為某些演算法執行期間產生的臨時物件提供機制,<memory>中的主要部分是模板類allocator,它負責產生所有容器中的預設分配器

----------------------------------------------------分割線---------------------------------------------------------------

 

以下轉自:http://www.cnblogs.com/duoduo369/archive/2012/04/12/2439118.html

學完c++快一年了,感覺很有遺憾,因為一直沒有感覺到c++的強大之處,當時最大的感覺就是這個東西的輸入輸出比C語言要簡單好寫。

  後來我發現了qt,opencv,opengl,原來,c++好玩的狠。

  在這些圖形庫之外,最常用的可能就是STL,這個東西由於當時學c++的時候迷迷糊糊,完全是一頭霧水,上學期資料結構之後開始有點兒開竅了,現在把才c++STL中常用的函式,用法貼一下,也是記錄一下,希望能給一樣迷糊的盆友們一些幫助。

 

  整理自《ACM程式設計》  

 

  迭代器(iterator)

  個人理解就是把所有和迭代有關的東西給抽象出來的,不管是陣列的下標,指標,for裡面的、list裡面的、vector裡面的,抽象一下變成了iterator

複製程式碼

 1 #include <iostream>
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     vector<int> v;
 9     for(int i = 0; i < 10; ++i )
10     {
11         v.push_back(i);
12     }
13     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
14     {
15         cout << *it << " ";
16     }
17     cout << endl;
18     return 0;
19 }

複製程式碼

 

  

  求和(<numeric> accumulate)

  accumulate(v.begin(),v.end(),0),把從 v.begin() 開始到 v.end()結束所有的元素加到 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(動態陣列)

  vector有記憶體管理的機制,也就是說對於插入和刪除,vector可以動態調整所佔用的記憶體空間。  

  vector相關函式

複製程式碼

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    v.push_back(3);  //陣列尾部插入3
    v.push_back(2);
    v.push_back(1);
    v.push_back(0);
    cout << " 下標 " << v[3] << endl;
    cout << " 迭代器 " << endl;
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;
    //在第一個元素之前插入111  insert begin+n是在第n個元素之前插入
    v.insert(v.begin(),111);
    //在最後一個元素之後插入222 insert end + n 是在n個元素之後插入
    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 ;
 }

複製程式碼

 

 


  陣列轉置 (<algorithm> reverse)

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

複製程式碼

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     vector<int> v;
10     for(int i = 0; i < 10; ++i)
11     {
12         v.push_back(i);
13     }
14     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
15     {
16         cout << *it << " ";
17     }
18     cout << endl;
19 
20     reverse(v.begin(),v.end());
21 
22 
23     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
24     {
25         cout << *it << " ";
26     }
27     cout << endl;
28     return 0;
29 }

複製程式碼

 

  排序(<algorithm> sort)

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

複製程式碼

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 bool Comp(const int &a,const int &b)
 8 {
 9     return a>b;
10 }
11 
12 int main()
13 {
14     vector<int> v;
15     v.push_back(1);
16     v.push_back(3);
17     v.push_back(2);
18     v.push_back(55);
19     v.push_back(-1);
20     v.push_back(0);
21     v.push_back(2);
22     v.push_back(3);
23     v.push_back(4);
24 
25     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
26     {
27         cout << *it << " ";
28     }
29     cout << endl;
30 
31     //預設升序
32     sort(v.begin(),v.end());
33 
34 
35     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
36     {
37         cout << *it << " ";
38     }
39     cout << endl;
40 
41     //用降序 需要自定義一個降序函式
42     sort(v.begin(),v.end(),Comp);
43 
44 
45     for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
46     {
47         cout << *it << " ";
48     }
49     cout << endl;
50 
51     return 0;
52 }

複製程式碼

 

  字串(<string>)

  輸入

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     string s1;
10     s1 = "hello";
11 
12     string s2;
13     char s[1024];
14     //scanf 輸入速度比cin快的多
15     //scanf 是C函式,不可以輸入string
16     scanf("%s",s);
17     s2 = s;
18 
19     cout << s1 << endl;
20     cout << s2 << endl;
21 
22     return 0;
23 }

複製程式碼

 

 

  尾部新增字元字串直接用+號 例如: s += 'a'; s += "abc",或者使用append方法,s.append(“123”)

  刪除 (erase clear)

  s.erase(it + 1,it + 4); clear()

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     string s;
 9     s = "0123456789";
10     cout << s << endl;
11 
12     string::iterator it = s.begin();
13 
14     //刪除s[3]
15     s.erase(it+3);
16     cout << s << endl;
17 
18     //刪除s[1]~s[3]
19     s = "0123456789";
20     s.erase(it + 1,it + 4);
21     cout << s << endl;
22 
23     //全部刪除
24     s.clear();
25     cout << "clear : " << s << endl;
26 
27     return 0;
28 }

複製程式碼

 

  查詢(find)

  用find找到string裡面第一個要找到元素(char或者串),找到返回陣列下標,找不到返回end()迭代器

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

  數字化處理(string)

  經常會遇到這樣一種情況,有一個數字,需要把每一位給提取出來,如果用取餘數的方法,花費的時間就會很長,所以可以當成字串來處理,方便、省時。

  例子:求一個整數各位數的和

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     string s;
 9     s = "123456789";
10     int sum = 0;
11     for(int i = 0; i < s.size(); ++i)
12     {
13         switch(s[i])
14         {
15             case '1': sum += 1;break;
16             case '2': sum += 2;break;
17             case '3': sum += 3;break;
18             case '4': sum += 4;break;
19             case '5': sum += 5;break;
20             case '6': sum += 6;break;
21             case '7': sum += 7;break;
22             case '8': sum += 8;break;
23             case '9': sum += 9;break;
24         }
25     }
26     
27     cout << sum << endl;
28     
29     return 0;
30 }

複製程式碼

 

  string與char *

  

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     string s_string;
10     char s_char[1000];
11     scanf("%s",s_char);
12 
13     s_string = s_char;
14 
15     //printf輸出char* 時用c_str處理
16     printf(s_string.c_str());
17     cout << endl;
18 
19     printf("%s",s_char);
20     cout << endl;
21 
22     cout << s_char << endl;
23     cout << s_string << endl;
24     return 0;
25 }

複製程式碼

 

  sscanf

  

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     string s1,s2,s3;
10     char sa[100],sb[100],sc[100];
11     sscanf("abc 123 wcd","%s%s%s",sa,sb,sc);
12     s1 = sa;
13     s2 = sb;
14     s3 = sc;
15     cout << s1 << " " << s2 << " " << s3 << endl;
16 
17     //將字串分離成數字,分隔符為',''$'
18     int a,b,c;
19     sscanf("4,5$6","%d,%d$%d",&a,&b,&c);
20     cout << a << " " << b << " " << c << endl;
21     return 0;
22 }

複製程式碼

 

  string與數值相互轉換( sprintf <sstream> )

複製程式碼

 1 #include<iostream>
 2 #include<string>
 3 #include<sstream>
 4 #include<cstdio>
 5 
 6 using namespace std;
 7 
 8 //c++ 方法 把數轉換為string
 9 string converToString(double x)
10 {
11     ostringstream o;
12     if( o << x)
13     {
14         // str()沒有'\0' c_str有
15         return o.str();
16     }
17     return "error";
18 }
19 
20 double converFromString(const string &s)
21 {
22     istringstream i(s);
23     double x;
24     if( i >> x)
25     {
26         return x;
27     }
28     //if error
29     return 0.0;
30 }
31 int main()
32 {
33     char b[100];
34     string s1;
35 
36     //c語言方法
37     sprintf(b,"%d",1987);
38     s1 = b;
39     cout << s1 << endl;
40 
41     string s2 = converToString(1954);
42     cout << s2 << endl;
43 
44     string s3 = "202";
45     int c = converFromString(s3);
46     cout << c << endl;
47 
48     string s4 = "casacsa6";
49     int d = converFromString(s4);
50     cout << d << endl;
51 
52     string s5 = "21abf4";
53     int f = converFromString(s5);
54     cout << f << endl;
55 
56     return 0;
57 }

複製程式碼

 

 

  set容器

  set是用紅黑樹的平衡二叉索引樹的資料結構來實現的,插入時,它會自動調節二叉樹排列,把元素放到適合的位置,確保每個子樹根節點的鍵值大於左子樹所有的值、小於右子樹所有的值,插入重複資料時會忽略。set迭代器採用中序遍歷,檢索效率高於vector、deque、list,並且會將元素按照升序的序列遍歷。set容器中的數值,一經更改,set會根據新值旋轉二叉樹,以保證平衡,構建set就是為了快速檢索(python中的set一旦建立就是一個常量,不能改的)。

  multiset,與set不同之處就是它允許有重複的鍵值。

  正反遍歷,迭代器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;
}

複製程式碼

 

  自定義比較函式,insert的時候,set會使用預設的比較函式(升序),很多情況下需要自己編寫比較函式。

  1、如果元素不是結構體,可以編寫比較函式,下面這個例子是用降序排列的(和上例插入資料相同):

複製程式碼

 1 #include<iostream>
 2 #include<set>
 3 
 4 using namespace std;
 5 
 6 struct Comp
 7 {
 8     //過載()
 9     bool operator()(const int &a, const int &b)
10     {
11         return a > b;
12     }
13 };
14 int main()
15 {
16     set<int,Comp> v;
17     v.insert(1);
18     v.insert(3);
19     v.insert(5);
20     v.insert(2);
21     v.insert(4);
22     v.insert(3);
23   
24     for(set<int,Comp>::iterator it = v.begin(); it != v.end(); ++it)
25     {
26         cout << *it << " ";
27     }
28     cout << endl;
29 
30     for(set<int,Comp>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
31     {
32         cout << *rit << " ";
33     }
34     cout << endl;
35 
36     return 0;
37 }

複製程式碼

 

 

  2、元素本身就是結構體,直接把比較函式寫在結構體內部,下面的例子依然降序:

複製程式碼

 1 #include<iostream>
 2 #include<set>
 3 #include<string>
 4 
 5 using namespace std;
 6 
 7 struct Info
 8 {
 9     string name;
10     double score;
11 
12     //過載 <
13     bool operator < (const Info &a) const
14     {
15         return a.score < score;
16     }
17 };
18 int main()
19 {
20     set<Info> s;
21     Info info;
22 
23     info.name = "abc";
24     info.score = 123.3;
25     s.insert(info);
26 
27     info.name = "EDF";
28     info.score = -23.53;
29     s.insert(info);
30 
31 
32     info.name = "xyz";
33     info.score = 73.3;
34     s.insert(info);
35     
36     for(set<Info>::iterator it = s.begin(); it != s.end(); ++it)
37     {
38         cout << (*it).name << ":" << (*it).score << endl;
39     }
40     cout << endl;
41 
42     for(set<Info>::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit)
43     {
44         cout << (*rit).name << ":" << (*rit).score << endl;
45     }
46     cout << endl;
47 
48     return 0;
49 }

複製程式碼

 

  multiset與set的不同之處就是key可以重複,以及erase(key)的時候會刪除multiset裡面所有的key並且返回刪除的個數。

  map

  map也是使用紅黑樹,他是一個鍵值對(key:value對映),便利時依然預設按照key程式的方式遍歷,同set。

複製程式碼

 1 #include<iostream>
 2 #include<map>
 3 #include<string>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     map<string,double> m;
10 
11     //宣告即插入
12     m["li"] = 123.4;
13     m["wang"] = 23.1;
14     m["zhang"] = -21.9;
15     m["abc"] = 12.1;
16     for(map<string,double>::iterator it = m.begin(); it != m.end(); ++it)
17     {
18         //first --> key second --> value
19         cout << (*it).first << ":" << (*it).second << endl;
20     }
21     cout << endl;
22     return 0;
23 }

複製程式碼

 

  用map實現數字分離

  string --> number

  之前用string進行過數字分離,現在使用map

複製程式碼

 1 #include<iostream>
 2 #include<map>
 3 #include<string>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     map<char,int> m;
10 
11     m['0'] = 0;
12     m['1'] = 1;
13     m['2'] = 2;
14     m['3'] = 3;
15     m['4'] = 4;
16     m['5'] = 5;
17     m['6'] = 6;
18     m['7'] = 7;
19     m['8'] = 8;
20     m['9'] = 9;
21     /*
22         等價於
23         for(int i = 0; i < 10; ++i)
24         {
25             m['0' + i] = i;
26         }
27     */
28 
29     string sa;
30     sa = "9876543210";
31     int sum = 0;
32     for( int i = 0; i < sa.length(); ++i)
33     {
34         sum += m[sa[i]];
35     }
36     cout << sum << endl;
37     return 0;
38 }

複製程式碼

 

  number --> string

複製程式碼

 1 #include <iostream>
 2 #include <map>
 3 #include <string>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     map<int,char> m;
10 
11     for(int i = 0; i < 10; ++i)
12     {
13         m[i] = '0' + i;
14     }
15 
16     int n = 7;
17 
18     string out = "the number is :";
19     cout << out + m[n] << endl;
20 
21     return 0;
22 }

複製程式碼

 

  multimap

  multimap由於允許有重複的元素,所以元素插入、刪除、查詢都與map不同。

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

複製程式碼

 1 #include <iostream>
 2 #include <map>
 3 #include <string>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     multimap<string,double> m;
10 
11     m.insert(pair<string,double>("Abc",123.2));
12     m.insert(pair<string,double>("Abc",123.2));
13     m.insert(pair<string,double>("xyz",-43.2));
14     m.insert(pair<string,double>("dew",43.2));
15 
16     for(multimap<string,double>::iterator it = m.begin(); it != m.end(); ++it )
17     {
18         cout << (*it).first << ":" << (*it).second << endl;
19     }
20     cout << endl;
21 
22     return 0;
23 }

複製程式碼

 

  至於刪除和查詢,erase(key)會刪除掉所有key的map,查詢find(key)返回第一個key的迭代器

  deque

  deque和vector一樣,採用線性表,與vector唯一不同的是,deque採用的分塊的線性儲存結構,每塊大小一般為512位元組,稱為一個deque塊,所有的deque塊使用一個Map塊進行管理,每個map資料項記錄各個deque塊的首地址,這樣以來,deque塊在頭部和尾部都可已插入和刪除元素,而不需要移動其它元素。使用push_back()方法在尾部插入元素,使用push_front()方法在首部插入元素,使用insert()方法在中間插入元素。一般來說,當考慮容器元素的記憶體分配策略和操作的效能時,deque相對vectore更有優勢。(下面這個圖,我感覺Map塊就是一個list< map<deque名字,deque地址> >)

  插入刪除

  遍歷當然可以使用下標遍歷,在這裡使用迭代器。

複製程式碼

 1 #include <iostream>
 2 #include <deque>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     deque<int> d;
 9 
10     //尾部插入
11     d.push_back(1);
12     d.push_back(3);
13     d.push_back(2);
14     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
15     {
16         cout << (*it) << " ";
17     }
18     cout << endl << endl;
19 
20     //頭部插入
21     d.push_front(10);
22     d.push_front(-23);
23     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
24     {
25         cout << (*it) << " ";
26     }
27     cout << endl << endl;
28 
29     d.insert(d.begin() + 2,9999);
30     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
31     {
32         cout << (*it) << " ";
33     }
34     cout << endl << endl;
35 
36     //反方向遍歷
37     for(deque<int>::reverse_iterator rit = d.rbegin(); rit != d.rend(); ++rit )
38     {
39         cout << (*rit) << " ";
40     }
41     cout << endl << endl;
42 
43     //刪除元素pop pop_front從頭部刪除元素 pop_back從尾部刪除元素 erase中間刪除 clear全刪
44     d.clear();
45     d.push_back(1);
46     d.push_back(2);
47     d.push_back(3);
48     d.push_back(4);
49     d.push_back(5);
50     d.push_back(6);
51     d.push_back(7);
52     d.push_back(8);
53     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
54     {
55         cout << (*it) << " ";
56     }
57     cout << endl;
58 
59     d.pop_front();
60     d.pop_front();
61     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
62     {
63         cout << (*it) << " ";
64     }
65     cout << endl;
66 
67     d.pop_back();
68     d.pop_back();
69     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
70     {
71         cout << (*it) << " ";
72     }
73     cout << endl;
74 
75     d.erase(d.begin() + 1);
76     for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
77     {
78         cout << (*it) << " ";
79     }
80     cout << endl;
81     return 0;
82 }

複製程式碼

 

  list

  list<int> l

  插入:push_back尾部,push_front頭部,insert方法前往迭代器位置處插入元素,連結串列自動擴張,迭代器只能使用++--操作,不能用+n -n,因為元素不是物理相連的。

  遍歷:iterator和reverse_iterator正反遍歷

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

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

  排序:l.sort()

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

  bitset

  從來沒用過,上兩幅圖吧就:

  stack(後進先出)

  這個印象深刻,學資料結構的時候做表示式求值的就是用的棧。

複製程式碼

 1 #include <iostream>
 2 #include <stack>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7 
 8     stack<int> s;
 9     s.push(1);
10     s.push(2);
11     s.push(4);
12     s.push(5);
13 
14     cout << s.size() << endl;
15 
16     while(s.empty() != true)
17     {
18         cout << s.top() << endl;
19         s.pop();
20     }
21     return 0;
22 }

複製程式碼

 

 

  stack然我唯一費解之處在於,貌似它沒有iterator,可以試試s.begin()編譯器報錯的。

  queue(先進先出)

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

  priority_queue(最大元素先出)

 

 

 

複製程式碼

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7 
 8     priority_queue<int> pq;
 9 
10     pq.push(1);
11     pq.push(3);
12     pq.push(2);
13     pq.push(8);
14     pq.push(9);
15     pq.push(0);
16 
17     cout << "size: " << pq.size() << endl;
18 
19     while(pq.empty() != true)
20     {
21         cout << pq.top() << endl;
22         pq.pop();
23     }
24     return 0;
25 }

複製程式碼

 

  過載操作符同set過載操作符。