一、概述
list使用一個雙向鏈表來管理數據。使用list必須含入頭文件<list>,其型別定義如下:
namespace std{
template <class T,
class Allocator = allocator<T> >
class list;
}
list不支持隨機存取,所以既不提供下標操作符,也不提供at()。list相較於vector的好處是每次插入或者刪除一個元素,就配置或者釋放一個元素空間。對於任何位置的元素插入或元素移除,list永遠是常數時間。
二、list內部結構
list本身和list節點是不同的結構,需要分開設計,STL list節點結構如下:
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer prev;
void_pointer next;
}
SGI list不僅是一個雙向鏈表,而且還是一個環狀雙向鏈表,結構圖如下
三、list的操作函數
1. 生成、複製和銷燬
操作 | 效果 |
---|---|
list<Elem> c | 產生一個存放Elem類型元素的空list |
list<Elem> c1(c2) | 產生一個與c2同型的list,每個元素都被複制 |
list<Elem> c(n) | 產生一個含有n個元素,以default構造函數產生元素的list |
list<Elem> c(n,elem) | 產生一個含有n個elem元素的list |
list<Elem> c(beg,end) | 產生一個以區間[beg,end]內元素爲初值的list |
c.~list<Elem>() | 銷燬所有元素,釋放內存 |
2. 非變動性操作
操作 | 效果 |
---|---|
c.size() | 返回元素個數。 |
c.empty() | 判斷容器大小是否爲0。 |
c.max_size() | 返回可容納元素最大數量 |
c1 == c2 | 判斷c1是否等於c2 |
c1 != c2 | 判斷c1是否不等於c2 |
c1 < c2 | 判斷c1是否小於c2 |
c1 > c2 | 判斷c1是否大於c2 |
c1 <= c2 | 判斷c1是否小於等於c2 |
c1 >= c2 | 判斷c1是否大於等於c2 |
c.front() | 返回第一個元素,不檢查元素是否存在 |
c.back() | 返回最後一個元素,不檢查元素是否存在 |
c.begin() | 返回一個隨機存取迭代器,指向第一元素 |
c.end() | 返回一個隨機存取迭代器,指向最後一個元素的下一位置 |
c.rbegin() | 返回一個逆向迭代器,指向逆向迭代時的第一個元素 |
c.rend() | 返回一個逆向迭代器,指向逆向迭代時最後元素的下一位置 |
3. 賦值操作
操作 | 效果 |
---|---|
c1 = c2 | 將c2的全部元素賦值給c1。 |
c.assign(n,elem) | 將elem的n個拷貝賦值給c。 |
c.assign(beg,end) | 將區間[beg,end]的元素賦值給c |
c1.swap(c2) | 將c1和c2元素互換 |
swap(c1,c2) | 同上,此爲全局函數 |
4. 元素存取操作
操作 | 效果 |
---|---|
c.front() | 返回c的第一個元素,不檢查元素存在與否 |
c.back() | 返回c的最後一個元素,不檢查元素存在與否 |
5. 迭代器函數
list迭代器不支持隨機存取,這些迭代器只是雙向迭代器。
操作 | 效果 |
---|---|
c.begin() | 返回一個雙向迭代器,指向第一個元素 |
c.end() | 返回一個雙迭代器,指向最後一個元素的下一位置 |
c.rbegin() | 返回一個逆向迭代器,指向逆向迭代的第一個元素 |
c.rend() | 返回一個逆向迭代器,指向逆向迭代的最後元素的下一位置 |
6. 元素的安插和移除
操作 | 效果 |
---|---|
c.insert(pos,elem) | 在pos位置插入一個elem副本,返回新元素的位置 |
c.insert(pos,n,elem) | 在pos位置插入n個elem副本,無返回值 |
c.insert(pos,beg,end) | 在pos位置插入區間[beg,end]內的元素,無返回值 |
c.push_back(elem) | 在尾部添加一個elem的副本 |
c.pop_back() | 移除最後一個元素,不回傳 |
c.push_front(elem) | 在頭部插入一個elem副本 |
c.pop_front() | 移除頭部元素,不回傳 |
c.remove(val) | 移除所有值爲val的元素 |
c.remove_if(op) | 移除所有造成op(elem)結果爲true的元素 |
c.erase(pos) | 移除pos位置所指元素,返回下一元素的位置 |
c.erase(beg,end) | 移除區間[beg,end]內的元素,返回下一元素的位置 |
c.resize(num) | 將大小改爲num。如果size增長了,新增大小以default構造函數產生出來 |
c.resize(num,elem) | 將大小改爲num。如果size增長了,新增大小以elem副本產生出來 |
c.clear() | 移除所有元素,將容器清空 |
7. 特殊變動性操作
操作 | 效果 |
---|---|
c.unique() | 如果存在若干相鄰而數值相等的元素,則移除重複元素,只留下一個 |
c.unique(op) | 如果存在若干個相鄰元素都使op()的結果爲true,則移除重複元素,只留下一個 |
c.splice(pos,c2) | 將c2內的所有元素轉移到c1內、迭代器pos之前 |
c.splice(pos,c2,c2pos) | 將c2內的c2pos所指元素轉移到c1內的pos所指的位置上,c1和c2可以相同 |
c.splice(pos,c2,c2beg,c2end) | 將c2內的[c2beg,c2end]區間所有元素轉移到c1內的pos之前 |
c.sort() | 以operator<爲準則對所有元素排序 |
c.sort(op) | 以op()爲準則對所有元素排序 |
c.merge(c2) | 假設c1和c2內的元素已序,將c2內的全部元素轉移到c1,保證合併後的list仍然有序 |
c.merge(c2,op) | 假設c1和c2內的元素按照op()已序,將c2內的全部元素轉移到c1,保證合併後的list仍然在op()準則下有序 |
c.reverse() | 將所有元素反序 |
8. 異常處理
所有STL標準容器中,list對於異常安全性提供了最佳支持。
操作 | 保證 |
---|---|
push_back() | 如果不成功,就沒有任何作用 |
push_front() | 如果不成功,就沒有任何作用 |
insert() | 如果不成功,就沒有任何作用 |
pop_back() | 不拋出異常 |
pop_front() | 不拋出異常 |
erase() | 不拋出異常 |
clear() | 不拋出異常 |
resize() | 如果不成功,就沒有任何作用 |
remove() | 只要元素比較操作不拋出異常,就不拋出異常 |
remove_if() | 只要判斷式不拋出異常,就不拋出異常 |
unique() | 只要元素比較操作不拋出異常,就不拋出異常 |
splice() | 不拋出異常 |
merge() | 只要元素比較時不拋出異常,保證“要麼不成功,要麼沒有任何作用” |
reverse() | 不拋出異常 |
swap() | 不拋出異常 |
四、程序示例
list的使用示例
//example of list
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
void printLists(const list<int>& l1, const list<int>& l2)
{
cout << "list1: ";
copy(l1.begin(), l1.end(), ostream_iterator<int>(cout, " "));
cout << endl << "list2: ";
copy(l2.begin(), l2.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
}
int main()
{
list<int> l1, l2;
for (int i = 0; i < 6; ++i){
l1.push_back(i);
l2.push_front(i);
}
printLists(l1, l2);
l2.splice(find(l2.begin(), l2.end(), 3), l1);
printLists(l1, l2);
l2.splice(l2.end(), l2, l2.begin());
printLists(l1, l2);
l2.sort();
l1 = l2;
l2.unique();
printLists(l1, l2);
l1.merge(l2);
printLists(l1, l2);
l1.reverse();
printLists(l1,l2);
l1.sort();
printLists(l1,l2);
return 0;
}
輸出結果: