list的介绍和使用

目录

杂谈

构造函数

容量相关函数

1.empy

2.size

修改函数

1.emplace、emplace_back、emplace_front

2.assign

3.insert(迭代器失效?)

4.erase(迭代器失效?)

5.clear

6.swap

操作函数

1.可以发现和vector一样,都没有提供find接口。

2.sort(有了算法库的sort,为什么要提供成员函数sort?)

3.merge 

4.reverse

5.unique

6.splice

7.remove

8.remove_if


杂谈

和vector一样,list也是一个类模板。第一个模板参数T表示list用于存什么类型的数据,第二个模板参数表示内存池类。

有人可能认为在刷题时似乎很少用到list,进而认为list不常用,实际上这是一种短视的看法,刷题时用得多只是因为测试用例都是以数组的形式给的,而在实际工作中,list是很常用的一种容器,因为vector有优点的同时也有许多缺点,比如vector在频繁头插或者头删的场景下效率十分低下,此时就不该用vector,而可以试试list。

构造函数

1.第一种表示默认构造,因为内存池对象可以不传,所以可以认为是无参的。

2.用n个val构造list,老熟人了。

3.利用迭代器区间构造list,不包括last指向的元素,因此区间为左闭右开【first,last) 。

4.拷贝构造。

容量相关函数

可以肉眼观察到 list的容量相关函数对比vector和string少了许多,这是因为list不涉及到扩容相关的问题,list只用按需申请即可。

1.empy

用于判断list是否为空,即是否存储了有效数据。

2.size

用于返回list中存储的有效数据的个数,返回类型为size_t。

修改函数

1.emplace、emplace_back、emplace_front

这边涉及到右值引用,暂且留到C++11讲解,只需知道这三个接口的功能分别对应insert、push_back、push_front。

2.对比vector修改函数的区别

可以发现list没有提供operator【】()接口,不支持随机访问。

2.assign

用于给list赋值。

3.insert(迭代器失效?)

可以发现使用方式和vector的insert没有什么不同。注意,因为list不需要扩容,因此不管怎么insert,list中的迭代器都不会失效。

1.在迭代器position指向的位置上插入T类型的val。

2.在迭代器position指向的位置上插入n个val。

3.在迭代器position指向的位置上插入一段迭代器区间的值。

4.erase(迭代器失效?)

1.删除迭代器position指向位置上的元素。

2.删除迭代器区间【first,last)上所有的元素,注意不包括last指向的元素。

erase函数是有返回值的,erase一个元素后会返回指向该元素的下一个元素的迭代器。

如下图演示能够证明erase是存在迭代器失效的,这里也很好理解,毕竟erase一个节点后,这个节点肯定是要被delete从堆上释放的,但注意此时迭代器还指向被删除节点的空间,再次通过迭代器去访问节点就是经典的野指针问题了。

5.clear

用于清空链表。

6.swap

用于交换链表管理的数据。

操作函数

1.可以发现和vector一样,都没有提供find接口。

list和vector与string不同,他俩都没有提供find接口。这是因为所有容器都有迭代器,所以find可以实现成一个函数模板,这样find就可以通过迭代器在任意容器里寻找指定元素,此时vector或者list再提供一个find成员函数就多此一举了。而string类和它们不太一样,因为在string中查找时,可能找一个字符,可能找一个字串,找到后返回下标。因为string的查找具有多样性,从而导致了string的查找比较独特,所以STL认为有必要单独为string实现一个find接口。 

对于算法库中的find,如果找到了目标元素,则返回指向目标元素的迭代器;反之返回指向最后一个元素后一个位置的迭代器,即相当于container.end()。

2.sort(有了算法库的sort,为什么要提供成员函数sort?)

用于给list中的元素排序,默认是排升序。模板参数Compare必须是一种可调用对象的类型,comp则必须是一种可调用对象,比如函数对象(即仿函数)、函数指针、函数等,如果想排降序,则给comp传一个逻辑为排降序的可调用对象。

这里有一个问题:明明<algorithm>中已经有一个sort了,为什么list要多此一举提供一个成员函数sort呢?

答案:因为list用不了算法库中的sort。如下图,可以观察到算法库中的sort是通过随机存取迭代器排序的,而list的物理空间不是连续的,因此list的迭代器不是随机存取迭代器,所以list用不了算法库里的sort,为此STL给list单独设计了成员函数sort。

3.merge 

用于将两条list合并再排序,如下图演示,ls1合并ls2后,因为ls1调用的该接口,因此ls2被清空了。

4.reverse

用于逆置list中的元素。

5.unique

用于删除list中的重复值,即去重,如下图演示。

注意unique去重是对数据有要求的,要求数据必须有序,因此使用unique前必须调用sort成员函数排序。也正是因为要排序,导致unique接口不常用,因为list排序的代价较大。去重我们可以用未来要学习的set容器,只需要将所有数据往set里插入,它天然支持去重。

6.splice

用于将链表A的全部或者某一部分转移到另一条链表B上,注意链表A的节点被转移是真正意义上的转移了,如下图演示,将整个ls2转移到ls1后,ls2这条链表就是一条空链表了。

接口1:将链表x整体移到迭代器position指向的另一条链表上。

接口2:将迭代器i指向的位于链表x上的单个节点转移到迭代器position指向的另一条链表上。

接口3:将链表的一个迭代器区间上的所有节点转移到迭代器position指向的另一条链表上。

7.remove

 用于删除链表中所有值等于val的节点,这个接口本质就是先find然后erase的多次循环。

8.remove_if

也是用于删除链表中的节点,只不过这里可以自定义删除的条件,比如大于10就删除等等。这里的模板参数Predicate必须是一种可调用对象的类型,pred也必须是一种可调用对象,比如函数对象(即仿函数),函数指针,函数等等,如下图所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值