list 包含在头文件< list >中:
#include <list>
其中的 list 类型系定义于 namespace std 中,是个 class template:
namespace std {
template <typename T,
typename Allocator = allocator<T> >
class list;
}
List 的元素可以是任何类型 T。第二个 template 实参可有可无,用来指定内存模型。默认的内存模型是 C++ 标准库提供的 allocator。
List 的能力
List 的内部结构完全迥异于 array、vector 或 deque。List 对象自身提供了两个 pointer,或称 anchor (锚点),用来指向第一个和最末一个元素。每个元素都有 pointer 指向前一个和下一个元素(或是指回 anchor)。如果想要安插新元素,只需操纵对应的 pointer即可(如下图所示)。
因此,list 在几个主要方面与 array、 vector 或 deque 不同:
- List 不支持随机访问。如果你要访问第 5 个元素,就得顺着串链逐一爬过前 4 个元素。所以,在 list 中随机巡访任意元素是很缓慢的行为。然而你可以从两端开始航行整个 list,所以访问第一个或最末一个元素的速度很快。
- 任何位置上(不只两端)执行元素的安插和移除都非常快,始终都是常量时间内完成,因为无须移动任何其他元素。实际上内部只是进行了一些 pointer 操作而已。
- 安插和删除动作并不会造成指向其他元素的各个 pointer、reference 和 iterator 失效。
- List 对于异常的处理方式是:要么操作成功,要么什么都不发生。你绝不会陷入“只成功一半”这种进退维谷的尴尬境地。
List 所提供的成员函数反映出它和 array、vector 以及 deque 的不同:
- List 提供 front()、 push_front() 和 pop_front()、back()、 push_back() 和 pop_back() 等操作函数。
- 由于不支持随机访问,list 既不提供 subscript (下标)操作符,也不提供 at()。
- List 并未提供容量、空间重新分配等操作函数,因为全无必要。每个元素有自己的内存,在元素被删除前一直有效。
- List 提供不少特殊成员函数,专门用于移动和移除元素。较之同名的 STL 通用算法,这些函数执行起来更快速,因为它们无须复制或搬移元素,只需调整若干 pointer 即可。
List 构造
操作 | 描述 |
---|---|
list< Elem > c | Default 构造函数,产生一个空 list,没有任何元素 |
list< Elem > c(c2) | Copy 构造函数,建立 c2 的同型 list 并成为 c2 的一份拷贝(所有元素都被复制) |
list< Elem > c = c2 | Copy 构造函数,建立一个新的 list 作为 c2 的拷贝(每个元素都被复制) |
list< Elem > c(rv) | Move 构造函数,建立一个新的 list,取 rvalue rv 的内容(始自 C++11) |
list< Elem > c = rv | Move 构造函数,建立一个新的 list,取 rvalue rv 的内容(始自 C++11) |
list< Elem > c(n) | 利用元素的 default 构造函数生成一个大小为 n 的 list |
list< Elem > c(n, elem) | 建立一个大小为 n 的 list,每个元素值都是 elem |
list< Elem > c(beg, end) | 建立一个 list,以区间 [beg, end) 作为元素初值 |
list< Elem > c(initlist) | 建立一个 list,以初值列 initlist 的元素为初值(始自 C++11) |
list< Elem > c = initlist | 建立一个 list,以初值列 initlist 的元素为初值(始自 C++11) |
c.~list() | 销毁所有元素,释放内存 |
非更易型操作
操作 | 描述 |
---|---|
c.empty() | 返回是否容器为空(相当于 size() == 0 但也许较快 |
c.size() | 返回目前的元素个数 |
c.max_size() | 返回元素个数之最大可能量 |
c1 ==c2 | 返回 c1 是否等于 c2 (对每个元素调用 ==) |
c1 != c2 | 返回 c1 是否不等于 c2(相当于 !(c1 == c2)) |
c1 < c2 | 返回 c1 是否小于 c2 |
c1 > c2 | 返回 c1 是否大于 c2(相当于 c2 < c1) |
c1 <= c2 | 返回 c1 是否小于等于 c2 (相当于 !(c2 < c1) ) |
c1 >= c2 | 返回 c1 是否大于等于 c2(相当于 !(c1 < c2)) |
List 赋值操作
操作 | 描述 |
---|---|
c = c2 | 将 c2 的全部元素赋值给 c |
c = rv | 将 rvalue rv 的所有元素以 move assign 方式给予 c (始自 C++11) |
c = initlist | 将初值列 initlist 的所有元素赋值给 c (始自 C++11) |
c.assign(n,elem) | 复制 n 个 elem,赋值给 c |
c.assign(beg , end) | 将区间 [beg, end) 内的元素赋值给 c |
c.assign(initlist) | 将初值列 initlist 的所有元素赋值给 c |
c1.swap( c2) | 置换 c1 和 c2 的数据 不抛出异常 |
swap(c1 , c2) | 置换 c1 和 c2 的数据 不抛出异常 |
List 访问
操作 | 描述 |
---|---|
c.front() | 返回第一元素(不检查是否存在第一元素) |
c.back() | 返回最末元素(不检查是否存在最末元素) |
迭代器相关操作
操作 | 描述 |
---|---|
c.begin() | 返回一个 bidirectional iterator 指向第一元素 |
c.end() | 返回一个bidirectional iterator 指向最末元素的下一位置 |
c.cbegin() | 返回一个 const bidirectional iterator 指向第一元素(始自 C++11) |
c.cend() | 返回一个 const bidirectional iterator 指向最末元素的下一位置(始自 C++11) |
c.rbegin() | 返回一个反向的( reverse ) iterator 指向反向迭代的第一元素 |
c.rend() | 返回一个反向的( reverse ) iterator 指向反向迭代的最末元素的下一位置 |
c.crbegin() | 返回一个 const reverse iterator 指向反向迭代的第一元素(始自 C++11) |
c.crend() | 返回一个 const reverse iterator 指向反向迭代的最末元素的下一位置(始自 C++11) |
元素的安插和移入
操作 | 描述 |
---|---|
c.push_back(elem) | 附加一个 elem 的拷贝于未尾 要么成功,要么无任何作用(no effect ) |
c.pop_back() | 移除最后一个元素,但是不返回它 不抛出异常 |
c.push_front(elem) | 在头部插入 elem 的一个拷贝 要么成功,要么无任何作用(no effect) |
c.pop_front() | 移除第一元素(但不返回) 不抛出异常 |
c.insert(pos , elem) | 在 iterator 位置 pos 之前方插人一个 elem 拷贝,并返回新元素的位置 要么成功,要么无任何作用(no effect) |
c.insert(pos ,n ,elem) | 在 iterator 位置 pos 之前方插入 n 个 elem 拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话) 要么成功,要么无任何作用(no effect) |
c.insert(pos , beg , end) | 在 iterator 位置 pos 之前方插入区间 [beg, end) 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话) 要么成功,要么无任何作用(no effect) |
c.insert(pos , initlist) | 在 iterator 位置 pos 之前方插入初值列 initlist 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos—如果没有新元素的话;始自 C++11) 要么成功,要么无任何作用(no effect) |
c.emplace(pos , args . . .) | 在 iterator 位置 pos 之前方插入一个以 args 为初值的元素,并返回新元素的位置(始自C++11) |
c.emplace_back(args . . .) | 附加一个以 args 为初值的元素于未尾,不返回任何东西(始自 C++11) |
c.emplace_front(args . . .) | 插入一个以 args 为初值的元素于起点,不返回任何东西(始自 C++11) |
c.erase(pos) | 移除 iterator 位置 pos 上的元素,返回下一元素的位置 不抛出异常 |
c.erase(beg , end) | 移除 [beg, end) 区间内的所有元素,返回下一元素的位置 不抛出异常 |
c.remove(val) | 移除所有其值为 val 的元素 只要元素比较动作不抛出异常,它就不抛出异常 |
c.remove_if(op) | 移除所有“造成 op (elem)结果为 true”的元素 只要判断式(predicate)不抛出异常,它就不抛出异 |
c.resize(num) | 将元素数量改为 num (如果 size() 变大,多出来的新元素都需以 default 构造函数完成初始化) 要么成功,要么无任何作用(no effect) |
c.resize(num , elem) | 将元素数量改为 num (如果 size() 变大,,多出来的新元素都是 elem 的拷贝) 要么成功,要么无任何作用(no effect) |
c.clear() | 移除所有元素,将容器清空 不抛出异常 |
特殊更易型操作
操作 | 描述 |
---|---|
c.unique() | 如果存在若干相邻而数值相同的元素,就移除重复元素,只留一个 只要元素比较动作不抛出异常,它就不抛出异常 |
c.unique(op) | 如果存在若干相邻元素都使 op() 的结果为 true,则移除重复元素,只留一个 只要元素比较动作不抛出异常,它就不抛出异常 |
c.splice(pos , c2) | 将 c2 内的所有元素转移(move)到 c 之内、迭代器 pos 之前 不抛出异常 |
c.splice(pos , c2 , c2pos) | 将 c2 内的 c2pos 所指元素转移到 c 内的 pos 所指位置( c 和 c2 可相同) 不抛出异常 |
c.splice(pos , c2, c2beg , c2end) | 将 c2 内的 [c2beg, c2end) 区间内所有元素转移到 c 内的 pos 之前( c 和 c2 可相同) 不抛出异常 |
c.sort() | 以 operator < 为准则对所有元素排序 |
c.sort(op) | 以 op() 为 i 准则对所有元素排序 |
c.merge(c2) | 假设 c 和 c2 容器都包含 op() 准则下的已排序(sorted)元素,将 c2 的全部元素转移到 c,并保证合并后的 list 仍为已排序 只要元素比较时不抛出异常,它便保证“要么成功,要么无任何作用” |
c.merge(c2 , op) | 假设 c 和 c2 容器都包含已排序(sorted)元素,将 c2 的全部元素转移到 c,并保证合并后的 list 在 op() 准则下仍为已排序 只要元素比较时不抛出异常,它便保证“要么成功,要么无任何作用” |
c.reverse() | 将所有元素反序(reverse the order) 不抛出异常 |
实例
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
void printList(const list<int>& l){
printf("list: ");
copy(l.cbegin(), l.cend(), ostream_iterator<int>(cout, " "));
printf("\n");
}
int main()
{
list<int> l1, l2;
for(int i = 0; i < 6; i ++){
l1.push_back(i);
l2.push_front(i);
}
printList(l1);
printList(l2);
printf("\n");
l2.splice(l2.end(), l1);
printList(l1);
printList(l2);
l2.splice(l2.end(), l2, l2.begin());
printList(l2);
printf("\n");
l2.sort();//排序
l1 = l2;
printList(l1);
l2.unique();//去重排序
printList(l2);
printf("\n");
l1.merge(l2);//合并,同时排序
printList(l1);
printList(l2);
return 0;
}