List容器

一、List

(1)定義

List是一種序列式容器。List容器完成的功能實際上和數據結構中的雙向鏈表是極其類似的,List中的數據元素是經過鏈表指針串連成邏輯意義上的線性表,也就是List也具備鏈表的主要優勢,即:在鏈表的任一位置進行元素的插入、刪除操做都是快速的。編程

(2)底層實現

List的實現大概是這樣的,相似雙向鏈表,:list的每一個節點有三個域:前驅元素指針域、數據域和後繼元素指針域。數據結構

前驅元素指針域保存了前驅元素的首地址;數據域則是本節點的數據;後繼元素指針域則保存了後繼元素的首地址。其實,List和循環鏈表也有類似的地方,即:頭節點的前驅元素指針域保存的是鏈表中尾元素的首地址,List的尾節點的後繼元素指針域則保存了頭節點的首地址,這樣,List實際上就構成了一個雙向循環鏈。函數

因爲List元素節點並不要求在一段連續的內存中,顯然在List中是不支持快速隨機存取的,所以對於迭代器,只能經過「++」或「--」操做將迭代器移動到後繼/前驅節點元素處。而不能對迭代器進行+n或-n的操做,這點是與vector等不一樣的地方
spa

(3)使用

使用list容器以前必須加上<list>頭文件:#include<list>;指針

List屬於std命名域的內容,所以須要經過命名限定:using std::list;也能夠直接使用全局的命名空間方式:using namespace std。
code

(4)特色

優勢:(1)內存不連續排序

          (2)動態操做,插入與刪除效率高;內存

          (3)可在兩端進行pop,push。rem

缺點:(1)不能隨機訪問;回調函數

          (2)相對於vector佔用內存多(須要存儲前驅後繼元素指針域)

二、成員函數

(1)構造函數

/*構造函數*/
list() 
//聲明一個空列表;
list(n) 
//聲明一個有n個元素的列表,每一個元素都是由其默認構造函數T()構造出來的
list(n,val) 
//聲明一個由n個元素的列表,每一個元素都是由其複製構造函數T(val)得來的
list(n,val) 
//聲明一個和上面同樣的列表
list(first,last) 
//聲明一個列表,其元素的初始值來源於由區間所指定的序列中的元素

(2)賦值操做

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;

(3)插入操做

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;

(4)刪除操做

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;

(5)定位操做

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;

(6)數據大小

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;

(7)交換操做

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;

(8)合併操做

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;

(9)排序操做

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;

(10)重載運算符

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;
}
相關文章
相關標籤/搜索