list
連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是透過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。相較於vector的連續線性空間,list就顯得負責許多,它的好處是每次插入或者刪除一個元素,就是配置或者釋放一個元素的空間。因此,list對於空間的運用有絕對的精準,一點也不浪費。而且,對於任何位置的元素插入或元素的移除,list永遠是常數時間。
List和vector是兩個最常被使用的容器。List容器是一個雙向連結串列。
-
採用動態儲存分配,不會造成記憶體浪費和溢位
-
連結串列執行插入和刪除操作十分方便,修改指標即可,不需要移動大量元素
-
連結串列靈活,但是空間和時間額外耗費較大
list容器的迭代器
List容器不能像vector一樣以普通指標作為迭代器,因為其節點不能保證在同一塊連續的記憶體空間上。List迭代器必須有能力指向list的節點,並有能力進行正確的遞增、遞減、取值、成員存取操作。所謂”list正確的遞增,遞減、取值、成員取用”是指,遞增時指向下一個節點,遞減時指向上一個節點,取值時取的是節點的資料值,成員取用時取的是節點的成員。
List*有一個重要的性質,插入操作和刪除操作都不會造成原有list迭代器的失效。這在vector是不成立的,因為vector的插入操作可能造成記憶體重新配置,導致原有的迭代器全部失效,甚至List元素的刪除,也只有被刪除的那個元素的迭代器失效,其他迭代器不受任何影響。
list是一個迴圈的雙向連結串列
list<int> myList;
for (int i = 0; i < 10; i++) {
myList.push_back(i);
}
list<int>::_Nodeptr node = myList._Myhead->_Next;
for (int i = 0; i < myList._Mysize * 2; i++) {
cout << "Node:" << node->_Myval << endl;
node = node->_Next;
if (node == myList._Myhead) {
node = node->_Next;
}
}
這是C++11標準庫下的寫法,list<int>::_Nodeptr node = myList._Myhead->_Next;
這句話不適用於其他版本。
建構函式
-
預設建構函式:
std::list<T> lst; // 建立一個空的列表 lst,其中 T 是列表中元素的型別。
-
區間建構函式:
std::list<T> lst(beg, end); // 將區間 `[beg, end)` 中的元素複製給列表 lst。
-
重複元素建構函式:
std::list<T> lst(n, elem); // 建立包含 n 個值為 elem 的元素的列表 lst。
-
複製建構函式:
std::list<T> lst2(lst); // 使用列表 lst 初始化列表 lst2,建立 lst 的副本。
修改操作
push_back(elem)
: 在容器尾部加入一個元素。pop_back()
: 刪除容器中最後一個元素。push_front(elem)
: 在容器開頭插入一個元素。pop_front()
: 從容器開頭移除第一個元素。insert(pos, elem)
: 在 pos 位置插入 elem 元素的複製,返回新資料的位置。insert(pos, n, elem)
: 在 pos 位置插入 n 個 elem 資料,無返回值。insert(pos, beg, end)
: 在 pos 位置插入[beg, end)
區間的資料,無返回值。clear()
: 移除容器的所有資料。erase(beg, end)
: 刪除[beg, end)
區間的資料,返回下一個資料的位置。erase(pos)
: 刪除 pos 位置的資料,返回下一個資料的位置。remove(elem)
: 刪除容器中所有與 elem 值匹配的元素。
大小
-
size();//返回容器中元素的個數
-
empty();//判斷容器是否為空
-
resize(num);//重新指定容器的長度為num,
若容器變長,則以預設值填充新位置。
如果容器變短,則末尾超出容器長度的元素被刪除。
- resize(num, elem);//重新指定容器的長度為num,
若容器變長,則以elem值填充新位置。
如果容器變短,則末尾超出容器長度的元素被刪除。
其他
list<int> rlist = { 3,2,1,5,4 };
cout << "rlist.front:" << rlist.front() << endl;
cout << "rlist.back:" << rlist.back() << endl;
rlist.reverse();
// 使用迭代器遍歷連結串列並輸出元素
for (auto it = rlist.begin(); it != rlist.end(); ++it) {
std::cout << *it << " ";
}
rlist.sort();