一、概述
list使用一个双向链表来管理数据。使用list必须含入头文件<list>,其型别定义如下:
namespace std{
template <class T,
class Allocator = allocator<T> >
class list;
}
list不支持随机存取,所以既不提供下标操作符,也不提供at()。list相较于vector的好处是每次插入或者删除一个元素,就配置或者释放一个元素空间。对于任何位置的元素插入或元素移除,list永远是常数时间。
二、list内部结构
list本身和list节点是不同的结构,需要分开设计,STL list节点结构如下:
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer prev;
void_pointer next;
}
SGI list不仅是一个双向链表,而且还是一个环状双向链表,结构图如下

三、list的操作函数
1. 生成、复制和销毁
| 操作 | 效果 |
|---|---|
| list<Elem> c | 产生一个存放Elem类型元素的空list |
| list<Elem> c1(c2) | 产生一个与c2同型的list,每个元素都被复制 |
| list<Elem> c(n) | 产生一个含有n个元素,以default构造函数产生元素的list |
| list<Elem> c(n,elem) | 产生一个含有n个elem元素的list |
| list<Elem> c(beg,end) | 产生一个以区间[beg,end]内元素为初值的list |
| c.~list<Elem>() | 销毁所有元素,释放内存 |
2. 非变动性操作
| 操作 | 效果 |
|---|---|
| c.size() | 返回元素个数。 |
| c.empty() | 判断容器大小是否为0。 |
| c.max_size() | 返回可容纳元素最大数量 |
| c1 == c2 | 判断c1是否等于c2 |
| c1 != c2 | 判断c1是否不等于c2 |
| c1 < c2 | 判断c1是否小于c2 |
| c1 > c2 | 判断c1是否大于c2 |
| c1 <= c2 | 判断c1是否小于等于c2 |
| c1 >= c2 | 判断c1是否大于等于c2 |
| c.front() | 返回第一个元素,不检查元素是否存在 |
| c.back() | 返回最后一个元素,不检查元素是否存在 |
| c.begin() | 返回一个随机存取迭代器,指向第一元素 |
| c.end() | 返回一个随机存取迭代器,指向最后一个元素的下一位置 |
| c.rbegin() | 返回一个逆向迭代器,指向逆向迭代时的第一个元素 |
| c.rend() | 返回一个逆向迭代器,指向逆向迭代时最后元素的下一位置 |
3. 赋值操作
| 操作 | 效果 |
|---|---|
| c1 = c2 | 将c2的全部元素赋值给c1。 |
| c.assign(n,elem) | 将elem的n个拷贝赋值给c。 |
| c.assign(beg,end) | 将区间[beg,end]的元素赋值给c |
| c1.swap(c2) | 将c1和c2元素互换 |
| swap(c1,c2) | 同上,此为全局函数 |
4. 元素存取操作
| 操作 | 效果 |
|---|---|
| c.front() | 返回c的第一个元素,不检查元素存在与否 |
| c.back() | 返回c的最后一个元素,不检查元素存在与否 |
5. 迭代器函数
list迭代器不支持随机存取,这些迭代器只是双向迭代器。
| 操作 | 效果 |
|---|---|
| c.begin() | 返回一个双向迭代器,指向第一个元素 |
| c.end() | 返回一个双迭代器,指向最后一个元素的下一位置 |
| c.rbegin() | 返回一个逆向迭代器,指向逆向迭代的第一个元素 |
| c.rend() | 返回一个逆向迭代器,指向逆向迭代的最后元素的下一位置 |
6. 元素的安插和移除
| 操作 | 效果 |
|---|---|
| c.insert(pos,elem) | 在pos位置插入一个elem副本,返回新元素的位置 |
| c.insert(pos,n,elem) | 在pos位置插入n个elem副本,无返回值 |
| c.insert(pos,beg,end) | 在pos位置插入区间[beg,end]内的元素,无返回值 |
| c.push_back(elem) | 在尾部添加一个elem的副本 |
| c.pop_back() | 移除最后一个元素,不回传 |
| c.push_front(elem) | 在头部插入一个elem副本 |
| c.pop_front() | 移除头部元素,不回传 |
| c.remove(val) | 移除所有值为val的元素 |
| c.remove_if(op) | 移除所有造成op(elem)结果为true的元素 |
| c.erase(pos) | 移除pos位置所指元素,返回下一元素的位置 |
| c.erase(beg,end) | 移除区间[beg,end]内的元素,返回下一元素的位置 |
| c.resize(num) | 将大小改为num。如果size增长了,新增大小以default构造函数产生出来 |
| c.resize(num,elem) | 将大小改为num。如果size增长了,新增大小以elem副本产生出来 |
| c.clear() | 移除所有元素,将容器清空 |
7. 特殊变动性操作
| 操作 | 效果 |
|---|---|
| c.unique() | 如果存在若干相邻而数值相等的元素,则移除重复元素,只留下一个 |
| c.unique(op) | 如果存在若干个相邻元素都使op()的结果为true,则移除重复元素,只留下一个 |
| c.splice(pos,c2) | 将c2内的所有元素转移到c1内、迭代器pos之前 |
| c.splice(pos,c2,c2pos) | 将c2内的c2pos所指元素转移到c1内的pos所指的位置上,c1和c2可以相同 |
| c.splice(pos,c2,c2beg,c2end) | 将c2内的[c2beg,c2end]区间所有元素转移到c1内的pos之前 |
| c.sort() | 以operator<为准则对所有元素排序 |
| c.sort(op) | 以op()为准则对所有元素排序 |
| c.merge(c2) | 假设c1和c2内的元素已序,将c2内的全部元素转移到c1,保证合并后的list仍然有序 |
| c.merge(c2,op) | 假设c1和c2内的元素按照op()已序,将c2内的全部元素转移到c1,保证合并后的list仍然在op()准则下有序 |
| c.reverse() | 将所有元素反序 |
8. 异常处理
所有STL标准容器中,list对于异常安全性提供了最佳支持。
| 操作 | 保证 |
|---|---|
| push_back() | 如果不成功,就没有任何作用 |
| push_front() | 如果不成功,就没有任何作用 |
| insert() | 如果不成功,就没有任何作用 |
| pop_back() | 不抛出异常 |
| pop_front() | 不抛出异常 |
| erase() | 不抛出异常 |
| clear() | 不抛出异常 |
| resize() | 如果不成功,就没有任何作用 |
| remove() | 只要元素比较操作不抛出异常,就不抛出异常 |
| remove_if() | 只要判断式不抛出异常,就不抛出异常 |
| unique() | 只要元素比较操作不抛出异常,就不抛出异常 |
| splice() | 不抛出异常 |
| merge() | 只要元素比较时不抛出异常,保证“要么不成功,要么没有任何作用” |
| reverse() | 不抛出异常 |
| swap() | 不抛出异常 |
四、程序示例
list的使用示例
//example of list
#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.begin(), l1.end(), ostream_iterator<int>(cout, " "));
cout << endl << "list2: ";
copy(l2.begin(), l2.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
}
int main()
{
list<int> l1, l2;
for (int i = 0; i < 6; ++i){
l1.push_back(i);
l2.push_front(i);
}
printLists(l1, l2);
l2.splice(find(l2.begin(), l2.end(), 3), l1);
printLists(l1, l2);
l2.splice(l2.end(), l2, l2.begin());
printLists(l1, l2);
l2.sort();
l1 = l2;
l2.unique();
printLists(l1, l2);
l1.merge(l2);
printLists(l1, l2);
l1.reverse();
printLists(l1,l2);
l1.sort();
printLists(l1,l2);
return 0;
}
输出结果:
本文详细介绍了C++ STL中的list容器,包括其内部结构、操作函数、迭代器使用及异常处理等内容,并通过示例展示了list的基本用法。
1435

被折叠的 条评论
为什么被折叠?



