🎈 作者:Linux猿
🎈 簡介:CSDN博客專家🏆,C/C++、面試、刷題、演算法盡管咨詢我,關注我,有問題私聊!
🎈 關注專欄:C/C++面試通關集錦 (優質好文持續更新中……)🚀
目錄
一、什么是 list ?
二、List 的定義
2.1 頭檔案
2.2 定義
2.3 常用方法
三、實體講解
3.1 size()、clear()、empty() 方法
3.2 push_front()、push_back() 方法
3.3 pop_front()、pop_back() 方法
3.4 begin()、end() 方法
3.5 rbegin()、rend() 方法
3.6 insert 方法
3.6.1 插入單個元素
3.6.2 插入 n 個相同的元素
3.6.3 在 postion 位置插入 [first, last) 區間的元素
3.7 erase 方法
3.7.1 洗掉單個元素
3.7.2 洗掉區間 [first, last) 的元素
四、總結
list 是 STL 最長使用的容器之一,是在日常使用以及面試中經常遇到的知識點,下面來詳細講解下 list,
一、什么是 list ?
list 是一個雙向鏈表封裝起來的容器,可以實作 O(1) 的時間復雜度插入和洗掉元素,但是,和鏈表一樣,不能通過下標(例如:g[i])快速訪問元素,只能通過遍歷獲取,

