目錄
list的概念
list的構造函數?
list的大小
size()
resize()
empty()
list的插入
push_front()和emplace_front()
push_back()和emplace_back()
insert()和emplace()
list的刪除
pop_front()
pop_back()
erase()
remove()?
remove_if()??
?unique()??
clear()
list的拼接
splice()
merge()
list的迭代器
迭代器類型
begin()和end()
rbegin()和rend()
list中的元素訪問
front()
back()
list的逆置
list的概念
- list是一種可以在常數范圍內在任意位置進行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。
- list的底層是雙向鏈表結構,雙向鏈表中每個元素存儲在互不相關的獨立結點當中,在結點中通過指針指向其前一個元素和后一個元素。
- list與forward_list非常相似,最主要的不同在于forward_list是單鏈表,只能進行單方向迭代。
- list與其他容器相比,list通常在任意位置進行插入、刪除元素的執行效率更高。
- list 和 forward_list最大的缺陷是不支持在任意位置的隨機訪問,其次,list還需要一些額外的空間,以保存每個結點之間的關聯信息(對于存儲的類型較小元素來說這可能是一個重要的因素)。
list的構造函數?
默認構造函數:創建一個空鏈表
list<T> list_name;
填充構造函數:創建包含?n
?個相同值的鏈表
list<int> list2(5, 10); // 包含5個值為10的節點:{10, 10, 10, 10, 10}
范圍構造函數:通過迭代器范圍?[first, last)
?初始化鏈表
int arr[] = {1, 2, 3};
list<int> list3(arr, arr + 3); // 復制數組內容:{1, 2, 3}
拷貝構造函數:通過另一個鏈表深拷貝初始化
list<int> list4(list3); // 拷貝 list3 的內容:{1, 2, 3}
移動構造函數:通過移動另一個鏈表的資源初始化(高效轉移所有權)
list<int> list5(move(list4)); // list4 變為空,list5 接管其內容
初始化列表構造函數(C++11 起):通過初始化列表直接賦值
list<int> list6 = {4, 5, 6}; // 直接初始化:{4, 5, 6}
?
list的大小
size()
size()
:返回當前元素數量
#include <list>
#include <iostream>int main() {list<int> mylist = {1, 2, 3, 4, 5};cout << "Size: " << mylist.size(); // 輸出 5return 0;
}
resize()
-
若?
n < size()
:截斷鏈表,僅保留前?n
?個元素。 -
若?
n > size()
:擴展鏈表,新增元素默認初始化為?T()
(或指定?value
)。
std::list<int> mylist = {1, 2, 3};mylist.resize(5); // 擴展為 {1, 2, 3, 0, 0}(填充默認值0)
mylist.resize(2); // 截斷為 {1, 2}
mylist.resize(4, 99); // 擴展為 {1, 2, 99, 99}
empty()
檢查鏈表是否為空(等價于?size() == 0
)
std::list<int> mylist;
if (mylist.empty())
{std::cout << "List is empty!";
}
list的插入
push_front()和emplace_front()
- push_front (const value_type& val)
- ???在頭部插入元素(拷貝構造)。
- emplace_front (Args&&... args);(C++11 起)
- ?在頭部直接構造元素(避免臨時對象拷貝)
頭部插入
list<int> mylist;
mylist.push_front(10); // 鏈表內容:{10}
mylist.push_front(20); // 鏈表內容:{20, 10}
push_back()和emplace_back()
尾部插入
- push_front (const value_type& val)
- ???在尾部插入元素(拷貝構造)。
- emplace_front (Args&&... args);(C++11 起)
- ?在尾部直接構造元素(避免臨時對象拷貝)
mylist.push_back(30); // 鏈表內容:{20, 10, 30}
insert()和emplace()
insert(iterator pos, const T& value) ?
在迭代器 pos 指向的位置前插入元素(拷貝構造)。
emplace(iterator pos, Args&&... args)(C++11 起)
在 pos 位置直接構造元素(更高效)。?
指定位置插入
示例一:插入單個元素:
list<int> mylist = { 1, 2, 3 };
mulist.insert(mylist.begin(), 1);
// mylist { 1, 1, 2, 3 }
示例二:插入多個相同元素:
list<int> mylist = { 1, 2, 3 };
list<int>::iterator it = mylist.begin();
myList.insert(it, 3, 100); // 插入3個100
// mylist { 100, 100, 100, 1, 2, 3 }
示例三:插入范圍元素:
list<int> mylist = { 1, 2, 3 };
list<int>::iterator it = mylist.end();vector<int> vec = {5, 6, 7};
myList.insert(it, vec.begin(), vec.end()); // 在末尾插入vector內容
// mylist { 1, 2, 3, 4, 5, 6 }
list的刪除
pop_front()
頭部刪除,移除鏈表第一個元素
list<int> mylist = { 1, 2, 3 };
mylist.pop_front(); // mylist:{ 2, 3 }
pop_back()
尾部刪除,移除鏈表最后一個元素
list<int> mylist = { 1, 2, 3 };
mylist.pop_back(); // mylist:{ 1, 2 }
erase()
任意位置刪除
erase(iterator pos)
刪除迭代器?pos
?指向的元素
list<int> mylist = {10, 20, 30, 40};auto it = mylist.begin() + 2;
mylist.erase(it); // 刪除30 → {10, 20, 40}
erase(iterator first, iterator last)
刪除迭代器范圍?[first, last)
?內的元素(左閉右開)
list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.erase(v.begin() + 1, v.begin() + 3);
// 刪除元素 2 和 3,v = {1, 4, 5}
// it 指向 4
remove()
?
用于刪除容器當中特定值的元素
list<int> list1 = { 1, 2, 3, 4,3, 3 };
lt.remove(3); //刪除容器當中所有值為3的元素
// list1 { 1, 2, 4 }
remove_if()
??
用于刪除容器當中滿足條件的元素。
bool single_digit(const int& val)
{return val < 10;
}list<int> list1 = { 1, 2, 3, 4,3, 3, 10 };
lt.remove_if(single_digit); / /刪除容器當中值小于10的元素
// list1 { 10 }
?unique()
??
用于刪除容器當中連續的重復元素。?
list<int> list1 = { 1, 4 ,3 ,3, 2, 2, 3 };
list1.sort(); //將容器當中的元素排為升序
list1.unique(); //刪除容器當中連續的重復元素
// list1 { 1, 2, 3, 4 }
clear()
移除所有元素,size()
?變為 0
list<int> mylist = { 1, 2, 3 };
mylist.clear(); // mylist.size() == 0
list的拼接
splice()
可以將一個鏈表的元素移動到另一個鏈表中,無需復制元素。
示例一:合并整個鏈表
list<int> list1 = {1, 2, 3};list<int> list2 = {4, 5, 6};// 將 list2 的所有元素移動到 list1 的末尾list1.splice(list1.end(), list2);// 輸出結果: 1 2 3 4 5 6for (auto num : list1) {std::cout << num << " ";}
示例 2: 移動單個元素
list<int> list1 = {1, 2, 3};
list<int> list2 = {4, 5, 6};// 將 list2 的第一個元素移動到 list1 的末尾
auto it = list2.begin();
list1.splice(list1.end(), list2, it); // list1{ 1, 2, 3 , 4 }
示例 3: 移動元素區間?
list<int> list1 = {1, 2, 3};
list<int> list2 = {4, 5, 6};// 將 list2 中從第二個元素到末尾的元素移動到 list1 的末尾
auto start = list2.begin();
start++;
auto end = list2.end();
list1.splice(list1.end(), list2, start, end);
// list1 { 1, 2, 3, 5, 6 }
merge()
如果兩個鏈表已排序,可以用?merge()
?合并并保持有序:
std::list<int> list1 = {1, 3, 5};
std::list<int> list2 = {2, 4, 6};// 合并后 list2 變為空,list1 包含 1 2 3 4 5 6
list1.merge(list2);
list的迭代器
迭代器類型
迭代器類型 | 說明 | 示例 |
---|---|---|
iterator | 可讀寫的正向迭代器 | list.begin() |
const_iterator | 只讀的正向迭代器 | list.cbegin() |
reverse_iterator | 可讀寫的反向迭代器 | list.rbegin() |
const_reverse_iterator | 只讀的反向迭代器 | list.crbegin() |
begin()和end()
-
begin()
:返回指向第一個元素的迭代器。 -
end()
:返回指向最后一個元素之后位置的迭代器(尾后迭代器)。
list<int> lt(10, 2);//正向迭代器遍歷容器list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}
rbegin()和rend()
-
rbegin()
:返回指向最后一個元素之后位置的迭代器(尾后迭代器)。 -
rend()
:返回指向第一個元素的迭代器。
list<int> lt(10, 2);//反向迭代器遍歷容器list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";rit++;}
支持的運算符
-
++it
?和?it++
:向前移動 -
--it
?和?it--
:向后移動 -
*it
:解引用獲取元素值 -
it1 == it2
?和?it1 != it2
:比較是否指向同一位置
不支持的運算符
-
it + n
?或?it[n]
(不支持隨機訪問) -
it1 < it2
(僅支持相等性比較)
?
list中的元素訪問
front()
獲取list容器第一個元素
list<int> lt = { 0, 1, 2, 3, 4 };cout << lt.front() << endl; //0
back()
獲取list容器最后一個元素
list<int> lt = { 0, 1, 2, 3, 4 };cout << lt.back() << endl; //4
list的逆置
reverse()
list<int> list1 = { 1, 2, 3, 4, 5 };list1.reverse();
// list1 { 5, 4, 3, 2, 1 }