vector的操作和扩容

1、vector数据结构

    vector是一段连续的内存空间。start,finish,end_of_storage三个指针描述了空间状态,这三个是普通的指针。start到finish是已经使用的内存,里面有元素。finish到end_of_storage是未使用的内存,里面没有元素。

 

2、定义与其初始化(指定其空间大小和初始值

vector<int>res(m);  //其空间capacity大小为m,但是没有初始化其中的值,还没有元素 size=0
vector<int>res(m, 0); //其空间(capacity)大小为m, 所有的值都为0,所有的数据类型都为int类型 size=m 

还可以定义二维的vector

vector<vector<int>>res(m, vector<int>(n, 0));  //相当于二位数组,其大小为m*n,所有的值都为0

当然也可以不指定其大小,直接vector<int>res; 此时其size和capacity都为0。

3、push_back()与扩容

  • 在vector类中作用为在vector尾部加入一个数据;即vector的size属性加1,但此时还要判断 (size+1)与capacity的关系,如果(size+1)>capacity,则说明集合已经满了,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,再插入新增的元素;
  • 对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了 ;
  • 初始时刻vector的capacity为0,塞入第一个元素后capacity增加为1;
  • 不同的编译器实现的扩容方式不一样,VS2015中以1.5倍扩容,GCC以2倍扩容。

    问题为什么要成倍的扩容而不是一次增加一个固定大小的容量呢?为什么是以两倍的方式扩容呢??

   答:成倍扩展是为了保证常数时间的复杂度,以2倍方式扩容是为了防止内存的浪费,更好的实现对内存的利用。

分析:

    比较一下两种方式的效率

   以成倍方式增长  :

  1. 假定有 n 个元素,倍增因子为 m;
  2. 完成这 n 个元素往一个 vector 中的 push_back​操作,需要重新分配内存的次数大约为 logm(n);
  3. 第 i 次重新分配将会导致复制 m^(i) (也就是当前的vector.size() 大小)个旧空间中元素;
  4. n 次 push_back 操作所花费的时间复制度为O(n): 
    这里写图片描述
  5. m / (m - 1),这是一个常量,均摊分析的方法可知,vector 中 push_back 操作的时间复杂度为常量时间.​

     一次增加固定值大小 

  1. 假定有 n 个元素,每次增加k个;
  2. 第i次增加复制的数量为为:100i
  3. n 次 push_back 操作所花费的时间复杂度为O(n^2): 
    这里写图片描述
  4. 均摊下来每次push_back 操作的时间复杂度为O(n);

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

成倍扩容的知乎回答:

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值