由於list和vector同屬於序列式容器,有很多相同的地方,而上一篇中已經寫了vector,所以這一篇着重寫list和vector的不同之處和特有之處。
特別注意的地方:
(1)STL中迭代器容器中都要注意的地方(vector中已經提到):
1)任何時候同時使用兩個迭代器產生的將會是一個前閉后開的區間(具體見插入和刪除的例子)
2)begin()指向的是vec中的第0個元素,而end是指向最后一個元素的后面一個位置(不是最后一個元素)
3)迭代器的時效性,如果一個迭代器所指向的內容已經被刪除,而后又使用該迭代器的話,會造成意想不到的后果
(2)list的迭代器是雙向迭代器(只能++ --,沒有偏移功能)而不是像vector那樣的隨機迭代器(和指針幾乎一樣的所有功能)
(3)list和vector的區別,本質區別:list是鏈式存儲,vector在內存中是連續區別的,有本質區別而導致下面區別
1)list不支持隨機訪問(2)中已經說明,vector可以像數組那樣使用平[]訪問元素,而list是不可以的
2) list的插入和刪除效率很高,所以list有push_front、pop_front、sort而vector中這些操作的效率太低了,所以STL中沒有寫這些功能
3)list的一些特有的函數remove、reverse、unique、splice、merge功能(這些連deque中都沒有的)
下面就是區別於vector的功能的list操作
1 #include<iostream> 2 #include<list> 3 using namespace std; 4 void print(list<int> link) 5 { 6 list<int> ::iterator it; 7 for(it=link.begin();it!=link.end();it++) 8 { 9 cout<<*it<<" "; 10 } 11 cout<<endl; 12 } 13 int main() 14 { 15 //鏈表的初始化是使用指針的,所以使用的是數組的地址 16 //特別注意:vector中已經注意到兩個迭代器形成的區間是前閉后開的 17 int num[10]={0,1,2,3,4,5,6,7,8,9}; 18 list<int> link(&num[0],&num[9]+1); 19 print(link); 20 21 //特別注意list的迭代器是雙向迭代器,而不是vector那樣的隨機迭代器,雙向迭代器沒有偏移能力,只能++ --,不能+5 22 /*例如,下面這兩句就只能在隨機迭代器中用,而不能再雙向迭代器中用 23 list<int> ::iterator it=link.begin(); 24 it=it+3;*/ 25 26 //push操作,vector是在內存中是順序存儲的,如果往頭部添加或者刪除元素效率會非常的低,所以vector中並沒有push_front,pop_front操作, 27 //但鏈表是鏈式存儲的不用擔心這個問題 28 link.push_front(5); 29 print(link); 30 31 //鏈表的刪除操作除了erase之外,還有一個romove。 32 //remove與erase不同,erase是刪除指定位置的節點,而remove是刪除指定值的節點 33 cout<<"刪除第一個元素:"<<endl; 34 link.erase(link.begin()); 35 print(link); 36 cout<<"刪除值為6的所有元素"<<endl; 37 link.remove(6); 38 print(link); 39 40 //排序,list中的排序有直接的函數而不需要使用algorithm里面的函數 41 cout<<"原來的數據:"<<endl; 42 print(link); 43 cout<<"sort之后的數據:"<<endl; 44 link.sort(); 45 print(link); 46 47 //反轉reverse 48 cout<<"原來的數據:"<<endl; 49 print(link); 50 cout<<"reverse之后的數據:"<<endl; 51 link.reverse(); 52 print(link); 53 54 //unique功能去除鏈表中相鄰的重復元素 55 int a[10]={1,1,3,2,2,2,1,1,2,3}; 56 list<int>a_unique(&a[0],&a[9]+1); 57 cout<<"原來的數據:"<<endl; 58 print(a_unique); 59 a_unique.unique(); 60 cout<<"unique之后的數據:"<<endl; 61 print(a_unique); 62 63 //在指定list的迭代器位置上拼接另一個鏈表中另一個迭代器或者另一個迭代器指定的區間的數據 64 //splice 65 int a1[3]={1,3,5}; 66 int a2[3]={2,4,6}; 67 list<int>link1(&a1[0],&a1[2]+1); 68 list<int>link2(&a2[0],&a2[2]+1); 69 cout<<"原來的數據:"<<endl; 70 cout<<"link1:"<<endl; 71 print(link1); 72 cout<<"link2:"<<endl; 73 print(link2); 74 link1.splice(link1.begin(),link2,link2.begin()); 75 cout<<"拼接后的數據:"<<endl; 76 cout<<"link1:"<<endl; 77 print(link1); 78 cout<<"link2:"<<endl; 79 print(link2); 80 81 cout<<"原來的數據:"<<endl; 82 cout<<"link1:"<<endl; 83 print(link1); 84 cout<<"link2:"<<endl; 85 print(link2); 86 link1.splice(link1.end(),link2,link2.begin(),link2.end()); 87 cout<<"拼接后的數據:"<<endl; 88 cout<<"link1:"<<endl; 89 print(link1); 90 cout<<"link2:"<<endl; 91 print(link2); 92 93 //融合兩個排序的list,融合的list依然是排序的 94 int b1[3]={2,4,6}; 95 int b2[3]={1,3,5}; 96 list<int>l1(&b1[0],&b1[2]+1); 97 list<int>l2(&b2[0],&b2[2]+1); 98 cout<<"原來的數據:"<<endl; 99 cout<<"l1:"<<endl; 100 print(l1); 101 cout<<"l2:"<<endl; 102 print(l2); 103 l1.merge(l2); 104 cout<<"融合后的數據"<<endl; 105 cout<<"l1:"<<endl; 106 print(l1); 107 cout<<"l2:"<<endl; 108 print(l2); 109 110 111 //如果需要使用merge融合兩個list,事先需要對兩個list排序 112 //有些書中說融合兩個未排序的list,融合的list也是未排序的 113 //很遺憾,在vs2010中這樣運行會出錯的,如下面這段代碼,雖然編譯通過,但是運行會出錯 114 /*int c1[3]={1,4,4}; 115 int c2[3]={6,3,5}; 116 list<int>lc1(&c1[0],&c1[2]+1); 117 list<int>lc2(&c2[0],&c2[2]+1); 118 cout<<"原來的數據:"<<endl; 119 cout<<"lc1:"<<endl; 120 print(lc1); 121 cout<<"lc2:"<<endl; 122 print(lc2); 123 lc1.merge(lc2); 124 cout<<"融合后的數據"<<endl; 125 cout<<"lc1:"<<endl; 126 print(lc1); 127 cout<<"lc2:"<<endl; 128 print(lc2);*/ 129 return 0; 130 }
由於運行結果在一張截屏沒法截下來了,所以就不貼結果了