List是一種序列式容器。List容器完成的功能實際上和數據結構中的雙向鏈表是極其類似的,List中的數據元素是經過鏈表指針串連成邏輯意義上的線性表,也就是List也具備鏈表的主要優勢,即:在鏈表的任一位置進行元素的插入、刪除操做都是快速的。編程
List的實現大概是這樣的,相似雙向鏈表,:list的每一個節點有三個域:前驅元素指針域、數據域和後繼元素指針域。數據結構
前驅元素指針域保存了前驅元素的首地址;數據域則是本節點的數據;後繼元素指針域則保存了後繼元素的首地址。其實,List和循環鏈表也有類似的地方,即:頭節點的前驅元素指針域保存的是鏈表中尾元素的首地址,List的尾節點的後繼元素指針域則保存了頭節點的首地址,這樣,List實際上就構成了一個雙向循環鏈。函數
因爲List元素節點並不要求在一段連續的內存中,顯然在List中是不支持快速隨機存取的,所以對於迭代器,只能經過「++」或「--」操做將迭代器移動到後繼/前驅節點元素處。而不能對迭代器進行+n或-n的操做,這點是與vector等不一樣的地方。
spa
使用list容器以前必須加上<list>頭文件:#include<list>;指針
List屬於std命名域的內容,所以須要經過命名限定:using std::list;也能夠直接使用全局的命名空間方式:using namespace std。
code
優勢:(1)內存不連續;排序
(2)動態操做,插入與刪除效率高;內存
(3)可在兩端進行pop,push。rem
缺點:(1)不能隨機訪問;回調函數
(2)相對於vector佔用內存多(須要存儲前驅後繼元素指針域)。
/*構造函數*/ list() //聲明一個空列表; list(n) //聲明一個有n個元素的列表,每一個元素都是由其默認構造函數T()構造出來的 list(n,val) //聲明一個由n個元素的列表,每一個元素都是由其複製構造函數T(val)得來的 list(n,val) //聲明一個和上面同樣的列表 list(first,last) //聲明一個列表,其元素的初始值來源於由區間所指定的序列中的元素
assign(): //具體和vector中的操做相似,也是有兩種狀況: //第一種是:l1.assign(n,val)將 l1中元素變爲n個T(val); //第二種狀況是:l1.assign(l2.begin(),l2.end())將l2中的從l2.begin()到l2.end()之間的數值賦值給l1 c.assign(n,num); //將n個num拷貝賦值給鏈表c。 c.assign(beg,end); //將[beg,end)區間的元素拷貝賦值給鏈表c。
示例:
int a[5] = {1,2,3,4,5}; list<int> a1; list<int>::iterator it; a1.assign(2,10); for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.assign(a,a+5); for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
push_back(); //push_back()從list的末端插入 push_front(): //push_front()實現的從list的頭部插入 insert(): //在指定位置插入一個或多個元素(三個重載) c.insert(pos,num); //在pos位置插入元素num。 c.insert(pos,n,num); //在pos位置插入n個元素num。 c.insert(pos,beg,end); //在pos位置插入區間爲[beg,end)的元素。
示例:
list<int> a1{1,2,3,4,5}; list<int>::iterator it; cout << "insert before:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.insert(a1.begin(),0); cout << "insert(pos,num) after:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.insert(a1.begin(),2,88); cout << "insert(pos,n,num) after:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; int arr[5] = {11,22,33,44,55}; a1.insert(a1.begin(),arr,arr+3); cout << "insert(pos,beg,end) after:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,2,3,4,5}; a1.push_back(10); list<int>::iterator it; cout << "push_back:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.pop_back(); cout << "pop_back:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.push_front(20); cout << "push_front:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.pop_front(); cout << "pop_front:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
pop_back(); //經過pop_front()刪除第一個元素 pop_front(): //刪除最後一個元素 //序列必須不爲空,若是當list爲空的時候調用pop_back()和pop_front()會使程序崩掉。 clear(): //清空list中的全部元素。 erase(): //刪除一個元素或一個區域的元素(兩個重載) l1.erase(l1.begin()); //將l1的第一個元素刪除。 l1.erase(l1.begin(),l1.end()); //將l1的從begin()到end()之間的元素刪除。 remove(num); //刪除鏈表中匹配num的元素 remove_if(comp); //刪除條件知足的元素,參數爲自定義的回調函數 unique(); //刪除相鄰的元素
示例:
list<int> a1{1,2,3,4,5}; list<int>::iterator it; cout << "clear before:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << "\t"; } cout << endl; a1.clear(); cout << "clear after:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << "\t"; } cout << endl;
list<int> a1{1,2,3,4,5}; list<int>::iterator it; cout << "erase before:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.erase(a1.begin()); cout << "erase after:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,2,3,4,5}; a1.remove(3); list<int>::iterator it; cout << "remove():"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,2,3,4,5}; a1.remove_if([](int n){return n<3;}); list<int>::iterator it; cout << "remove_if():"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,1,3,3,5}; a1.unique(); list<int>::iterator it; cout << "unique:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; return 0;
begin(); //經過調用list容器的成員函數begin()獲得一個指向容器起始位置的iterator end():, //調用list容器的 end()函數來獲得list末端下一位置,至關於:int a[n]中的第n+1個位置a[n], //其實是不存在的,不能訪問,常常做爲循環結束判斷結束條件使用。 c.rbegin(); //返回逆向鏈表的第一個元素,即c鏈表的最後一個數據。 c.rend(); //返回逆向鏈表的最後一個元素的下一個位置,即c鏈表的第一個數據再往前的位置。 front(); //經過front()能夠得到list容器中的頭部元素 back(): , //經過back()能夠得到list容器的最後一個元素 //可是有一點要注意,就是list中元素是空的時候,這時候調用front()和back()會發生什麼呢? //實際上會發生不能正常讀取數據的狀況,可是這並不報錯,那咱們編程序時就要注意了,建議在使用以前最好先調用empty()函數判斷list是否爲空。 reverse(): //經過reverse()完成list的逆置。
示例:
list<int> a1{1,2,3,4,5}; list<int>::iterator it; for(it = a1.begin();it!=a1.end();it++){ cout << *it << "\t"; } cout << endl;
list<int> a1{1,2,3,4,5}; list<int>::reverse_iterator it; for(it = a1.rbegin();it!=a1.rend();it++){ cout << *it << "\t"; } cout << endl;
list<int> a1{1,2,3,4,5}; if(!a1.empty()){ cout << "the first number is:" << a1.front() << endl; cout << "the last number is:" << a1.back() << endl; }
list<int> a1{1,2,3,4,5}; a1.reverse(); list<int>::iterator it; cout << "reverse:"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
empty(): //利用empty() 判斷list是否爲空。 resize(): //若是調用resize(n)將list的長度改成只容納n個元素,超出的元素將被刪除, //若是須要擴展那麼調用默認構造函數T()將元素加到list末端。 //若是調用resize(n,val),則擴展元素要調用構造函數T(val)函數進行元素構造,其他部分相同。 c.size(); //返回鏈表c中實際元素的個數。 c.max_size(); //鏈表c可能容納的最大元素數量。
示例:
list<int> a1{1,2,3,4,5}; a1.resize(8); list<int>::iterator it; cout << "resize(n):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.resize(10, 10); cout << "resize(n,num):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
swap():交換兩個鏈表(兩個重載),一個是l1.swap(l2); 另一個是swap(l1,l2),均可能完成連個鏈表的交換。 c1.swap(c2); 將c1和c2交換。 swap(c1,c2); 同上。
示例:
list<int> a1{1,2,3,4,5},a2,a3; a2.swap(a1); list<int>::iterator it; cout << "a2.swap(a1):"; for(it = a2.begin();it!=a2.end();it++){ cout << *it << " "; } cout << endl; swap(a3,a2); cout << "swap(a3,a2):"; for(it = a3.begin();it!=a3.end();it++){ cout << *it << " "; } return 0;
merge(): //合併兩個鏈表並使之默認升序(也可改),l1.merge(l2,greater<int>()); //調用結束後l2變爲空,l1中元素包含原來l1 和 l2中的元素,而且排好序,升序。 //其實默認是升序,greater<int>()能夠省略,另外greater<int>()是能夠變的,也能夠不按升序排列。 c1.merge(c2); //合併2個有序的鏈表並使之有序,重新放到c1裏,釋放c2。 c1.merge(c2,comp); //合併2個有序的鏈表並使之按照自定義規則排序以後重新放到c1中,釋放c2。 c1.splice(c1.beg,c2); // 將c2鏈接在c1的beg位置,釋放c2 c1.splice(c1.beg,c2,c2.beg); //將c2的beg位置的元素鏈接到c1的beg位置,而且在c2中施放掉beg位置的元素 c1.splice(c1.beg,c2,c2.beg,c2.end); //c2的[beg,end)位置的元素鏈接到c1的beg位置而且釋放c2的[beg,end)位置的元素
示例:
list<int> a1{1,2,3},a2{4,5,6}; a1.merge(a2); list<int>::iterator it; cout << "a1.merge(a2):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a2.merge(a1,[](int n1,int n2){return n1>n2;}); cout << "a2.merge(a1,comp):"; for(it = a2.begin();it!=a2.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,2,3},a2{4,5,6}; a1.splice(a1.begin(), a2); list<int>::iterator it; cout << "a1.merge(a2):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
list<int> a1{1,2,3},a2{4,5,6}; a1.splice(a1.begin(), a2,++a2.begin()); list<int>::iterator it; cout << "a1.merge(a2):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; return 0;
list<int> a1{1,2,3},a2{4,5,6}; a1.splice(a1.begin(),a2,a2.begin(),a2.end()); list<int>::iterator it; cout << "a1.merge(a2):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; return 0;
c.sort() 將鏈表排序,默認升序 c.sort(comp) 自定義回調函數實現自定義排序
示例:
list<int> a1{1,3,2,5,4}; a1.sort(); list<int>::iterator it; cout << "sort():"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl; a1.sort([](int n1,int n2){return n1>n2;}); cout << "sort(function point):"; for(it = a1.begin();it!=a1.end();it++){ cout << *it << " "; } cout << endl;
operator== operator!= operator< operator<= operator> operator>=
示例:
list<int> a1 {1,2,3,4,5},a2; a2 = a1; list<int>::iterator it; for(it = a2.begin();it!=a2.end();it++){ cout << *it << endl; }