C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

一、序列式容器vector、list、deque

vector 可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢
deque 双端队列。支持快速随机访问。在头尾插入/删除速度很快
list 双向链表。只支持双向顺序访问。在list中任何位置进行插入和删除的速度都很快
forward_list 单向链表。只支持单向顺序访问。在链表任何位置进行插入和删除操作速度都很快
array 固定大小数组。支持快速随机访问。不能添加或删除元素
string 与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入或删除速度快

vector

  • vector的底层实现:vector在底层使用一个数组实现的

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

  • 特点:
    • 因为vector使用数组实现的,因此元素是保存在连续的内存中的,所以通过索引取值的速度非常快
    • 因为是连续存储,所以在中间进行元素的增加或者删除非常耗时,可能伴随着移动元素以及内存重分配
    • 内存重分配之后,vector原来的指针、引用、迭代器都会失效,因为元素的地址改变了
  • 一般没有特殊要求时,都需要vector
  • 更多细节参阅vector源码剖析:https://blog.****.net/qq_41453285/article/details/103565158

list

  • list的底层实现:list在底层使用一个双向的环形链表实现的

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

  • 特点:
    • 因为list是使用链表实现的,所以在任意位置进行增加或者删除速度都比较快(指针的交换)
    • 另外,由于其不像vector一样拥有的连续的内存空间,不支持索引访问,所以查找的速度比较慢,因为需要遍历链表
    • 另外,它额外开销比较大,因为链表的节点需要存储指针
    • 无论是增加还是删除元素,其迭代器、指针、引用都不会失效,因为元素的地址没有改变
  • 当需要频繁的对元素进行增加或者删除时,list是比较好的选择
  • 更多细节参阅list源码剖析:https://blog.****.net/qq_41453285/article/details/103565158

deque

  • deque的底层实现:
    • deque在底层是由多个(多段)vector组成的
    • 如下图所示,右边的缓冲区就是deque实际存储数据的地方,每一个缓冲区都是一个数组;然后使用map(STL中称为中控器)来保存每一个数组的指针
    • 当我们操作deque时就是通过找到map指针,然后找到对应的缓冲区,然后对元素进行操作的

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

  • 特点:
    • deque支持在头部和尾部进行增删元素(如下图所示),所以在头部和尾部删除和增加元素的速度非常快
    • 因为其底层也是vector实现的,因此也支持索引取值
    • 对内存有限制的系统中,deque比vector可以包含更多元素,因为它不止使用一块内存
    • 存取元素的时候,deque的内部结构会多出一个间接过程,相比vector操作会慢一些
  • 当需要在两端频繁的对元素进行增加或者删除时,deque是比较好的选择

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

二、容器适配器stack、queue

  • stack和queue其实内部都是调用上面封装好的vector、list、deque等结构来实现的
  • stack和queue在内部调用vector、list、deque等它们提供好的方法来实现各种操作

stack

  • deque的底层实现:在内部默认以deque实现stack。因为deque是双向开口的数据结构,所以只要封闭其头端开口既可以形式一个stack

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

  • 特点:
    • stack是一种栈结构
    • stack允许新增元素、移除元素、取得最顶端元素。但除了最顶端外,没有任何其他方法可以存取stack的其他元素。换言之stack不允许有遍历行为
    • 将元素推入stack的动作称为push,将元素推出stack的动作称为pop
  •  
  • 更多细节参阅stack源码剖析:https://blog.****.net/qq_41453285/article/details/103631022

queue

  • queue的底层实现:在内部默认以deque实现queue。因为deque是双向开口的数据结构,所以只要封闭其底端的出口和前端的入口就可以形成一个queue​​​​​​​

C/C++面试:48---vector、list、deque、stack、queue的区别是什么?底层是如何实现的?

  • 特点:
    • queue是一种队列结构
    • queue允许新增元素、移除元素、从最底端加入元素、取得最顶端元素
    • 但除了最底端可以加入、最顶端可以取出外,没有任何其他方法可以存取queue的其他元素。换言之queue不允许有遍历行为
    • 将元素推入queue的动作称为push,将元素推出 queue的动作称为pop
  • 更多细节参阅queue源码剖析:https://blog.****.net/qq_41453285/article/details/103631323