vector是一块连续分配的内存,从数据安排的角度来说,和数组极其类似。html
不一样的地方就是:node
(1) 数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;linux
(2) vector是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。面试
vector发现本身的空间不够了,因而申请新的内存空间(自增一倍),并将前面已有数据复制到新空间的前部。算法
自增一倍,主要是“位移”运算。数组
对于vector增长新元素的时候,有可能很快完成,也有可能要进行扩容,效率降低;dom
删除末尾元素效率很高,删除中间元素效率低;函数
deque是双端队列,在接口上和vector很是类似,在许多操做的地方能够直接替换。post
与vector不一样的是,deque不能保证全部的元素存储在连续的空间中,在deque中经过指针加偏移量方式访问元素可能会致使非法的操做。性能
Ref: C++ STL学习之三:容器deque深刻学习(转)
除了在频繁在头部或尾部进行插入和删除操做外,deque比list和forward_list的性能更差。
deque是一种优化了的对序列两端元素进行添加和删除操做的基本序列容器。
一般由一些独立的区块组成,第一区块朝某方向扩展,最后一个区块朝另外一方向扩展。
它容许较为快速地随机访问但它不像vector同样把全部对象保存在一个连续的内存块,而是多个连续的内存块。而且在一个映射结构中保存对这些块以及顺序的跟踪。
Ref: STL源码剖析---deque
deque采用一块所谓的map(注意,不是STL的map容器)做为主控。这里所谓map是一小块连续空间,其中每一个元素(此处称为一个节点,node)都是指针,指向另外一段(较大的)连续线性空间,称为缓冲区。缓冲区才是deque的储存空间主体。
SGI STL 容许咱们指定缓冲区大小,默认值0表示将使用512 bytes 缓冲区。
让咱们思考一下,deque的迭代器应该具有什么结构,首先,
为了可以正确跳跃,deque必须随时掌握管控中心(map)。因此在迭代器中须要定义:当前元素的指针,当前元素所在缓冲区的起始指针,当前元素所在缓冲区的尾指针,指向map中指向所在缓区地址的指针。
From: 深刻分析 Linux 内核链表
struct list_head { struct list_head *next, *prev; }; #define list_entry(ptr, type, member) container_of(ptr, type, member)
// container_of宏定义在[include/linux/kernel.h]中 #define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
// offsetof宏定义在[include/linux/stddef.h]中 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
Ref: [算法总结] 一文搞懂面试链表题
在 O(1) 时间删除链表节点 - 单向链表
作一次复制便可。
反转链表 O(n)
用三个临时指针 prev、cur、next 在链表上循环一遍便可。
旋转单链表,以及删除单链表倒数第 n 个节点
快指针结合慢指针,相同步幅走
求单链表的中间节点
快指针结合慢指针,不一样步幅走
链表划分,大于x的排后面;小于x的排前面
初始化两个链表leftList, rightList,遍历原链表。
在O(nlogn)时间内对链表进行排序
快排或者并归 --> Goto: 排序章节
合并两个排序的链表
同步指针法
删除链表中重复的结点
利用两个指针,相似冒泡排序
判断单链表是否存在环
快慢指针,慢指针每次移动一步,快指针每次移动两步,若是存在环,那么两个指针必定会在环内相遇。
找到环的入口点
咱们设置两个指针,一个是快指针fast,一个是慢指针slow,fast一次走两步,slow一次走一步,若是单链表有环那么当两个指针相遇时必定在环内。
此时将一个指针指到链表头部,另外一个不变,两者同时每次向前移一格,当两个指针再次相遇时即为环的入口节点。若是fast走到null则无环。
判断两个无环单链表是否相交
尾巴必然同样;或者用”有环“的思想去解题。
求两个无环单链表的第一个相交点
妙哉,四种方法四个角度:
判断两个有环单链表是否相交
若是两个有环单链表相交,那么它们必定共有一个环,即环上的任意一个节点都存在于两个链表上。
复杂链表的复制
题目描述:输入一个复杂链表(每一个节点中有节点值,以及两个指针,一个指向下一个节点,另外一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,不然判题程序会直接返回空)
第二个指针如何复制的问题?
奇偶复制。这样,random指针指向的结点天然知道”本身的copy"的位置。
std::array
is just a class version of the classic C array. That means its size is fixed at compile time and it will be allocated as a single chunk (e.g. taking space on the stack). The advantage it has is slightly better performance because there is no indirection between the object and the arrayed data.
forward_list 容器以单链表的形式存储元素。forward_list 的模板定义在头文件 forward_list 中。fdrward_list 和 list 最主要的区别是:它不能反向遍历元素;只能从头至尾遍历。
forward_list 的单向连接性也意味着它会有一些其余的特性:
forward_list 的操做比 list 容器还要快,并且占用的内存更少,尽管它在使用上有不少限制,但仅这一点也足以让咱们满意了。
End.