list的一些常用接口
其实list的接口和前面的string和vector基本都是一样的,用法也基本类似,我们还是挑几个讲讲吧。
一.常用的接口
1.1 push_back
图中是一个空参构造加上一个push_back的使用,这两个接口的使用还是很简单的,看一下即可。下面是迭代器的使用,都是很简单的。
1.2 emplace_back
这个emplace_back的作用和push_back在插入一些内置类型的时候是没有什么区别的,但是在插入自定义类型的时候是有些区别的。
这是我们写的一个自定义类型的类A,接下来我们来掩饰一下。
我们发现当我们通过创建对象尾插和匿名对象的尾插,这两个函数都是可以实现的,但是在进行隐式类型转换的尾插的时候,这个emplace_back是无法完成的,这是为什么呢?
bb.emplace_back({ 1, 2 });
这行代码报错的根源在于,emplace_back
尝试直接在容器的末尾构造对象,而使用花括号初始化列表 { 1, 2 }
时,编译器没办法明确应该如何将其转换为 A
类的对象。
详细解释
-
push_back
和花括号初始化列表:push_back
能够接受花括号初始化列表,这是因为它会调用隐式转换构造函数。编译器会尝试把{ 1, 2 }
转换为A
类的对象,由于A
有一个模板构造函数A(T a, T b)
,编译器能够推断出T
为int
,进而调用这个构造函数来创建A
类的对象。 -
emplace_back
和花括号初始化列表:emplace_back
是直接在容器的末尾构造对象,它会把参数原封不动地传递给构造函数。当你使用{ 1, 2 }
时,编译器无法确定这是一个参数包还是一个初始化列表,所以无法调用模板构造函数。
我们该怎么解决呢?
最后一行代码它会直接调用构造来生成,更加高效,它是直接把两个参数给了构造函数构造,只需要一次构造函数的过程更加的高效。
1.3 remove
这个函数的作用就是删除list链表当中的指定元素,我们下面来演示一下。
看一下这个,第一次我们要删除100,但是链表中没有100,它会什么都不做,也不会报错。
我们发现第二个remove(5),他确实把5删除了,第三个remove(8)是把全部的8都给删除了。
1.4 sort函数
这个sort函数不是算法库中的sort函数,而是我们链表自己实现的sort函数。
list类中为什么还要写一个sort函数呢?直接用算法库的不行吗?
我们发现是无法使用的,因为list的迭代器是双向迭代器不是随机迭代器,因为链表只支持++/--不支持+/-,所以无法使用这个sort函数。
下面来科普一下迭代器的种类。
迭代器分为五类,输入迭代器、输出迭代器、单向迭代器、双向迭代器和随机访问迭代器。,单向迭代器只支持++的功能不支持--/+/-的功能,而双向迭代器支持++/--但是不支持+/-的功能,随机迭代器是都支持,我们的list链表就是典型的双向迭代器,因为我们都知道链表的空间不是连续的,所以实现两个迭代器之间的+/-操作没什么意义,而我们的vector和string的空间都是连续的,所以它们两个都是随机迭代器。
如上图所示,我们算法库中的sort函数接收的是随机迭代器,我们传入的是双向迭代器,无法完成+/-的功能,所以不能作为参数传过去。
这个参数代表双向迭代器,它可以传双向迭代器也可以传随机迭代器,因为随机迭代器也能进行++/--的操作,但是不能传单向迭代器,因为单向迭代器无法进行--的操作。
这个就是单项迭代器的参数表示了,他什么类型的迭代器都可以传。
我们找到了报错原因,知道了为什么不能使用算法库的了,接下来我们就用我们算法库中的吧。
使用的形式就是list对象.sort()的形式,不用传参数。
但是这个sort()建议数据量少的时候可以用,大的时候就不要用了,我们来看一下为什么。
我们来跑一下就可以看出来了。
我们可以看出,list的排序效率不如vector。
所以在排大数据的时候我们可以先把链表中的内容放入vector中,再放回list中即可。
我们可以看到即使我们先把list中的数据放入vector中再把结果放回list中所用的时间还是比直接同list的sort函数的所用的时间短,所以处理大数据的时候我们可以使用这样的形式。
1.6 assign
std::list
是一个双向链表容器,assign
是 std::list
的一个成员函数,其主要作用是将新的元素赋值给 std::list
,替换掉 std::list
中原来的所有元素,效率挺高的。
这就是它的全部用法了,第一个表示用5个10给它初始化,第二个表示用1,2,3,4,5,6给它初始化,第三个是通过迭代器初始化的,list的迭代器是双向迭代器,不能进行+/-操作,vector的迭代器是随机迭代器,可以进行+/-操作,这样就是全部的用法了,也是很简单的。
1.7 unique
这个函数的作用就是去重的,只能去除相邻 元素的重复。
就把相邻重复的8去掉了,那么如果我们想去除全部的重复元素呢,我们该怎么办呢?
要配合sort使用了
这样就可以了,先排序,再去重即可。
如上图结果所示,达到了我们预期的效果。
1.8 splice
也是有三种的用法,我们分别来试一下。
这是第一个用法,表示在v1的end位置放上v2,此时v2的数据就会被移除。
v2没有打印结果,表示没有数据了。
第二个用法。
第一个参数是你要放的位置,第二个参数是你要放的哪个对象的数据,最后一个位置就是找到要放的那个数据。
此时就会把1放在最后了。
第三种用法。
就是在v1的end位置上放上v2的begin到end位置的数据。
就达到了预期的效果了。
我们常用的接口都讲解完毕了。
这些其他的接口大家感兴趣了都可以试一下。
二.结束语
感谢大家的查看,希望可以帮助到大家,做的不是太好还请见谅,其中有什么不懂的可以留言询问,我都会一一回答。 感谢大家的一键三连。