list内部结构与array、vector、deque完全不同。list自身有两个指针,用来指向第一个元素和最后一个元素。每个元素都有指针指向前一个和后一个元素,插入删除时改变指针就行。

不支持随机访问,任何位置的插入删除快。插入和删除不会使其他元素的指针,引用和迭代器失效。

list的异常处理方式为,操作成功,或者什么都不发生。

list成员函数显示的与array、vector、deque的区别:

list提供front()、push_front()、pop_front()、back()、push_back()、pop_back()等操作函数

由于不支持随机访问,list不能下标操作符访问,也没有at()函数

list没有内存分配和重新分配的函数,因为没有必要

list有特殊的成员函数用来移动和删除元素,比同名的全局函数速度快。

创建、复制、销毁

与序列式容器相同,如下表:

操作 结果
list<Elem> c 默认构造
list<Elem> c(c2) 复制构造
list<Elem> c = c2 复制构造
list<Elem> c(rvalue) move构造
list<Elem> c=crvalue move构造
list<Elem> c(n) 默认构造一个大小为n的list
list<Elem> c(n,elem) 生成一个有n个元素的list,每个元素都是elem
list<Elem> c(begin,end) 以begin和end的左闭右开区间构造一个list
list<Elem> c(initlist) 以初值列表构造list
list<Elem> c = initlist 同上
c.~list() 销毁所有元素,释放内存

非变动性操作

操作 效果
c.empty() 返回容器是否为空
c.size() 返回目前容器内元素个数
c.max_size() 返回元素个数的最大可能值
c1 == c2  
!=  
<  
>  
<=  
>=  

赋值操作

操作 效果
c = c2 赋值
c = rv 将右值move给c
c = initlist 初始化表赋给c
c.assign(n,elem) n个elem赋给c
c.assign(begin,end) 左闭右开赋给c
c.assign(initlist) 初始化表赋给c
c1.swap(c2) 交换c1,c2
swap(c1,c2) 比上面那个慢,全局函数

元素访问

不能下标访问,只能用范围for循环,使用特定函数或者迭代器。不支持随机访问,只有front()和back()能直接访问元素。这两个函数不检查范围。

迭代器相关函数

操作 效果
c.begin() 返回一个双向迭代器指向第一个元素
c.end() 返回指向最后一个元素的双向迭代器
c.cbegin() 第一个的const,c11
c.cend() 第二的const,c11
c.rbegin() 反向的迭代器指向反向迭代的第一个元素
c.rend() 反向的迭代器指向反向迭代的最后一个
c.crbegin() c11
c.crend() c11

插入和删除元素

list删除元素有特别的remove()成员函数,比全局的remove()函数效率更高,因为只对内部的指针进行操作,不改变元素。

其中rempove_if()函数可以定义移除的元素需要满足的条件,例如:

coll.remove_if([] (int i)

{

return i%2==0;

});

会移除所有偶数。

插入删除函数

操作 效果 异常处理
c.push_back() 尾插 成功或者没有任何效果
c.pop_back() 尾删,不反悔 不抛出异常
c.push_front() 头插 成功或者没有任何效果
c.pop_front() 头删,不反悔 不抛出异常
c.insert(pos,elem) 指定位置前插入 成功或者没有任何效果
c.insert(pos,n,elem) 指定位置前插入n个elem,返回第一个新元素的位置 成功或者没有任何效果
c.insert(pos,begin,end) 指定位置前插入左闭右开的所有元素,返回第一个新元素位置 成功或者没有任何效果
c.insert(pos,initlist) 指定为之前插入初始化列的所有元素并返回第一个新元素的位置 成功或者没有任何效果
c.emplace(pos,args…) 在pos前插入以args为初值的元素,并返回新元素位置,c11  
c.emplace_back(args…) 上面的函数的后插实现,不返回,c11  
c.emplace_front(args…) 上面的函数的头插实现,不返回,c11  
c.erase(pos) 删除指定位的元素,返回下一个 不抛出异常
c.erase(begin,end) 删除区间 不抛出异常
c.remove(val) 删除所有值为val的元素 元素比较不抛出异常,这个函数就不抛出异常
c.remove_if(op) 上文讲过了 如上
c.resize(num) 元素数量改为num,如果变多,多出来的默认构造 成功或者没有任何效果
c.resize(num,elem) 如果变多,多出来的为elem 成功或者没有任何效果
c.clear() 删除所有元素 不抛出异常

以下操作不会造成指向成员的迭代器和指针失效:

insert(),emplace(),emplace…(),push_front(),push_back(),pop_front(),pop_back(),erase()

特殊变动性操作

操作 效果 异常处理
c.unique() 如果存在临近且数值相同的元素,只保留一个 元素比较不抛出异常,这个函数就不抛出异常
c.unique(op) 如果存在相邻元素满足op,就只保留一个 元素比较不抛出异常,这个函数就不抛出异常
c.splice(pos,c2) 把c2的所有元素搬到c的pos前 不抛出异常
c.splice(pos,c2,c2pos) 把c2的c2pos的元素搬到c的pos前 同上
c.splice(pos,c2,c2begin,c2end) 把c2的c2begin和c2end之间的元素左闭右开搬到c的pos前 同上
c.sort() 从小到大对c进行排序  
c.sort(op) 以op准则进行排序  
c.merge(c2) 假设c和c2的容器都包含符合op()的已经排序的元素,将c2的元素搬到c,并保证合并后的list依然是已排序的 元素比较不抛出异常,这个函数就不抛出异常
c.merge(c2,op) 假设c和c2的容器都包含符合op()的已经排序的元素,将c2的元素搬到c,并保证合并后的list依然是符合op的已排序的 元素比较不抛出异常,这个函数就不抛出异常
c.reserve 将所有元素反序 不抛出

list实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
 
using namespace std;
 
void printLists(const list<int>& l1, const list<int>& l2)
{
	cout << "list1:";
	copy(l1.cbegin(), l2.cend(), ostream_iterator<int>(cout, " "));
	cout << endl << "list2:";
	copy(l2.cbegin(), l2.cend(), ostream_iterator<int>(cout, " "));
	cout << endl << endl;
}
 
int main()
{
	//创建两个空链表
	list<int> list1, list2;
 
	//填充元素
	for (int i = 0; i < 6; ++i)
	{
		list1.push_back(i);
		list2.push_front(i);
	}
	printLists(list1, list2);
 
	//把list1的所有元素插入到list2的第一个值为3的元素前面
	//find()返回一个指向第一个值为3的元素的迭代器
	list2.splice(find(list2.begin(), list2.end(), //定义位置
		3),
		list1);//源链表
 
	printLists(list1, list2);
 
	//将list2的第一个元素移到最后
	list2.splice(list2.end(),	//定义位置
				 list2,			//源链表
				 list2.begin());//初始位置
 
	printLists(list1, list2);
 
	//排序list2,将其赋值给list1,并删除list1中重复元素
	list2.sort();
	list1 = list2;
	list2.unique();
	printLists(list1, list2);
 
	//将同样排过序的list2合并到list1
	list1.merge(list2);
	printLists(list1, list2);
}