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

因为最近一直在用 C++ 的 list,搜到的那个最高访问的 CSDN 博文写的不够简洁。而官网上的一些例子有些细节没涉及到,得自己再复制下来跑一遍才能搞明白。于是便萌生了写这篇博文的念头,方便自己以后查阅。

本文的例子都来自官网的介绍:http://www.cplusplus.com/reference/list/list/

文章目录

    • list 实现
    • list 定义和初始化
    • list 函数介绍
      • 迭代器
      • 容量
      • 元素访问
      • 更改 list
      • 操作
    • 函数举例
      • assign()
      • begin() —— 对 list 进行顺序遍历
      • erase()——动态删除
      • insert()——插入元素
      • merge() —— 合并两个 list
      • rbegin() —— 对 list 进行逆向遍历
      • remove()

list 实现

list 容器是由双向链表实现的,因此不能使用下标运算符 [] 访问其中的元素

使用 list 的时候得加上 #include 头文件以及得在 std 名字空间中使用。

list 定义和初始化

只需要简单的 list 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 
#include 
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 
#include 
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 
#include 
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 
#include 
#include 
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 
#include 
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 
#include 
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;
}

利用『逆向』这个特性,我们还可以用来实现逆向排序。STL 里的 sort 默认是按自然数顺序来排序的,要想实现从大到小排序的效果,我们有三种方法:

  • 自己写比较函数
struct greater
{
    template<class T>
    bool operator()(T const &a, T const &b) const { return a > b; }
};

std::sort(numbers.begin(), numbers.end(), greater());
  • 指定比较规则
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
  • 使用 rbegin()
std::sort(numbers.rbegin(), numbers.rend());   // note: reverse iterators

remove()

#include 
#include 
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() 函数。具体代码见那一节。

你可能感兴趣的:(#,C/C++)