目录
List使用一个doubly linked list(双向串列)管理元素,按惯例,C++标准库并未明定实现方式,只是遵守list的名称、限制和规格。List其实相当于数据结构中的双链表,List对象提供了两个pointer,分别指向前后元素。。只有运用迭代器,才能访问 list 容器中存储的各个元素。因此,list特性:
1、List不支持随机访问,因此访问元素的效率较低;
2、任何位置上,执行元素的插入和移除都很快,始终是常量时间内完成,因为无需移动任何元素;
3、安插和删除的操作不会因此指向其他元素的pointer、reference、iterator失效;
4、List对异常的控制是,要么操作成功,要么什么都不发生。
使用list时必须先包含头文件:
#include<list>
1、list构造
list<类型> 对象名;
示例:
1)产生一个list对象,没有任何元素:
list<int> c;
2)copy构造函数,建立c2同型list并成为c2的一份副本,该复制是深度复制:
list<Elem>c(c2);
list<Elem>c=c2;
3)rv是一个list右值引用,那么这里的构造函数是一个Move构造函数,建立一个新的list,取右值内容:
list<Elem>c(rv)
list<Elem>c=rv
4)利用元素的默认构造函数生成一个大小为n(容量也为n)的vector:
list<Elem>c(n)
5)建立一个大小为n的list,并初始化为elem:
list<Elem>c(n,elem)
6)建立一个list,并以迭代器所指向的区间[beg,end)作为元素值:
list<Elem>c(beg,end)
7)建立一个list,以初值列init list元素为初值(C++11新特性):
list<Elem>c(initlist)
list<Elem>c=initlist
8)销毁所有元素,释放内存:
c.~list()
使用示例:
#include <iostream>
#include <list>
using namespace std;
int main()
{
list <int > L0; // 空链表
list <int > L1(9); // 建一个含9个默认值是0的元素的链表
list <int > L2(5, 1); // 建一个含5个元素的链表,默认值都是1
list <int > L3(L2); // 建一个L2 的深copy链表
list <int > L4(L0.begin(), L0.end());// 建一个含L0一个区域的元素
list<int> c = L2;
for (auto it = c.begin(); it != c.end(); it++) {
cout << " " << *it;
}
cout << endl;
return 0;
}
2、元素插入
2.1、insert
1)在iterator指向的pos位置的前方插入一个元素elem的副本,并返回新元素的位置(此时返回的是整型,而非iterator)。
c.insert(pos,elem);
2)在iterator指向的pos位置的前方插入n个元素的副本,并返回第一个新元素的位置。
c.insert(pos,n,elem);
3)在iterator指向的pos位置的前方插入区间[beg,end)内所有元素的副本,并返回第一个新元素的位置。
c.insert(pos,beg,end);
4)在iterator指向的pos位置的前方插入初始化列表所有元素的副本,并返回第一个元素的位置。
c.insert(pos,initlist);
操作示例:
L1( 1,2,3), L2(4,5,6);
list1.insert(++list1.begin(),9); // list1(1,9,2,3)
list1.insert(list1.begin(),2,9); // list1(9,9,1,2,3);
list1.insert(list1.begin(),list2.begin(),--list2.end());//list1(4,5,1,2,3);
2.2、push_back or pop_front
1)在list末尾插入元素elem
c.push_back(elem)
2)在首部插入元素elem
c.push_front(elem)
3、访问
1)front() 返回第一个元素的引用
int nRet = list1.front() // nRet = 1
2)back() 返回最后一 元素的引用
int nRet = list1.back() // nRet = 3
3)begin() 返回第一个元素的指针(iterator)
it = list1.begin(); // *it = 1
4)end() 返回最后一个元素的下一位置 的指针(list 为空时end()=begin())
it = list1.end();
--it; // *it = 3
5)rbegin() 返回链表最后一 元素的后向指针(reverse_iterator or const)
list ::reverse_iterator it = list1 .rbegin (); // *it = 3
6)rend() 返回链表第一元素的 下一位置 的后向指针
list< int>::reverse_iterator it = list1 .rend(); // *(--riter) = 1
3、元素移除
3.1、pop_back or pop_front
1)移除最后一个元素,但是不返回该元素
c.pop_back()
2)移除首部元素,但是不返回该元素
c.pop_front()
3.2、erase
1)移除iterator位置pos上的元素,返回下一个元素的位置
c.erase(pos)
2)移除区间[beg,end)所指向的元素所有内容,返回下一个元素的位置
c.erase(beg,end)
3.3、remove or remove_if
1)移除所有值为val的元素
c.remove(val)
2)移除所有符合op(elem)为true的元素
c.remove_if(op)
示例:
// 小于2 的值删除
bool myFun (const int & value ) { return (value < 2); }
list1.remove_if( myFun ); // list1(3)
3.4、clear
1)移除所有元素,容器清空
c.clear()
3.5、resize
1)将list大小调整为num,若大小增大,新元素以默认构造函数或者零值进行初始化
c.resize(num)
2)将list大小调整为num,若大小增大,新元素以elem进行初始化
c.resize(num,elem)
示例代码:
1、移除所有值为9的元素
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> c{ 1,2,3,4,5,6,7,8,9,9,9,9,9,9 };
c.remove(9);
for (auto it = c.begin(); it != c.end(); it++)
{
cout << " " << *it;
}
cout << endl;
return 0;
}
输出:
4、list特殊函数
4.1、unique
只对相邻元素去重,不相邻的不做处理。
1)如果存在若干相邻数值相同的元素,就移除重复元素,只留一个
c.unique()
2)如果存在若干相邻元素都使op()结果为true,移除重复元素,只留一个
c.unique(op)
4.2、splise
1)c.splise(pos,c2)
将c2内所有的元素转移到c之内,迭代器指向的pos位置之前
2)c.splise(pos,c2,c2pos)
将c2内的c2pos所指元素转移到c的pos所指位置
3)splise(pos,c2,c2beg,c2end)
将c2区间[beg,end)内所有的元素转移到c内的pos之前
4.3、sort
1)c.sort()
默认从小到大排序。
2)c.sort(op)
以op()定义的准则进行排序,以下输出按大到小排序。
#include <iostream>
#include <list>
using namespace std;
bool op(int&a, int&b)
{
return a > b;
}
int main() {
list<int> c{ 45,78,385,7,4,978,49,11 };
c.sort(op);
for (auto it = c.begin(); it != c.end(); it++) {
cout << " " << *it;
}
cout << endl;
return 0;
}
输出:
4.4、merge
1)c.merge(c2)
假设c和c2容器都包含op()准则下的已排序元素,将c2的全部元素转移到c,并保证合并后的list依然有序。
list<int> l1 {45,78,385,7,4,978,49,11};
list<int> l2 {-1,-5,-2,-4,-3};
l1.merge(l2);
l1 =>
-1,-5,-2,-4,-3,45,78,385,7,4,978,49,11
注意:可以看出list所谓的合并有序,是指l和2的相对有序,而不是整体有序。
2)c.merge(c2,op)
在op()准则下进行合并,合并后的元素有序。
4.5、reverse
1)c.reverse()
将所有元素逆序。
4.6、swap
swap() 交换两个链表( 两个重载)
list1.swap(list2); // list1 (4 ,5 ,6 ) list2 (1 ,2 ,3 )
参考文章
1、std::list使用方法
https://blog.csdn.net/tianzy16/article/details/84949500
2、STL STD::list使用说明
https://blog.csdn.net/lanyzh0909/article/details/7567696
3、C++ STL list迭代器及用法