除了博客https://blog.csdn.net/Master_Cui/article/details/107751785中介绍的操作,list还有一些其他的操作
1.reverse
void reverse();
这个最为简单,作用是反转list
示例
void reversetest()
{
list<int> l={1,2,3,4,5,6,7};
l.reverse();
for (list<int>::iterator it=l.begin();
it!=l.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
2.sort
void sort();
template <class Compare>
void sort (Compare comp);
这个也较为简单,作用是对list中的元素进行排序
示例1
void sorttest()
{
list<int> l={1,3,5,7, 2, 4,6,8};
l.sort();
for (list<int>::iterator it=l.begin();
it!=l.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
第二个重载函数为list排序指定了规则,comp可以为函数指针,函数对象以及lambada表达式
而且comp必须为严格弱序,简单来说,严格弱序就是comp的实现中,如果两个元素相等,要返回false,次序保持不变。
具体原因后续再说
示例2
bool comp(int a, int b) {return a>b;}
void sorttest2()
{
list<int> l{1,3,5,7, 2, 4,6,8};
l.sort(comp);
for (list<int>::iterator it=l.begin();
it!=l.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
上述的comp就是一个严格弱序的比较函数(因为当a与b相等时,返回false,如果加了等号,那么就不是严格弱序),因为list按照comp返回值为true的条件进行排序,所以排序后,list中每个元素都比后面的元素要大,所以排序后结果是降序的
3.merge
void merge (list& x);
template <class Compare>
void merge (list& x, Compare comp);
作用是合并两个有序的list对象,合并完之后,调用对象也是有序的,同时list对象x中的元素都被移动到了调用对象中
示例1
void mergetest()
{
list<int> l1={1,3,5,7};
list<int> l2={2,4,6,8};
l1.merge(l2);
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
通过结果可知,merge函数将l1与l2合并,并将l2中的元素都移动到了l1中,l2变为空
使用merge函数时,要求两个list对象都是已经排好序的,如果list对象不排序,程序将崩溃
示例2
void mergetest()
{
list<int> l1={1,3,5,7};
list<int> l2={4,2,6,8};
l1.merge(l2);
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
所以在使用list的merge方法时,先使用sort方法将list排好序,然后再调用merge
merge方法也可以使用函数指针或者函数对象或者lambda表达式来规定合并两个有序list对象的规则,同样,comp也必须是严格弱序的
示例3
bool isodd1(int a, int b)
{
return a %2==0 && b%2!=0;
}
void mergetest2()
{
list<int> l1={3,1,7,5};
list<int> l2={4,2,8,6};
l1.sort();
l2.sort();
l1.merge(l2,isodd1);
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
上述代码中,首先合并list对象前,对list对象进行排序,然后按照函数isodd1中的规则对l2进行合并,如果a是偶数并且b是奇数,那么将a和b的位置调换
所以最终偶数在前,奇数在后
同时,merge后,将l2中的元素都移动到了l1中,l2变为空
合并过程如下
1 3 5 7->2 1 3 5 7->2 4 1 3 5 7->2 4 6 1 3 5 7->2 4 6 8 1 3 5 7
每次merge时,如果第一次发现满足isodd1的条件,就直接执行merge
4.splice
void splice (iterator position, list& x);
//将list对象x拼接到调用对象的迭代器位置position,splice后,将x中的元素移动到调用对象中,见示例1
void splice (iterator position, list& x, iterator i);
//将x中迭代器位置i指向的元素拼接到调用对象中迭代器位置position,splice后,将x中的迭代器位置i指向的元素移动到调用对象中,见示例2
void splice (iterator position, list& x, iterator first, iterator last);
//将l2中迭代器范围内的元素移动到调用对象中,见示例3
splice函数的作用是拼接两个list对象,和merge类似,只不过splice不要求链表有序,而且可以部分拼接
示例1
void splicetest()
{
list<int> l1={3,1,7,5};
list<int> l2={4,2,8,6};
l1.splice(++l1.begin(), l2);//将l2中的所有元素移动到l1的++l1.begin()位置,拼接后,l2为空
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
示例2
void splicetest2()
{
list<int> l1={3,1,7,5};
list<int> l2={4,2,8,6};
l1.splice(++l1.begin(), l2, ++l2.begin());//将l2中 ++l2.begin()指向的元素2移动到l1中的++l1.begin()的位置
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
示例3
void splicetest2()
{
list<int> l1={3,1,7,5};
list<int> l2={4,2,8,6};
l1.splice(++l1.begin(), l2, ++l2.begin(), --l2.end());
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
for (list<int>::iterator it=l2.begin();
it!=l2.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
5.unique
void unique();
template <class BinaryPredicate>
void unique (BinaryPredicate binary_pred);
函数的作用:如果list对象中有连续重复的元素,那么只保留第一个连续重复的元素,将剩余的连续重复元素删除,如果没有连续重复的元素,不删除该元素
示例1
void uniquetest()
{
list<int> l1={1,1,2,2,3,3,1,1,2,3};
l1.unique();
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
通过上面的例子可以知道,unique并不能去重,只是删除连续重复的元素并将第一个连续重复的元素保留,如果向去重,需要先排序
同样,和sort,merge类似,也可以指定unique的规则,同样需要保证严格弱序
示例2
bool comp(int a, int b) {return a<b;}
void uniquetest()
{
list<int> l1={1,1,2,2,3,3,1,1,2,3};
l1.unique(comp2);
for (list<int>::iterator it=l1.begin();
it!=l1.end();++it) {
cout<<*it<<",";
}
cout<<endl;
}
删除过程如下;
1, 1 , 2, 2, 3, 3, 1, 1, 2, 3(发现1和1不满足comp,所以保留第二个1)->1, 1, 2, 2, 3, 3, 1, 1, 2, 3(发现1和2满足comp,所以删除第1
^ ^ ^ ^
个2)->1, 1, 2, 3, 3, 1, 1, 2, 3(发现1和2满足comp,所以删除第2个2)->1, 1, 3, 3, 1, 1, 2, 3(发现1和3满足comp,所以删除第1个3)
^ ^ ^ ^
->1, 1, 3, 1, 1, 2, 3(发现1和3满足comp,所以删除第2个3)->1, 1, 1, 1, 2, 3(发现1和1不满足comp,所以保留第1个1)->
^ ^ ^ ^
1, 1, 1, 1, 2, 3(发现1和1不满足comp,所以保留第2个1)->1, 1, 1, 1, 2, 3(发现1和2满足comp,所以删除2)->
^ ^ ^ ^
1, 1, 1, 1, 3(发现1和3满足comp,所以删除3)->1, 1, 1, 1
^ ^
参考
http://www.cplusplus.com/reference/list/list/
https://blog.csdn.net/jiange_zh/article/details/78240806