1. 程式人生 > >C ++ list 用法整理(官網例子)

C ++ list 用法整理(官網例子)

因為最近一直在用 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)
end
將迭代器返回到最後(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() 函式。具體程式碼見那一節。