扩容特点:

  1)新增元素:vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素;

  2)对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了 ;

  3)初始时刻vector的capacity为0,插入第一个元素后capacity增加为1;

  4)不同的编译器实现的扩容方式不一样,VS2015中以1.5倍扩容,GCC以2倍扩容。

以成倍方式增长

  假定有 n 个元素,倍增因子为 m;

  

  完成这 n 个元素往一个 vector 中的 push_back​操作,需要重新分配内存的次数大约为 logm(n);

  第 i 次重新分配将会导致复制 m^(i) (也就是当前的vector.size() 大小)个旧空间中元素;

  n 次 push_back 操作所花费的时间复制度为O(n):

  m / (m - 1),这是一个常量,均摊分析的方法可知,vector 中 push_back 操作的时间复杂度为常量时间。

一次增加固定值大小

  假定有 n 个元素,每次增加k个;

  

  第i次增加复制的数量为为:100i

  n 次 push_back 操作所花费的时间复杂度为O(n^2):

  均摊下来每次push_back 操作的时间复杂度为O(n)。

  总结:对比可以发现采用采用成倍方式扩容,可以保证常数的时间复杂度,而增加指定大小的容量只能达到O(n)的时间复杂度,因此,使用成倍的方式扩容。

增长因子的选取:

  根据查阅的资料显示,考虑可能产生的堆空间浪费,成倍增长倍数不能太大,使用较为广泛的扩容方式有两种,以2二倍的方式扩容,或者以1.5倍的方式扩容。

  以2倍的方式扩容,导致下一次申请的内存必然大于之前分配内存的总和,导致之前分配的内存不能再被使用,所以最好倍增长因子设置为(1,2)之间。

  借用一张图来说明2倍与1.5倍的区别:

  

总结

  1)vector在push_back以成倍增长可以在均摊后达到O(1)的事件复杂度,相对于增长指定大小的O(n)时间复杂度更好。

  2)为了防止申请内存的浪费,现在使用较多的有2倍与1.5倍的增长方式,而1.5倍的增长方式可以更好的实现对内存的重复利用,因而更好。

C++ STL vector扩容原理分析的更多相关文章

  1. ArrayList扩容原理分析

    1:代码解读和分析 1.1:构造方法分析 1: public ArrayList(int initialCapacity) { ) { this.elementData = new Object[in ...

  2. ConcurrentHashMap原理分析(二)-扩容

    概述 在上一篇文章中介绍了ConcurrentHashMap的存储结构,以及put和get方法,那本篇文章就介绍一下其扩容原理.其实说到扩容,无非就是新建一个数组,然后把旧的数组中的数据拷贝到新的数组 ...

  3. c++ 从vector扩容看noexcept应用场景

    c++11提供了关键字noexcept,用来指明某个函数无法--或不打算--抛出异常: void foo() noexcept; // a function specified as will nev ...

  4. 「必知必会」最细致的 ArrayList 原理分析

      从今天开始也正式开 JDK 原理分析的坑了,其实写源码分析的目的不再是像以前一样搞懂原理,更重要的是看看他们编码风格更进一步体会到他们的设计思想.看源码前先自己实现一个再比对也许会有不一样的收获! ...

  5. STL vector用法介绍

    STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和f ...

  6. JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析 http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balaba ...

  7. 转载:solr MoreLikeThis的原理分析

    转载地址:http://blog.sina.com.cn/s/blog_5ddc071f0101muos.html 在solr中有两种方式实现MoreLikeThis:MoreLikeThisHand ...

  8. STL vector 用法介绍

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

  9. STL vector使用方法介绍

    介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

随机推荐

  1. JS 选择结构语句与循环结构语句

    笔记整理自:廖雪峰老师的JS教程 选择结构 与Java使用一致. 需要注意的 JavaScript把null.undefined.0.NaN和空字符串''视为false,其他值一概视为true. 循环 ...

  2. Ext原码学习之Ext-more.js

    // JavaScript Document Ext.apply(Ext,{ userAgent:navigator.userAgent.toLowerCase(), cache:{}, isSeed ...

  3. JAVA String介绍、常量池及String、StringBuilder和StringBuffer得区别. 以及8种基本类型的包装类和常量池得简单介绍

    一.概述 String是代表字符串的类,本身是一个最终类,使用final修饰,不能被继承. 二.定义方式   方式一:直接赋值法 String str1 = "hello"; 方式 ...

  4. redis(二)-----redis基本数据类型之字符串

    Redis的全称是REmote Dictionary Server,它主要提供了5种数据结构:字符串.哈希.列表.集合.有序集合,同时在字符串的基础之上演变 出了位图(Bitmaps)和HyperLo ...

  5. [LeetCode]1528. 重新排列字符串

    给你一个字符串 s 和一个 长度相同 的整数数组 indices . 请你重新排列字符串 s ,其中第 i 个字符需要移动到 indices[i] 指示的位置. 返回重新排列后的字符串. 示例 1: ...

  6. tomcat编码错乱问题

    问题场景:相同的代码,在同事电脑上可以正常运行,在我电脑上用项目跑代码的时候,密文没法解密,用main方法就可以,而且用同事代码打的war包在我本地也不行,初步排查,应该是本地环境的问题. 场景1:本 ...

  7. bi工具是什么,如何选择?

    ​商业智能使用的一套方法和技术根据解决方案的目的而广泛多样化.有些工具专注于数据准备方面,可能包括ETL(提取,转换,加载)层,以更好地组织和利用数据.有些工具专注于更广泛的企业使用,可能专注于数据混 ...

  8. 国内外主流5款doshboard软件比较和对比

    大数据行业随着互联网的蓬勃发展中也越来越被人们看好,但是从事大数据行业的数据分析师经常会谈到dashboard,很多人就会疑惑什么是dashboard,下面就来了解一下Doshboard的发展. da ...

  9. spyeye手机监控最新版分享下载不用碰对方手机,所有聊天内容,照片等都能看见

    spyeye间谍眼介绍的非常详细,不但可以监控用户收发短信和通话记录,还可远程开启手机听筒,监听手机周围声音,实时监控用户的通话,并且利用GPS功能监测到手机用户所在位置,给用户安全隐私造成极大的威胁 ...

  10. 【C++ 调试】增量链接 Incremental Linking

    概述: Incremental Linking翻译成中文就是"增量链接",是一个链接的参数选项,作用就是为了提高链接速度的.什么意思呢?不选用增量链接时,每次修改或新增代码后进行链 ...