容器list,所控制的长度为N的序列是以一个有着N个节点的双向链表来存储的,支持双向迭代器。
优势:可以在链表中随意的插入和删除元素或是子链表,所需的仅是改变前后指针。
劣势:在定位操作中比如查找和随即存取,时间是线性增加的,而且在存储上每个节点还有前向和后向两个指针。
异常:模版类list的另外一个有点是在异常处理方面,对任何容器来说,器成员函数在执行中抛出的异常,使容器本身处于一种一致的状态,可以被销毁,并且容器没有对其所分配的存储空间失去控制。但对大部分操作尤其是那些能够影响多个元素的操作,当抛出异常时,并美欧制定容器的精确状态,但list保证对于大部分成员函数抛出异常时,容器能够恢复到操作前的状态。
typedef list<T,allocator<T>> mycont; //使用默认模版参数,可以省略第二个参数
构造函数:
list() 声明一个空列表;
list(al) 声明一个空列表,但她还存储一个分配器对象al;
list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的
list(n,val,al) 声明一个和上面一样的列表,但还存储分配器对象al;
list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素
list(first,last,al) 声明一个和上面一样的列表,但它还存储分配器对象al;
resize 为了被控序列的长度改为只容纳n个元素,超出的元素将被删除,如果需要扩展那么默认值为T()的元素会被放到序列末端。
clear 删除所有元素
front back 存取被控序列的第一个元素;存取被控序列的最后一个元素。如果它不是一个常量表达式可以作为一个左值。如果序列为空,则这种行为将是未定以的。
push_back 向对象末端插入值为x的元素;push_front为对象开始处插入元素;pop_back删除最后一个元素;pop_front删除第一个元素;序列必须不为空,否则调用将是为定义。
assign 为了将被控序列替换成由(first,last)所指定的序列。且不能是原序列的一部分。
insert 为了在迭代器it指定的元素前插入一个元素,返回值是一个迭代器,只想刚插入的元素,也可以插入一个序列
erase 删除it所指定的元素,返回值为一个迭代器,只想下一个元素,也可以删除一个区间。
splice 将一系列的列表节点接入到一个列表中,被接入的节点列表将会被删除,接入操作中没有元素复制,只是将节点中的指针改写;cont.splice(it,cont2)把对象cont2中所有内容接入,这两个对象必须不同;cont.splice(it,cont2,p)将对象cont2中迭代器p指定的节点接入到由迭代器it指定的节点前面,这两个对象可以相同;cont.splice(it,cont2,first,last)将cont2中指定的序列接入到迭代器it所指定的元素前面,这两个对象可以相同,但it不能是序列的一部分;这两个列表所拥有的分配器对象必须相等。
remove 删除所有值等于v的元素;remove_if 删除所有似的pr(x)为true的元素x;//在STL中比较特殊的它真正的删除了元素-b-
unique 删除指定范围内相同的元素;//在STL中比较特殊的好像- -#
sort 将序列排序,结果序列是按operator<排序的,操作中用到了接入操作,可以将pr作为排序函数;
merge 将两个讲过排序序列合并,合并中用到了接入操作,合并后第二个序列将为空,可以用pr替换排序函数;
reverse 翻转整个序列;
测试:
// 1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "list"
#include "assert.h"
using namespace std;
typedef list<int> mycont;
int main(int argc, char* argv[])
{
mycont mylist1;
assert(mylist1.empty()&&mylist1.size()==0);
mycont mylist2(5),mylist3(6,'x');
assert(mylist2.size()==5&&mylist2.back()=='/0');
assert(mylist3.size()==6&&mylist3.back()=='x');
mycont mylist4(mylist3);
assert(mylist4.size()==6&&mylist4.back()=='x');
mycont mylist5(mylist4.begin(),mylist4.end());
assert(mylist5.size()==6&&mylist5.back()=='x');
mylist5.resize(8);
assert(mylist5.size()==8&&mylist5.back()=='/0');
mylist5.assign(mylist3.begin(),mylist3.end());
assert(mylist5.size()==mylist3.size()&&mylist5.back()==mylist3.back());
mylist4.clear();
for (int i=0;i<3;i++)
{
mylist4.insert(mylist4.begin(),i); // 2 1 0
}
mylist5.clear();
for (int y=3;y>0;y--)
{
mylist5.insert(mylist5.begin(),y);//1--3
}
assert(mylist5.front()==1&&mylist5.back()==3);
mylist5.splice(mylist5.begin(),mylist4);
assert(mylist5.front()==2&&mylist5.size()==6);//2 1 0 1 2 3
assert(mylist4.size()==0);//被插入序列将被删除
mylist5.sort();
assert(mylist5.front()==0&&mylist5.back()==3);//0 1 1 2 2 3
mylist5.remove(1);
assert(mylist5.size()==4);
mylist5.unique();
assert(mylist5.size()=3);
//front back begin end 的不同
return 0;
}