声明:虽然本系列博客与具体的编程语言无关。但是本文作者对c++相对比较熟悉,其次是java,所以难免会有视角上的偏差。举例也大多是和这两门语言相关。
Vector的出现主要是为了解决数组的静态空间的问题。所谓静态空间指的是一旦配置就不能改变。当然如果你硬要重新配置也是可以的,自己重新申请一块空间,然后把数据搬过去。而vector是动态空间,它的内部机制会自行扩充空间以容纳新元素。 可以用水桶装水的例子来示意的感性认识一下。如图1所示,不断向水桶中装水,那么装满了之后怎么办呢。如果是数组的做法,那么就需要自己搬一个更大的桶,把水装进去。而如果是,vector的做法,那么桶就可以自己随着水的增多而变大哦。而且是水刚要满时,水桶就自动变大。C++ vector自动增大至两倍的容量。数组的做法与vector的做法分别如图2和图3。
图1 装水
图2 装水-array
图3 装水-vector
那么问题来了,怎么能实现这种容量自增长呢,或者能够从外部看上去是自增长呢?这时候就体现出面向对象的好处了我们可以构建一个类出来,这个类呢能够帮助我们监测对象的容量,容量不够的时候就自增容量至两倍。这是容易做到的。可以通过一个私有的变量size就可以做到,每次先添加一个元素就增加1。当size与当前的容量一样大的时候就扩容,并将数据拷贝到新的容器中,然后该释放旧空间就释放之类的。因为类的封装,我们看不到这些内容,从外部看上去就实现了这种自增长容量的容器了。但是其原理必定也需要新构造一个空间出来。
图4 vector
接来下介绍两个概念:size,capacity。Begin和end之间的大小就是size,也就是当前的使用容量,可以理解成当前的水位;而capacity是当前所申请的空间大小,可以理解为水桶的容量。那么当size==capacity的时候,就要capacity=capacity*2+1就可以了。当然实际操作起来并不是这么简单,不能把capacity*2+1就不管了,因为capacity也只是一个私有成员变量而已,咱们可不能自欺欺人。要做到实际创建这么大的空间就需要空间分配啊,元素的搬移啊,实操起来还是比较麻烦的。这部分内容可参考《STL源码剖析》4.2小节。另外一个问题是,如果我们不断放水,当水量小到一定程度是,是不是大桶就是一种资源的浪费了呢?对应到程序上来就是空间的浪费。这时候可以换个小桶。那么换多小的桶呢,一个自然的想法是1/2大小的,这样与自增的大小就对应起来了。实际上在某些输入情况下这是会产生性能问题的。比如在数据size 为1/2capacity时不断插入然后删除,那么就会不停的换大桶小桶。在C++ stl中,选用1/4大小。
小秘密:下一篇将讲解C++中的vector以及java中的vector与arrayList。
See you next time. Happy Coding!!!
我的GitHub
---------------------
作者:dnhua
来源:CSDN
原文:https://blog.csdn.net/dnhua/article/details/84797653
版权声明:本文为博主原创文章,转载请附上博文链接!