List结构
list使用双向链表来管理元素,可以从两端发展新元素,其内部结构如图1所示。
图1 list的结构
List能力
List的内部结构和vetor或deque截然不同,主要的区别入下:
- list不支持随机存取功能,可以支持首尾的直接存取,想获取其他元素,则需要遍历链表。
- 任何位置的删除、插入操作都非常快速,不需要移动和删除其他元素,这些操作在常数时间内完成。
- 安插和删除操作不会造成指向其他元素的各个pointer、reference、iterators失效
- list对异常操作的处理方式:要么成功,要么什么都不发生。
- list提供了不少特殊的成员函数,专门用于移动元素,和STL的通用算比较,这些成员函数的执行速度更快,主要是成员函数操作时,不需要移动元素或拷贝,仅需要调指针。
Splice函数
list的好处是不论在任何位置,元素的安插和移除都只需要常数时间。如果我们要将若干元素从A容器移动B容器,使用splice函数将会更加高效,splice中文解释为衔接,链接,结合。从名字中就可以看出,该函数的功能,如图2所示是将元素3从容器A转移到容器B中,C之前(举例用,未考虑型别),从执行动作中,可以看到执行splice函数后,原容器中就不包含该元素了,是转移属于操作。
图2 splice举例
List操作函数族
list类提供了多种操作元素的函数和算法,这些函数可以满足大部分的应用场景。
List的构造函数和析构函数list<Elem> c 产生一个空list,其中没有任何元素 list<Elem> c1(c2) 产生另一个同型list的副本(所有的元素都被拷贝) list<Elem> c(n) 利用元素的default构造函数产生一个大小为n的list list<Elem> c(n,elem) 产生一个大小为n的list,每个元素值都是elem list<Elem> c(beg, end) 产生一个list,以区间[beg, end)做为元素初值 c.~list<Elem>() 销毁所有元素,并释放内存 list的非变动性操作c.size() 返回容器的大小 c.empty() 判断容器是否为空,等价于size()==0,但可能更快 c.max_size() 返回容器最大的可以存储的元素 reserve() 如果容量不足,扩大之 c1 == c2 判断c1 是否等于c2 c1 != c2 判断c1是否不等于c2 c1 < c2 判断c1 是否小于c2 c1 > c2 判断c1 是否大于c2 c1 <= c2 判断c1是否小于等于c2 c1 >= c2 判断c1是否大于等于c2 list的赋值操作c1 = c2 将c2的全部元素赋值给c1 c.assign(n, elem) 复制n个elem,复制给c c.assign(beg, end) 将区间[beg;end)内的元素赋值给c c1.swap(c2) 将c1和c2元素互换 swap(c1,c2) 同上,此为全局函数 list元素之间存取c.front 返回第一个元素,不检查元素存在与否 c.back 返回最后一个元素,不检查元素存在与否 list迭代器相关函数c.begin() 返回一个双向迭代器,指向第一个元素 c.end() 返回一个双向迭代器,指向最后一个元素的下一个位置 c.begin() 返回一个逆向迭代器,指向逆向迭代的第一个元素 c.end() 返回一个逆向迭代器,
指向逆向迭代的最后一个元素的下一个位置 list安插、移除操作函数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副本 c.pop_front() 移除第一个元素,但不返回 c.remove(val) 移除所有其值为val的元素 c.remove_if() 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() 移除所有元素,将容器清空 备注:安插和移除元素,都会使“作用点”之后的各个元素的iterator等失效,若发生内存重新分配,该容器身上的所有iterator等都会失效 List的特殊变动性操作c.unique() 如果存在若干相邻而数值相等的元素,就移除重复元素,
之留下一个c.unique(op) 如果存在若干相邻元素,都使op()的结果为ture,
则移除重复元素,只留下一个。c1.splice(pos, c2) 将c2内的所有元素转移到c1之内,迭代器pos之前 c1.splice(pos, c2, c2pos) 将c2内的c2pos所指元素转移到c1之内的pos所指位置上
(c1,c2可相同)c1.splice(pos, c2,
c2beg,c2end)将c2内的[c2beg,c2end)区间内所有元素转移到
c1内的pos之前(c1,c2可相同)c.sort() 以operator<为准则,对所有元素排序 c.sort(op) 以op()为准则,对所有元素排序 c1.merge(c2) 假设c1和c2容器都包含已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list还是已序。 c1.merge(c2,op) 假设c1和c2容器都包含op()原则下的已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list在op()原则仍是已序。 c.reverse() 将所有元素反序
list实例
#include "stdafx.h" #include <list> #include <string> #include <iostream> #include <algorithm> using namespace std; void PrintLists(const list<int> &list1, const list<int> &list2) { cout << "list1: "; copy(list1.begin(), list1.end(), ostream_iterator<int>(cout ," ")); cout << endl << "list2: "; copy(list2.begin(), list2.end(), ostream_iterator<int>(cout, " ")); cout << endl; cout << endl; } void ListExample() { //creat two empty lists; list<int> list1, list2; for (int i = 0; i < 6; ++i) { list1.push_back(i); list2.push_front(i); } //list1: 0 1 2 3 4 5 //list2: 5 4 3 2 1 0 PrintLists(list1, list2); list2.splice(find(list2.begin(), list2.end(), 3), list1); PrintLists(list1, list2); list2.splice(list2.end(), list2, list2.begin()); PrintLists(list1, list2); list2.sort(); list1 = list2; //list1.push_back(-9); list2.unique(); PrintLists(list1, list2); list1.merge(list2); PrintLists(list1, list2); list1.reverse(); PrintLists(list1, list2); }调用ListExample函数后的运行结果: