C ++ list 用法整理(官網例子)
阿新 • • 發佈:2018-12-18
因為最近一直在用 C++ 的 list,搜到的那個最高訪問的 CSDN 博文寫的不夠簡潔。而官網上的一些例子有些細節沒涉及到,得自己再複製下來跑一遍才能搞明白。於是便萌生了寫這篇博文的念頭,方便自己以後查閱。
本文的例子都來自官網的介紹:http://www.cplusplus.com/reference/list/list/
文章目錄
list 實現
list 容器是由雙向連結串列實現的。
使用 list 的時候得加上 #include <list>
標頭檔案以及得在 std 名字空間中使用。
list 定義和初始化
只需要簡單的 list<TYPE> my_list;
就可以完成對一個 list 的定義了。不需要 new。
初始化的話就要用到 list 的建構函式。
一個簡單的例子是:
int myints[] = {75,23,65,42,13};
list<int> mylist (myints, myints+5);
當然我們仍然可以使用一些函式對 list 增加刪除元素。
list 函式介紹
這裡介紹一些我覺得可能比較常用的函式。
迭代器
函式名 | 作用 |
---|---|
begin | 將迭代器返回到開頭(Return iterator to beginning) |
將迭代器返回到最後(Return iterator to end) | |
rbegin | Return reverse iterator to reverse beginning |
rend | Return reverse iterator to reverse end |
C++ 11 標準又新增 cbegin, cend, crbegin 和 crend 這四個函式,返回的都是 const_iterator。
容量
函式名 | 作用 |
---|---|
empty | 檢查容器是否為空 |
size | 返回當前容器內元素個數 |
max_size | 返回當前容器能容納的最大元素數量 |
元素訪問
函式名 | 作用 |
---|---|
front | 訪問第一個元素 |
back | 訪問最後一個元素 |
更改 list
函式名 | 作用 |
---|---|
assign | Assign new content to container |
push_front | 將元素插入到開頭 |
pop_front | 刪除第一個元素 |
push_back | 將元素插入到最後 |
pop_back | 刪除最後一個元素 |
insert | 插入元素 |
erase | 刪除元素 |
swap | 交換兩個 list 內容 |
resize | 改變容器大小 |
clear | 刪除容器所有內容 |
C++ 11 標準又增加了 emplace_front, emplace_back, emplace 這三個函式
操作
函式名 | 作用 |
---|---|
splice | 合併兩個 list |
remove | 根據值刪除元素 |
remove_if | 刪除滿足條件的元素 |
unique | 刪除重複的值 |
merge | 合併排好序的 list |
sort | 對容器內的元素排序 |
reverse | 將元素反序 |
函式舉例
這裡介紹一些函式的使用例子,加深理解。函式的排序按字典序排的,方便從目錄查詢跳轉。
ATTENTION:程式的輸出一般寫在註釋裡。
assign()
#include <iostream>
#include <list>
using namespace std;
template <class T>
void print_list(list<T> my_list)
{
for (typename list<T>::iterator it = my_list.begin(); it != my_list.end(); ++it)
cout << ' ' << *it;
cout << '\n';
}
int main ()
{
list<int> first;
list<int> second;
first.assign (7, 100); // 7 ints with value 100
print_list(first);
// 100 100 100 100 100 100 100
second.assign (first.begin(),first.end()); // a copy of first
print_list(second);
// 100 100 100 100 100 100 100
int myints[]= {1776, 7, 4};
first.assign (myints, myints+3); // assigning from array
print_list(first);
// 1776 7 4
cout << "Size of first: " << int (first.size()) << '\n';
cout << "Size of second: " << int (second.size()) << '\n';
// Size of first: 3
// Size of second: 7
return 0
}
begin() —— 對 list 進行順序遍歷
end() 的程式碼和這個一模一樣。
#include <iostream>
#include <list>
using namespace std;
int main ()
{
int myints[] = {75,23,65,42,13};
list<int> mylist (myints,myints+5);
cout << "mylist contains:";
for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)
std::cout << ' ' << *it;
cout << '\n';
// mylist contains: 75 23 65 42 13
return 0;
}
erase()
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int> mylist;
list<int>::iterator it1,it2;
// set some values:
for (int i=1; i<10; ++i) mylist.push_back(i*10);
// 10 20 30 40 50 60 70 80 90
it1 = it2 = mylist.begin(); // ^^
advance (it2,6); // ^ ^
++it1; // ^ ^
it1 = mylist.erase (it1); // 10 30 40 50 60 70 80 90
// ^ ^
it2 = mylist.erase (it2); // 10 30 40 50 60 80 90
// ^ ^
++it1; // ^ ^
--it2; // ^ ^
mylist.erase (it1,it2); // 10 30 60 80 90
// ^
cout << "mylist contains:";
for (it1=mylist.begin(); it1!=mylist.end(); ++it1)
cout << ' ' << *it1;
cout << '\n';
return 0;
}
使用 erase() 函式,我們可以實現動態的刪除。
int main ()
{
list<int> mylist;
// set some values:
for (int i=1; i<5; ++i) mylist.push_back(i*10);
// 10 20 30 40
cout << "mylist contains:";
for (list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
{
if (*it == 30)
it = mylist.erase(it);
cout << ' ' << *it;
}
cout << '\n';
// mylist contains: 10 20 40
return 0;
}
insert()——插入元素
insert 的引數還是到官網上查比較好,上面的表格裡給出了連結。
下面的 ^
表示當前的迭代器指向哪個元素。
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main ()
{
list<int> mylist;
list<int>::iterator it;
// set some initial values:
for (int i=1; i<=5; ++i) mylist.push_back(i); // 1 2 3 4 5
it = mylist.begin();
++it; // it points now to number 2 ^
mylist.insert (it,10); // 1 10 2 3 4 5
// "it" still points to number 2 ^
mylist.insert (it,2,20); // 1 10 20 20 2 3 4 5
--it; // it points now to the second 20 ^
vector<int> myvector (2,30);
mylist.insert (it,myvector.begin(),myvector.end());
// 1 10 20 30 30 20 2 3 4 5
// ^
cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
cout << ' ' << *it;
cout << '\n';
// mylist contains: 1 10 20 30 30 20 2 3 4 5
return 0;
}
merge() —— 合併兩個 list
#include <iostream>
#include <list>
using namespace std;
// compare only integral part:
bool mycomparison (double first, double second)
{
return ( int(first)<int(second) );
}
int main ()
{
list<double> first, second;
first.push_back (3.1);
first.push_back (2.2);
first.push_back (2.9);
second.push_back (3.7);
second.push_back (7.1);
second.push_back (1.4);
first.sort(); // 2.2 2.9 3.1
second.sort(); // 1.4 3.7 7.1
first.merge(second); // 1.4 2.2 2.9 3.1 3.7 7.1
// (second is now empty)
second.push_back (2.1); // 2.1
first.merge(second, mycomparison);
cout << "first contains:";
for (list<double>::iterator it=first.begin(); it!=first.end(); ++it)
cout << ' ' << *it;
cout << '\n';
// first contains: 1.4 2.2 2.9 2.1 3.1 3.7 7.1
return 0;
}
但是經過我的嘗試,好像可以不排序合併:
int main ()
{
list<double> first, second;
for (int i=1; i<=5; ++i) first.push_back(i);
for (int i=1; i<=5; ++i) second.push_back(i+10);
first.merge(second);
// (second is now empty)
cout << "first contains:";
for (list<double>::iterator it=first.begin(); it!=first.end(); ++it)
cout << ' ' << *it;
cout << '\n';
// first contains: 1 2 3 4 5 11 12 13 14 15
return 0;
}
rbegin() —— 對 list 進行逆向遍歷
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int> mylist;
for (int i=1; i<=5; ++i) mylist.push_back(i);
cout << "mylist backwards:";
for (list<int>::reverse_iterator rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
cout << ' ' << *rit;
cout << '\n';
// mylist backwards: 5 4 3 2 1
return 0;
}
remove()
#include <iostream>
#include <list>
using namespace std;
int main ()
{
int myints[]= {17,89,7,14};
list<int> mylist (myints,myints+4);
// 17 89 7 14
mylist.remove(89);
cout << "mylist contains:";
for (list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
cout << ' ' << *it;
cout << '\n';
// mylist contains: 17 7 14
return 0;
}
它會刪除所有匹配的值,也就是說
int myints[]= {17,89,7,89,14};
list<int> mylist (myints,myints+5);
// 17 89 7 89 14
mylist.remove(89);
// mylist contains: 17 7 14
如果你想像下面這樣寫的話,會出現死迴圈。
int main ()
{
int myints[]= {17,89,7,14};
list<int> mylist (myints,myints+4);
// 17 89 7 14
cout << "mylist contains:";
for (list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it) {
if (*it == 89)
mylist.remove(89);
cout << ' ' << *it;
}
cout << '\n';
// 死迴圈
return 0;
}
想要達到上述的效果,可以使用 erase() 函式。具體程式碼見那一節。