C++中的 list(清單)是順序容器,其中存儲的元素并不是記憶體連續的,這一點和上一節讨論的 deque 是類似的。
C++中的 list 容器類
list 容器類的特點
稍後幾節将要讨論的C++中的 vector(向量)容器中的元素在記憶體中是連續存儲的,這一點恰好和 list 相反。元素相鄰存儲的好處是随機通路非常友善,可以像類似于C語言數組那樣通過下标通路各個元素,但是插入元素開銷就比較大了,因為每插入一個元素,都必須移動其他所有元素。
而C++中的 list 則客服了 vector 容器的這個缺點,它允許程式員在 list 的任意位置插入元素,而不會造成很大的開銷。不過,就随機通路而言,list 比 vector 慢。
list 的聲明與初始化
在C++程式開發中使用 list 容器類是非常友善的,隻需要在程式開頭包含 頭檔案就可以了:
#include
list 容器類在 std 命名空間中,是以聲明一個 list 容器類對象可以按照下面這種方式:
std::list obj;
其中 objType 表示資料類型,它可以是任意類型,也可以是一個類,甚至可以是 list 本身,例如:
std::list i;std::list<:list>> li;
我們可以在定義 list 容器類對象時對其初始化(需要c++11支援),例如下面這段C++代碼:
std::list mylist = {1, 1, 2, 3, 5};
上面這樣的初始化将在 mylist 中填充資料,如前文所述,這些資料元素在記憶體中的分布不是連續的,倒是有些像連結清單:
資料元素在記憶體中的分布不是連續的
一旦定義好 list 容器類對象并且初始化完畢,我們就可以通過疊代器通路其中的元素了。疊代器可以通過成員函數 begin() 和 end() 輔助使用,下面是一個例子,請看:
#include #include #include #include using namespace std;int main(){ list mylist = {1, 1, 2, 3, 5}; cout<::iterator it; for(it=mylist.begin();it!=mylist.end();++it) cout<
疊代器的使用
編譯并執行上述C++代碼,可以得到如下輸出:
List elements are: 1 1 2 3 5
從代碼可以看出,疊代器 it 本質上是一個指針,它在 for() 循環中的使用,和常用的整型循環變量在 for() 中的使用非常類似,唯一的差別就是使用 begin() 函數作為起點,end() 函數作為終點。
C++中的 list 容器類也可以倒序周遊,隻需将begin()函數和end()函數換成 rbegin() 和 rend() 函數就可以了,這一點和上一節介紹的的 deque 容器類是類似的,不再贅述了。
list 容器類的成員函數
list 容器類的成員函數
insert() 函數
insert() 函數
它可以将給定的元素插入到 list 的指定位置,傳回值是一個疊代器,指向最開始插入的元素位置。典型用法如下:
insert(pos, num_elem, elem)
其中 pos 表示将要插入的位置;num_elem 表示要插入的元素數,預設是 1;elem 則表示要插入的元素。下面是一段典型的C++代碼執行個體,請看:
#include #include using namespace std;int main(){ list mylist = {1,1,2}; list::iterator it = mylist.begin(); // 疊代器指向第 2 個位置 advance(it, 1); // 将元素 3 插入疊代器指向的位置 mylist.insert(it, 3); cout << "The list after inserting 1 element using insert() is : "; for (list::iterator i = mylist.begin();i != mylist.end();i++) cout << *i << " "; cout << endl; return 0;}
insert() 函數
代碼很簡單,我們先指定要插入元素的位置(通過疊代器),然後即可調用 insert() 成員函數将元素 3 插入。編譯并執行上述C++代碼,可以得到如下輸出,請看:
# g++ t1.cpp --std=c++11# ./a.outThe list after inserting 1 element using insert() is : 1 3 1 2
可以看出,這裡我們僅将元素 3 插入 1 次,若希望插入多次,則可以通過 insert() 函數的第二個參數指定:
...mylist.insert(it, 2, 3);...
此時再編譯并執行修改後的C++代碼,可以得到 1 3 3 1 2 的輸出。
push_back() 和 push_front() 函數
push_back() 和 push_front() 函數
list 容器類是一個雙向的清單類,是以可以雙向插入。push_back() 函數可以将元素插入到 list 容器的尾部,而 push_front() 函數則可以将元素插入到 list 容器的頭部。下面這段C++代碼是一個簡單的執行個體:
#include #include #include #include using namespace std;void printlist(list mylist){ list :: iterator it; for(it = mylist.begin(); it != mylist.end(); ++it) cout < mylist = {1, 1, 2, 3}; cout<
push_back() 和 push_front() 函數
編譯并執行這段C++代碼,可以得到如下輸出:
# g++ t.cpp --std=c++11# ./a.out List elements are: 1 1 2 3 List contents after push_front and push_back: 0 1 1 2 3 5
pop_back() 和 pop_front() 函數
pop_back() 和 pop_front() 函數
這兩個函數的功能恰好分别和 push_back() 與 push_front() 函數的功能反過來,pop_back() 函數可以将 list 的尾部元素删除,而 pop_front() 函數則可以将 list 的頭部元素删除,顯然,在元素頭部或者尾部元素被删除後,list 的長度會減少。下面是一段C++代碼示例:
#include #include #include using namespace std;void printlist(list mylist){ list :: iterator it; for(it = mylist.begin(); it != mylist.end(); ++it) cout < mylist = {1, 1, 2, 3, 5}; cout<
pop_back() 和 pop_front() 函數
編譯并執行這段C++代碼,得到如下輸出:
List elements are: 1 1 2 3 5List contents after push_front and push_back: 1 2 3
size(),empty(),erase(),clear() 函數
size(),empty(),erase(),clear() 函數
list 容器類的 size() 成員函數傳回容器内所有元素的個數,empty() 傳回容器是否為空,erase() 函數則可以從 list 中删除某個元素,clear() 函數可以删除 list 容器中所有的元素。下面是一段C++代碼示例,請看:
#include #include #include using namespace std;void printlist(list mylist){ list :: iterator it; for(it = mylist.begin(); it != mylist.end(); ++it) cout < mylist = {1, 1, 2, 3, 5}; cout<::iterator it = mylist.begin(); if(!(mylist.empty())){ mylist.erase(it); cout<
size(),empty(),erase(),clear() 函數
編譯并執行上述C++代碼,得到如下輸出,請看:
List elements are: 1 1 2 3 5 size of the list: 5List after erase first element: 1 2 3 5 New size of the list: 4
front(),back(),swap(),reverse(),sort()函數
front(),back(),swap(),reverse(),sort()函數
其實這些函數的功能能夠直接通過它們的名字看出:front() 和 back() 函數分别傳回 list 的頭部和尾部元素,swap() 和 reverse() 函數則分别可以交換和反轉 list,sort() 函數則提供了排序功能。下面是一段C++代碼示例:
#include #include #include using namespace std;void printlist(list mylist){ list :: iterator it; for(it = mylist.begin(); it != mylist.end(); ++it) cout < mylist = {1, 1, 2, 3, 5}; cout< oddlist = {1,5,9,3,7}; oddlist.sort(); cout<
front(),back(),swap(),reverse(),sort()函數
編譯并執行這段C++代碼,得到如下輸出:
List elements are: 1 1 2 3 5 Front of the list: 1Back of the list: 5Reversed List: 5 3 2 1 1 Contents of odd list:1 3 5 7 9 After swapping mylist: 1 3 5 7 9 Oddlist : 5 3 2 1 1
小結
小結
本節主要介紹了C++标準容器類 list 的基本特點,并且結合一些執行個體說明了 list 容器類的基本用法,希望對讀者有所幫助。