二、List 的定義
2.1 頭檔案
使用 List 需要引入頭檔案:
#include <list>
2.2 定義
list<T>變數名稱;
其中,T 是資料型別,例如:int、char、String、類等,
下面來看一下定義的例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
cout<<"t1 size = "<<t1.size()<<endl; // size = 0
list<int> t2(5); // 定義一個長度為 5,初始值都為 0 的 int 型別的 list
cout<<"t2 size = "<<t2.size()<<endl; // size = 5
list<int> t3(5, 10); // 定義一個長度為 5,初始值都為 10 的 int 型別的 list
cout<<"t3 size = "<<t3.size()<<endl; // size = 5
int idx = 0;
list<int>::iterator iter;
for(iter = t3.begin(); iter != t3.end(); ++iter) {
cout<<*iter<<" "; // *iter = 10
}
cout<<endl;
// 輸出為:10 10 10 10 10
list<int> t4(t3); // 使用 t3 初始化 t4,需要是一樣的型別
list<int> t5(t3.begin(), t3.end()); // 使用 t3 初始化 t5
}
輸出為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
t1 size = 0
t2 size = 5
t3 size = 5
10 10 10 10 10
linuxy@linuxy:~/defineDir$
還可以使用花括號的形式初始化:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1{1,2,3,4,5,6}; // 定義一個名為 t1 的 int 型別的 list
list<int>::iterator iter;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
}
輸出為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 3 4 5 6
linuxy@linuxy:~/defineDir$
2.3 常用方法
size() : 回傳鏈表中的元素個數;
clear(): 清空所有元素;
empty(): 判斷是否為空;
push_front(): 在鏈表開頭添加元素;
push_back(): 在鏈表結尾添加元素;
pop_front(): 洗掉鏈表開頭的元素;
pop_back(): 洗掉鏈表結尾元素;
begin(): 回傳指向鏈表第一個元素的迭代器;
end(): 回傳指向鏈表最后一個元素的迭代器;
rbegin(): 回傳指向鏈表最后一個元素的迭代器;(用于逆向遍歷元素)
rend(): 回傳指向鏈表第一個元素的迭代器;(用于逆向遍歷元素)
insert(position, val): 在鏈表 position 位置插入元素 val;
insert(position, n, val): 在鏈表 position 位置插入 n 個元素 val;
insert(position, first, last): 在鏈表 position 位置插入 [first, last) 區間的元素;
erase(position): 洗掉 position 位置的元素;
erase(first, last): 洗掉 區間[first, last) 位置的元素;
三、實體講解
3.1 size()、clear()、empty() 方法
函式原型為:
size_type size() const // 回傳鏈表存盤的元素總數
void clear() // 清空鏈表
bool empty() const // 判斷鏈表是否為空,慷訓傳 true,否則,false
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
cout<<"t1.size() = "<<t1.size()<<endl; // size = 0
cout<<"t1.empty() = "<<t1.empty()<<endl; // 判斷是否為空
cout<<"--------------------------"<<endl;
t1.push_back(1); // 在 t1 尾部添加一個元素
cout<<"t1 size = "<<t1.size()<<endl; // size = 1
cout<<"t1.empty() = "<<t1.empty()<<endl; // 判斷是否為空
cout<<"--------------------------"<<endl;
t1.clear();
cout<<"t1 size = "<<t1.size()<<endl; // size = 1
cout<<"t1.empty() = "<<t1.empty()<<endl; // 判斷是否為空
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
t1.size() = 0
t1.empty() = 1
--------------------------
t1 size = 1
t1.empty() = 0
--------------------------
t1 size = 0
t1.empty() = 1
linuxy@linuxy:~/defineDir$
3.2 push_front()、push_back() 方法
函式原型如下:
void push_front (const value_type& val); // 將元素添加到鏈表的開頭
void push_back (const value_type& val); // 將元素添加到鏈表的結尾
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
t1.push_front(10);
t1.push_back(20);
list<int>::iterator iter;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<endl;
}
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
10
20
linuxy@linuxy:~/defineDir$
可以看到,輸出的順序為 10、20,
3.3 pop_front()、pop_back() 方法
函式原型如下:
void pop_front(); // 洗掉鏈表最前面一個(第一個)元素
void pop_back(); // 洗掉鏈表最后一個元素
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter; // 迭代器
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為:1 2 3 4 5 6
t1.pop_front(); // 洗掉鏈表第一個元素
t1.pop_back(); // 洗掉鏈表最后一個元素
cout<<"----------------------------"<<endl;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為:2 3 4 5
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 3 4 5 6
----------------------------
2 3 4 5
linuxy@linuxy:~/defineDir$
可以看到,鏈表第一個和最后一個元素被洗掉了,
3.4 begin()、end() 方法
函式原型如下:
iterator begin(); // 回傳指向第一個元素的迭代器
iterator end(); // 回傳指向最后一個元素的迭代器
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter; // 順序遍歷鏈表的迭代器
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為:1 2 3 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 3 4 5 6
linuxy@linuxy:~/defineDir$
可以看到,順序輸出了鏈表中的元素,
3.5 rbegin()、rend() 方法
函式原型如下:
reverse_iterator rbegin() // 回傳指向最后一個元素的反向迭代器
reverse_iterator rend() // 回傳指向第一個元素的反向迭代器
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::reverse_iterator iter; // 反向迭代器
for(iter = t1.rbegin(); iter != t1.rend(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
//輸出為: 6 5 4 3 2 1
}
輸出為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
6 5 4 3 2 1
linuxy@linuxy:~/defineDir$
可以看到,逆序輸出了鏈表元素,
注意:遍歷鏈表的迭代器需要使用反向迭代器,例如上面的代碼中 list<int>:: reverse_iterator,
3.6 insert 方法
insert 多載了多個方法,下面來看一下,
3.6.1 插入單個元素
函式原型如下:
iterator insert (const_iterator position, const value_type& val); // 在 position 的位置插入元素 val
注意:如果鏈表中 position 位置原先有元素,則新元素插入后,原先的元素在新元素后面,
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
if(*iter == 3) { // 在元素 3 的位置插入元素 7,故元素 3 就位于了 7 后面
t1.insert(iter, 7);
}
}
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為: 1 2 7 3 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 7 3 4 5 6
linuxy@linuxy:~/defineDir$
可以看到,7 插入到了原先 3 的位置,插入后,3 在 7 后面,
3.6.2 插入 n 個相同的元素
iterator insert (const_iterator position, size_type n, const value_type& val); // 在 position 位置插入 n 個元素 val
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
if(*iter == 3) { // 在元素 3 后面插入 5 個 7
t1.insert(iter, 5, 7);
}
}
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為:1 2 7 7 7 7 7 3 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 7 7 7 7 7 3 4 5 6
linuxy@linuxy:~/defineDir$
可以看到,插入了 5 個 7,插入后,3 排在了最后一個 7 后面,
3.6.3 在 postion 位置插入 [first, last) 區間的元素
iterator insert (const_iterator position, InputIterator first, InputIterator last); // 在 position 位置插入[first, last) 區間的元素
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int> t2;
for(int i = 7; i <= 9; ++i) { // 插入元素 7 8 9
t2.push_back(i);
}
list<int>::iterator iter;
for(iter = t1.begin(); iter != t1.end(); ++iter) {
if(*iter == 3) { // 在元素 3 的位置插入元素 7 8 9
t1.insert(iter, t2.begin(), t2.end());
}
}
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為: 1 2 7 8 9 3 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 2 7 8 9 3 4 5 6
linuxy@linuxy:~/defineDir$
可以看到 7,8,9 插入到了 t1 中原先 3 的位置,其中,迭代器 first 和 last 只要是一個區間就可以,不一定是 begin() 和 end(),
3.7 erase 方法
3.7.1 洗掉單個元素
函式原型如下所示:
iterator erase (const_iterator position); // 洗掉 position 位置的元素
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter = t1.begin();
++iter;
t1.erase(iter); // 洗掉 2
for(iter = t1.begin(); iter != t1.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
// 輸出為: 1 3 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 3 4 5 6
linuxy@linuxy:~/defineDir$
可以看到洗掉了元素 2,
3.7.2 洗掉區間 [first, last) 的元素
函式原型如下所示:
iterator erase (const_iterator first, const_iterator last); // 洗掉鏈表中 [first, last) 區間的元素
來看一個例子:
#include <iostream>
#include <list> // list 頭檔案
using namespace std; // 命名空間,如果沒有,則使用 std::list
int main() {
list<int> t1; // 定義一個名為 t1 的 int 型別的 list
for(int i = 1; i <= 6; ++i) { // 插入元素 1 2 3 4 5 6
t1.push_back(i);
}
list<int>::iterator iter1, iter2;
iter2 = t1.begin();
++iter2;
iter1 = iter2;
++iter2;
++iter2; // iter1 指向元素 2,iter2 指向元素 4
t1.erase(iter1, iter2); // 洗掉 [2, 4) 區間的元素,故洗掉鏈表中的 2,3 兩個元素
for(iter1 = t1.begin(); iter1 != t1.end(); ++iter1) {
cout<<*iter1<<" ";
}
cout<<endl;
// 輸出 1 4 5 6
}
輸出結果為:
linuxy@linuxy:~/defineDir$ g++ -o main main.cpp
linuxy@linuxy:~/defineDir$ ./main
1 4 5 6
linuxy@linuxy:~/defineDir$
可以看到洗掉了區間 [2, 4) 的元素,即:2 和 3,

四、總結
以上就是 STL list 常用的方法講解,在經常插入/洗掉元素操作的情況下可以考慮使用 list,
?好文推薦?
最受歡迎的 Linux 竟然是它,Ubuntu 排第六 ?
零基礎都能看懂的 STL map 詳解
一文掌握C/C++記憶體泄漏,防止記憶體泄漏以及檢測工具!
【萬字整理】??8大排序演算法??【建議收藏】
🎈 歡迎小伙伴們點贊👍、收藏?、留言💬
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297832.html
標籤:其他
上一篇:什么是并查集?【建議收藏】

