今天来讲一下list:
list:
我们的这个list相当于是一个带头双向循环链表:
我们来看一下我们的list的接口:
我们看这些接口:构造函数和析构函数还有迭代器里面的一些接口:这些接口我们前面的两个容器已经学习过了,我们看一下list里面新的接口:
remove接口是删除数据用的,我们把数据传进去,然后我们调用这个接口,他就会把我们要删除的数据删除掉;
unique接口表示的把数据里面的重复的数据删除掉,只留下一个,但是有一个问题就是他必须是顺序的数据才是有效的,不是顺序的话,就不能完全把重复的数据删除掉;这时候我们还有一个接口sort,这个接口就是为了排序的;
sort接口,这个接口是排序用的,默认的会排升序;
其实我们的算法库里面是有sort排序的,那为什么我们的list还要自己实现一个接口呢?
迭代器的分类:
我们来看一下迭代器的分类:迭代器的类型是由迭代器的底层结构决定的;
我们的string和vector就是随机的迭代器;list是双向的迭代器;
这些迭代器的作用是不一样的,我们单向的迭代器是++,顺序的进行遍历;
双向的迭代器是++/--,可以是正向的遍历迭代器,也可以是逆向的遍历迭代器。
随机迭代器是可以正向的++,逆向的--,也可以是迭代器的相加或者相减。
算法库里面的sort和list的sort:
我们回过头来看一下刚才的问题。
我们来看一下我们的算法库里面的sort函数:
我们的算法库里面的函数sort的参数的类型是randomiterator,随机迭代器,
我们再看一下这个图片,我们的list里面的迭代器是双向的迭代器,根本满足不了我们的算法库里面的参数类型。
算法库里面的reverse,这个接口里面的参数是双向的迭代器,这个可以,下面的find的参数类型是单向的迭代器,这个我们的list也可以使用,因为我们的list里面就是双向的迭代器,双向迭代器拥有单项迭代器的功能,我们就可以使用它。但是不可以权限放大,双向迭代器使用随机迭代器的参数的函数,这是不行的。随机迭代器功能比双向的强大。
算法库里面的sort我们的list不能用,里面的是使用的快排的逻辑,会发生迭代器的相减,这个list的迭代器做不到。
但是我们的list里面的自己的sort真的就不错吗?
list里面的sort效率:
list里面的sort函数的效率比较低下;他的效率比vector使用库里面的sort效率要低上很多的。当数据比较多的时候,list里面的sort效率更低。
我们来看这个代码:我们的两个list,一个使用list里面的sort函数来进行排序,另外一个先把数据拷贝给vector,(vector的初始化方式可以是这种迭代器的区间进行初始化的),先把list里面的数据给到vector,让vector使用算法库里面的sort来进行排序,然后排完以后,list再调用assign函数,把迭代器区间的数据拷贝给到list,然后结束,,,,。。
就这么麻烦的方式,居然还比list调用内部的sort要快上不少。。。
我们继续来看下一个接口:
splice接口:
我们的这个接口表示的是粘接:
第一种是把一个list里面的数据粘接到新的list里面,第二个参数是要粘接的list的别名,第一个参数表示要粘接的位置,把list粘接到position位置的前面。
第二种是把list里面的i位置的数据粘接到新的的list里面。
第三种是把list里面的一段迭代器区间的数据粘接到新的list里面。
我们看上面的代码:
我们上面有两个list,我们把list2数据粘接到list1的前面,然后我们再把两个链表打印下;
我们的list2是没有了。
这个粘接,我们把链表2的数据粘接到链表1的时候,链表2里面就没有数据了。
假如我们想把list2里面的数据粘接到list1里面,但是不是开始位置的前面,我们想把她粘接到其他的位置前面,我们就看如图中的操作,我们把迭代器的位置往后面移动一点,+2,但是这时候就错了,因为我们的list的迭代器是双向的迭代器,他是不支持+/-的,随机迭代器才支持+/-。
这个一般的需求是什么呢?
我们看这个代码,假设我们现在想让一个链表的最后面的数据放到我们的最开始的位置,我们也可以使用这个splice接口。(我们的上面的end(),这个接口是我们的最后一个数据的下一个位置,也就是空)。