1、当向vector push_back一个元素时,如果此时元素个数超过了vector的容量,会触发扩容
2、扩容的过程是:开辟新空间->拷贝旧空间的元素->释放旧空间
3、扩容过程中开辟新空间的大小影响着往vector插入元素的效率:
- 如果新空间大小为旧空间大小+1,也就是边插入边扩容,这样每一次插入都要进行拷贝,时间复杂度为O(n),效率非常低下
- 如果新空间大小为旧空间大小+k,那么push_back一个元素的平均时间复杂度还是为O(n)。计算如下:
- 如果新空间大小为旧空间大小的m倍,那么push_back一个元素的平均时间复杂度为O(1),效率得到大大提升。计算如下:
- 一般m取1.5或2。取1.5的时候每次扩容时可以重用之前释放的内存,而取2的时候扩容时不能重用之前释放的内存,解释如下:
- 为什么m不取3或4或者更大呢?因为如果倍数超过2倍(包含2倍)方式扩容会存在:①空间浪费可能会比较高,比如:扩容后申请了64个空间,但只存了33个元素,有接近一半的空间没有使用。②无法使用到前面已释放的内存。
4、总结
- vector在push_back以成倍增长可以在均摊后达到O(1)的事件复杂度,相对于增长指定大小的O(n)时间复杂度更好。
- 为了防止申请内存的浪费,现在使用较多的有2倍与1.5倍的增长方式,而1.5倍的增长方式可以更好的实现对内存的重复利用。
5、vector的size()、capacity()、resize()和reserve()
size返回vector中元素个数
capacity返回vector的容量(capacity>=size)
resize修改size大小,如果resize指定的大小n小于当前size,将多出来的元素删去;如果n大于size小于当前capacity,将会插入n-size个默认元素值;如果n大于capacity,会扩容使capacity=size=n
reserve修改capacity大小,如果指定大小n小于等于当前capacity,什么都不做;如果n大于capacity,将扩容到n
6、参考
面试题:C++vector的动态扩容,为何是1.5倍或者是2倍_vector扩容_森明帮大于黑虎帮的博客-CSDN博客
STL之vector扩容机制_萝卜说菜的博客-CSDN博客