list用法及示例
文章目錄
- list用法及示例
- 一、簡介
- 二、容器特性
- 三、使用
- 成員函式
- 幾種創建方式
- 示例:
- demo1:
- demo2: 插入:push_front(), push_back(), emplace_front(), emplace_back(), emplace()
- demo3: 插入:insert()的多種方式
- demo4: 移動:splice()的多種方式
- demo5: 洗掉pop_back();pop_front();erase();remove();clear()
- demo6 :洗掉相鄰重復的元素 unique()的兩種方式
- demo7: 洗掉能夠使lamba運算式成立的所有元素 remove_if()
- demo8: 可使用std::advance()更便捷的移動迭代器(注意不要越界)
一、簡介
list 容器,又稱雙向鏈表容器,
該容器的底層是以雙向鏈表的形式實作的
二、容器特性
list 容器中各個元素的前后順序是靠指標來維系的,每個元素都配備了 2 個指標,分別指向它的前一個元素和后一個元素,其中第一個元素的前向指標總為 null,尾部元素的后向指標也總為 null,
它可以在序列已知的任何位置快速插入或洗掉元素(時間復雜度為O(1)),并且在 list 容器中移動元素,也比其它容器的效率高,
它不能像 array 和 vector 那樣,通過位置直接訪問元素,
只有運用迭代器,才能訪問 list 容器中存盤的各個元素,
注意:
- 雙向迭代器不能通過下標訪問 list 容器中指定位置處的元素,
- 雙向迭代器不支持使用 -=、+=、+、- 運算子,
- 雙向迭代器不支持使用 <、 >、 <=、 >= 比較運算子,
三、使用
成員函式
| 成員函式 | 功能 |
|---|---|
| begin() | 回傳指向容器中第一個元素的雙向迭代器, |
| end() | 回傳指向容器中最后一個元素所在位置的下一個位置的雙向迭代器, |
| rbegin() | 回傳指向最后一個元素的反向雙向迭代器, |
| rend() | 回傳指向第一個元素所在位置前一個位置的反向雙向迭代器, |
| cbegin() | 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用于修改元素, |
| cend() | 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用于修改元素, |
| crbegin() | 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用于修改元素, |
| crend() | 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用于修改元素, |
| empty() | 判斷容器中是否有元素,若無元素,則回傳 true;反之,回傳 false, |
| size() | 回傳當前容器實際包含的元素個數, |
| max_size() | 回傳容器所能包含元素個數的最大值,一般是 2的32次方-1 或者2的62次方-1, |
| front() | 回傳第一個元素的參考, |
| back() | 回傳最后一個元素的參考, |
| assign() | 用新元素替換容器中原有內容, |
| emplace_front() | 在容器頭部生成一個元素,該函式和 push_front() 的功能相同,但效率更高, |
| push_front() | 在容器頭部插入一個元素, |
| pop_front() | 洗掉容器頭部的一個元素, |
| emplace_back() | 在容器尾部直接生成一個元素,該函式和 push_back() 的功能相同,但效率更高, |
| push_back() | 在容器尾部插入一個元素, |
| pop_back() | 洗掉容器尾部的一個元素, |
| emplace() | 在容器中的指定位置插入元素,該函式和 insert() 功能相同,但效率更高, |
| insert() | 在容器中的指定位置插入元素, |
| erase() | 洗掉容器中一個或某區域內的元素, |
| swap() | 交換兩個容器中的元素,必須保證這兩個容器中存盤的元素型別是相同的, |
| resize() | 調整容器的大小, |
| clear() | 洗掉容器存盤的所有元素, |
| splice() | 將一個 list 容器中的元素插入到另一個容器的指定位置, |
| remove(val) | 洗掉容器中所有等于 val 的元素, |
| remove_if() | 洗掉容器中滿足條件的元素, |
| unique() | 洗掉容器中相鄰的重復元素,只保留一個, |
| merge() | 合并兩個事先已排好序的 list 容器,并且合并之后的 list 容器依然是有序的, |
| sort() | 通過更改容器中元素的位置,將它們進行排序, |
| reverse() | 反轉容器中元素的順序, |
幾種創建方式
- 創建一個沒有任何元素的空list容器:
std::list<int> test;
- 創建一個包含n個元素的list容器:
std::list<int> test(10);
- 創建一個包含n個元素的list容器,并賦初始值:
std::list<int> test(10, 9);
std::list<int>test{ 1,2,3,4,5,6,7,8,9 };
- 通過拷貝一個已有的容器的方式創建新的list容器:
std::list<int> tmp(10);
std::list<int> test(tmp);
- 通過拷貝其他型別容器(或陣列)中指定區域內的元素的方式創建list容器:
int a[] = { 1,2,3,4,5,6,7,8,9 };
std::list<int> test(a, a+9);
std::array<int, 9>arr{ 1,2,3,4,5,6,7,8,9 };
std::list<int>test(arr.begin()+2,arr.end()-4);//拷貝arr容器中的{3,4,5}
示例:
demo1:
#include <iostream>
#include <list>
int main()
{
std::array<int, 9>arr{ 1,2,3,4,5,6,7,8,9 };
std::list<int>test(arr.begin(), arr.end());//通過拷貝其他型別容器(或陣列)中指定區域內的元素的方式創建list容器
test.emplace_front(0);//頭部插入一個元素
test.emplace_back(-1);//尾部插入一個元素
test.remove(9);//移除9這個元素
for (auto &i : test) {//修改指定元素
if (i == 5) {
i = 555;
}
}
for (auto i : test) {
printf(" %d", i);
}
printf("\n排序\n");
test.sort();//排序
for (auto i : test) {
printf(" %d", i);
}
printf("\n");
}
結果:
0 1 2 3 4 555 6 7 8 -1
排序
-1 0 1 2 3 4 6 7 8 555
demo2: 插入:push_front(), push_back(), emplace_front(), emplace_back(), emplace()
#include <iostream>
#include <list>
int main()
{
std::list<int> test{ 1,2,3 };
test.push_front(0); //頭部插入一個元素{0,1,2,3}
test.push_back(4); //尾部插入一個元素{0,1,2,3,4}
test.emplace_front(-1); //頭部插入一個元素{-1,0,1,2,3,4}
test.emplace_back(5); //尾部插入一個元素{-1,0,1,2,3,4,5}
test.emplace(test.end(), 6);//向指定位置插入一個元素{-1,0,1,2,3,4,5,6}
for (auto i : test) {
std::cout << i << " ";
}
}
-1 0 1 2 3 4 5 6
demo3: 插入:insert()的多種方式
#include <iostream>
#include <list>
int main()
{
std::list<int> test{ 1,2 };
test.insert(test.begin(), 0);//指定的位置之前插入 1 個元素 3 {0,1,2}
test.insert(test.end(), 2, 3);//指定的位置之前插入 2 個元素 3 {0,1,2,3,3}
std::array<int, 3>tmp{ 4,5,6 };
test.insert(test.end(), tmp.begin(), tmp.end());//將其他容器中特定位置的元素插入指定位置 {0,1,2,3,3,4,5,6}
test.insert(test.end(),{7,8});//插入初始化串列中所有的元素{0,1,2,3,3,4,5,6,7,8}
for (auto i : test) {
std::cout << i << " ";
}
}
0 1 2 3 3 4 5 6 7 8
demo4: 移動:splice()的多種方式
#include <iostream>
#include <list>
int main()
{
std::list<int> test1{ 1,2,3,4 };
std::list<int> test2{ 5,6,7 };
std::list<int>::iterator it = ++test1.begin(); //it 迭代器指向元素 2
//第一種用法:將test2的所有元素移動到2所在的位置:
test1.splice(it, test2);//test1:{1,5,6,7,2,3,4}; test2:{}; it迭代器仍然指向元素2
//第二種用法:將 it 指向的元素 2 移動到 test2.begin()位置:
test2.splice(test2.begin(), test1, it); //test1:{1,5,6,7,3,4}; test2:{2}; it仍然指向元素2
//第三種用法:,將 [test1.begin(),test1.end())范圍內的元素移動到 test2.begin() 位置:
test2.splice(test2.begin(), test1, test1.begin(), test1.end()); //test1:{}; test2:{1,5,6,7,3,4,2};it仍然指向元素2
std::cout << "test1.size(): " << test1.size() << std::endl;
std::cout << "test2.size(): " << test2.size() << std::endl;
std::cout << "it: " << *it << std::endl;
for (auto i : test2) {
std::cout << i << " ";
}
}
test1.size(): 0
test2.size(): 7
it: 2
1 5 6 7 3 4 2
demo5: 洗掉pop_back();pop_front();erase();remove();clear()
#include <iostream>
#include <list>
int main()
{
std::list<int> test{ 0,1,2,3,3,3,4,5,6,7,6,5,4,3,2,1,99,0 };
test.pop_back();//移除最后一個元素{0,1,2,3,3,3,4,5,6,7,6,5,4,3,2,1,99}
test.pop_front();//移除第一個元素{1,2,3,3,3,4,5,6,7,6,5,4,3,2,1,99}
test.erase(++test.begin()); //洗掉第二個元素{1,3,3,3,4,5,6,7,6,5,4,3,2,1,99}
//洗掉指定元素
for (std::list<int>::iterator i = test.begin(); i != test.end();++i) {
if ((*i) == 7) {
test.erase(i);
}
}
//{1,3,3,3,4,5,6,6,5,4,3,2,1,99}
test.remove(99);//洗掉元素99 {1,3,3,3,4,5,6,6,5,4,3,2,1}
for (auto i : test) {
std::cout << i << " ";
}
std::cout<< std::endl;
test.erase(++test.begin(), --test.end());//洗掉指定一段元素 {1,1}
for (auto i : test) {
std::cout << i << " ";
}
test.clear();//清空
}
1 3 3 3 4 5 6 6 5 4 3 2 1
1 1
demo6 :洗掉相鄰重復的元素 unique()的兩種方式
#include <iostream>
#include <list>
//二元謂詞函式
bool fuc1(int a, int b) {
if (a / 10 == b / 10) {
return true;
}
return false;
}
int main()
{
std::list<int> test{10,20,30,30,31,32,33,40,50,60,30,50,60};
//方式一:
test.unique();//洗掉相鄰重復的元素,僅保留一份
for (auto i : test) {
std::cout << i << " ";
}
std::cout << std::endl;
//方式二:
test.unique(fuc1);//fuc1 為二元謂詞函式,是我們自定義的去重規則
for (auto i : test) {
std::cout << i << " ";
}
std::cout << std::endl;
}
10 20 30 31 32 33 40 50 60 30 50 60
10 20 30 40 50 60 30 50 60
demo7: 洗掉能夠使lamba運算式成立的所有元素 remove_if()
#include <iostream>
#include <list>
int main()
{
std::list<int> test{1,2,3,4,5,6,7,8,9,10};
test.remove_if([](int n){return (n % 2 != 0);} ); //洗掉test容器中能夠使lamba運算式成立的所有元素,
for (auto i : test) {
std::cout << i << " ";
}
std::cout << std::endl;
}
2 4 6 8 10
demo8: 可使用std::advance()更便捷的移動迭代器(注意不要越界)
#include <iostream>
#include <list>
int main()
{
std::list<int> test{1,2,3,4,5,6,7,8,9,10};
auto it = test.begin();
std::advance(it, 5);
*it = 60;
for (auto i : test) {
std::cout << i << " ";
}
std::cout << std::endl;
}
1 2 3 4 5 60 7 8 9 10
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/384444.html
標籤:其他
上一篇:Windows的基礎docker
