List使用一个双向链表来管理元素。
List的能力
List的内部结构与vector和deque截然不同,因此区别也很显著,如下
1. List不支持随机存取。所以在List遍历是很缓慢的行为
2. 任何位置安插与删除元素非常快
3. 安插和删除元素并不会造成指向其他元素的各个pointer,reference,iterator失效
List提供的成员函数也可以看出来它和vector以及deque的不同
1. 由于不能随机存取,List既不提供下标符,也不提供at()。
2. List并未提供容量/空间分配等操作符,因为并无必要。
3. List提供了不少特殊的成员函数,专门用于移动元素。较之同名的STL通用算法,这些函数执行更快,因为它们无需拷贝或移动,只需调整若干指针即可
List的操作函数
- 生成,复制,销毁
- 非变动性操作
- 赋值操作
- 元素存取
List不支持随机操作,只有front和back能够直接存取元素,这些函数并不检查空,所以调用者必须确保容器至少含有一个元素,如
list<int> col;
if (!col.empty())
{
cout << col.back();
}
- 迭代器相关函数
只有运用迭代器才能存取list中的各个元素,且由于list不能随机存取,这些迭代器只是双向迭代器。所以凡是用到随机迭代器的算法,你都不能调用。 - 元素的安插和移除
其特有的函数有remove(),remove_if()等等
下面看例子
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;
int main(void)
{
list<int> col;
col.push_back(1);
col.push_back(2);
col.push_back(3);
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 1 2 3
cout << endl;
col.insert(col.begin(),0);
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 0 1 2 3
cout << endl;
col.insert(col.begin(),col.begin(),col.end());
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 0 1 2 3 0 1 2 3
cout << endl;
col.remove(0);
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 1 2 3 1 2 3
cout << endl;
col.erase(col.begin());
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); //2 3 1 2 3
cout << endl;
col.clear();
copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); //不打印
return 0;
}
- splice函数
List的好处就是不论任何位置,元素的安插和移除都只需要常数时间,如果你需要将容器A中的若干元素转放到容器B中,那么就好办了,只需重新定义一些指针就好了。为此list提供了特殊的变动性函数用于改变元素和区间的次序,或是用来重新串连。
例子
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;
int main(void)
{
int arr1[] = {1,2,2,3,4};
list<int> col1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 2 3 4
cout << endl;
col1.unique();
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4
cout << endl;
int arr2[] = {5,6};
list<int> col2(arr2,arr2+2);
copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //5,6
cout << endl;
col1.splice(col1.begin(),col2);
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 5 6 1 2 3 4
cout << endl;
copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //不打印任何,因为col2的元素已被移到col1中去了
cout << endl;
col1.sort();
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4 5 6
cout << endl;
col1.reverse();
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 6 5 4 3 2 1
cout << endl;
return 0;
}
再看一个关于merge()的例子
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;
int main(void)
{
list<int> col1;
col1.push_back(1);
col1.push_back(12);
col1.push_back(30);
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 3
cout << endl;
list<int> col2;
col2.push_back(4);
col2.push_back(5);
col2.push_back(6);
copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); // 4 5 6
cout << endl;
list<int> col3(col2);
col1.merge(col2);
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 4 5 6 12 30
cout << endl;
col2.reverse();
copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //不打印
cout << endl;
col3.reverse();
col1.merge(col3);
copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); //没有排序
return 0;
}
关于list的merge()函数还没有细研究,反正记住使用这个成员函数是有条件的,必须是有序元素。
总结
可以看出list比一般容器共通操作多出的函数如下
assign(n,elem);
assign(beg,end);
remove(val);
remove_if(op);
resize(num);
resize(num,elem);
unique();
unique(op);
c1.splice(pos,c2);
c1.splice(pos,c2,c2pos);
c1.splice(pos,c2,c2beg,c2end);
sort();
merge();
reverse();
- 首先可以看出list比一般容器多了许多与拼接(splice)有关的成员函数,当然是因为其实作版本一般是双向链表,所以很多操作只需要移动指针就可以,效率很高