一、vector
vector数据结构 vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。因此能高效的进行随机存取,时间复杂度为o(1);但因为内存空间是连续的,所以在进行插入和删除操作时,会造成内存块的拷贝,时间复杂度为o(n)。
另外,当数组中内存空间不够时,会重新申请一块内存空间并进行内存拷贝。连续存储结构:vector是可以实现动态增长的对象数组,支持对数组高效率的访问和在数组尾端的删除和插入操作,在中间和头部删除和插入相对不易,需要挪动大量的数据。
vector有start、finish、end_of_storage
vector还有reserve函数,而list没有,因为list扩容机制不需要
它与数组最大的区别就是vector不需程序员自己去考虑容量问题,库里面本身已经实现了容量的动态增长,而数组需要程序员手动写入扩容函数进形扩容。
二、list
list数据结构 list是由双向链表实现的,因此内存空间是不连续的。只能通过指针访问数据,所以list的随机存取非常没有效率,时间复杂度为o(n);但由于链表的特点,能高效地进行插入和删除。非连续存储结构:list是一个双链表结构,支持对链表的双向遍历。每个节点包括三个信息:元素本身,指向前一个元素的节点(prev)和指向下一个元素的节点(next)。因此list可以高效率的对数据元素任意位置进行访问和插入删除等操作。由于涉及对额外指针的维护,所以开销比较大。
三、vector和list的区别
- vector的随机访问效率高,但在插入和删除时(不包括尾部)需要挪动数据,不易操作。
- list的访问要遍历整个链表,它的随机访问效率低。但对数据的插入和删除操作等都比较方便,改变指针的指向即可。
- 迭代器类型不一样,vector是随机存取,random,lists是bidirectional_iterator_tag
- 从遍历上来说,list是单向的,vector是双向的。
- vector中的迭代器在使用后就失效了,而list的迭代器在使用之后还可以继续使用。
- list会多一些函数,比如remove,unique,splice(是把迭代器所指的放在这个list的position前),merge,reverse,内部会有一个transfer函数,把一个链表接到另一个链表上
- list不能使用STL的sort,必须要创建自己的sort成员函数,不支持随机存取,list的sort函数使用快排,然后其调用的merge操作包含了归并排序。
- vector删除元素不释放空间,析构才释放。链表是删除会释放空间
四、deque与vector的区别
- list不再能够像vector一样以普通指针作为迭代器,因为其节点不保证在存储空间中连续存在;
- list插入操作和结合才做都不会造成原有的list迭代器失效;
- list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要一个指针;
- list不像vector那样有可能在空间不足时做重新配置、数据移动的操作,所以插入前的所有迭代器在插入操作之后都仍然有效;
- deque是一种双向开口的连续线性空间,所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作;可以在头尾两端分别做元素的插入和删除操作;
- deque和vector最大的差异,一在于deque允许常数时间内对起头端进行元素的插入或移除操作,二在于deque没有所谓容量概念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,deque没有所谓的空间保留功能。
- deque的start迭代器和finish迭代器并不是⼀开始就指向map数组的头尾,指向map的中间节点,为了使前后插⼊留有的空间相同;插⼊、删除操作为了提⾼效率,会判断元素偏前还是偏后,偏前移动前⾯的元素
五、vector、list、deque三者应用差别
三者的应用区别:
vector、list、deque适⽤场景?
▪ vector:需要随机存取,不关⼼插⼊删除
▪ list:需要插⼊删除,不关⼼随机存取(写多读少的场景)
▪ deque:需要随机存取、头尾的随机存取