vector的扩容机制—为何是1.5倍或者是2倍

2023-09-22 09:03:35


前言

在 C++ 编程中,Vector 是一种常用的动态数组容器。其大小是可以动态调整的,而在扩容操作中,Vector 通常会将容量增加为原来的两倍。本篇博客将详细介绍 Vector 扩容的原理、扩容过程,并解释为何选择两倍进行扩容。

一、Vector 扩容过程

当向vector中插入元素时,如果元素有效个数size与空间容量capacity相等时,vector内部会触发扩容机制
扩容的过程是:开辟新空间->拷贝旧空间的元素->释放旧空间

每次扩容新空间不能太大,也不能太小,太大容易造成空间浪费,太小则会导致频繁扩容而影响程序效。

二、为什么是1.5倍或者2倍?

如果新空间大小为旧空间大小+1,也就是边插入边扩容,这样每一次插入都要进行拷贝,时间复杂度为O(n),效率非常低下。

如果新空间大小为旧空间大小+k,其中k是一个固定的增量,那么在每次扩容时,新空间的大小会增加k个单位。假设原始空间大小为n,进行m次扩容后,新空间的大小为n + m*k。平摊下来每次插入的时间复杂度还是O(n),效率非常低下。
在这里插入图片描述
以倍数方式进行扩容
假设有n个元素需要像vector插入,倍增因子为m,则完成n个元素像vector的push_back操作需要扩容log以m为低n的次方。比如:以二倍方式扩容,当向vector插入1000个元素,需要扩容log以2为底1000次方,就是扩容10次,第i次增容会把m的i次方个元素搬移到新空间,n次push_back的总操作次数为:
在这里插入图片描述
一般m取1.5或2。取1.5的时候每次扩容时可以重用之前释放的内存,而取2的时候扩容时不能重用之前释放的内存,解释如下:
使用2倍(k=2)扩容机制扩容时,每次扩容后的新内存大小必定大于前面的总和。
而使用1.5倍(k=1.5)扩容时,在几次扩展以后,可以重用之前的内存空间了。
在这里插入图片描述

为什么m不取3或4或者更大呢?因为如果倍数超过2倍(包含2倍)方式扩容会存在:①空间浪费可能会比较高,比如:扩容后申请了64个空间,但只存了33个元素,有接近一半的空间没有使用。②无法使用到前面已释放的内存。

参考

更多推荐

软件定制APP开发步骤分析|小程序

软件定制APP开发步骤分析|小程序软件定制开发步骤:1.需求分析:这是软件定制开发的第一步,也是最关键的一步。在这个阶段,软件开发团队需要与客户进行沟通,了解客户的具体需求和期望。通过讨论和交流,确定软件的功能和特性,制定开发计划和时间表。2.设计阶段:在需求分析的基础上,软件开发团队需要进行软件的设计。这个阶段包括对

Ceph入门到精通-ceph pool 删除导致 misplaced 的原因

misplaced的原因Ceph中的misplaced对象是指将对象(或对象的副本)存储在错误的位置上,这可能会导致性能下降或数据不一致的问题。在删除Ceph池时,可能会导致misplaced的原因有以下几个:删除过程中的操作失误:在删除Ceph池时,操作人员可能会不小心删除了正在使用的池,导致对象被误删除或移动到错误

springboot和vue:四、web入门(静态资源访问+文件上传+拦截器)

静态资源访问使用IDEA创建SpringBoot项目,会默认创建出classpath:/static/目录,静态资源一般放在这个目录下即可。如果默认的静态资源过滤策略不能满足开发需求,也可以自定义静态资源过滤策略。在application.properties中定义过滤规则和静态资源位置。过滤规则为/static/**

ESP8266 WiFi物联网智能插座—项目简介

目录1、项目背景2、设备节点功能3、上位机功能物联网虽然能够使家居设备和系统实现自动化、智能化管理,但是依然需要依靠更为先进的终端插座作为根本保障,插座是所有家用电器需要使用的电源设备,插座的有序智能管理,对于实现智能家居设备的统一智能管理具有举足轻重的作用。无论是家庭生活,还是工业制造,插座在生活中的应用无所不在,当

GPIO子系统编写LED灯的驱动、linux内核定时器

一、GPIO子系统1.概念:一个芯片厂商生产出芯片后会给linux提供一个当前芯片中gpio外设的驱动,我们当前只需要调用对应的厂商驱动即可完成硬件的控制。而linux内核源码中的gpio厂商驱动有很多,这里linux内核对厂商驱动做了一些封装,提供了一系列的API,我们在自己编写的设备驱动中只需要调用这些API即可访

AI定义汽车,长城画了个看得见的“饼”

何小鹏提出的“AI定义汽车”概念,正在被业界关注并重视,这其中,就包括长城汽车。9月12日,在一场媒体交流会上,长城汽车透露,其内部已经成立了一个AILab部门,主要的工作,就是为整个长城提供包括产品、技术以及企业产品开发在内的人工智能大模型技术底座。据了解,该部门的技术负责人,是原沙龙品牌智能化技术中心负责人杨继峰。

MySQL 学习笔记(基础)

首先解释数据库DataBase(DB):即存储数据的仓库,数据经过有组织的存储数据库管理系统DataBaseManagementSystem(DBMS):管理数据库的软件SQL(StructuredQueryLanguage):结构化查询语言/操作关系型数据库的编程语言/定义操作所以关系型数据库的统一标准关系型数据库下

2716. 最小化字符串长度

2716.最小化字符串长度给你一个下标从0开始的字符串s,重复执行下述操作任意次:在字符串中选出一个下标i,并使c为字符串下标i处的字符。并在i左侧(如果有)和右侧(如果有)各删除一个距离i最近的字符c。请你通过执行上述操作任意次,使s的长度最小化。返回一个表示最小化字符串的长度的整数。示例1:输入:s=“aaabc”

BD就业复习第五天

1.核心组件的优化:hive、spark、flink针对Hive、Spark和Flink这三个核心组件,以下是它们的优化和一些常见面试题以及详细的回答:1.Hive优化面试问题1:什么是Hive?为什么需要对Hive进行优化?回答:Hive是一个数据仓库工具,它建立在Hadoop之上,用于分析和查询大规模数据。Hive

绘图系统五:数据产生

文章目录AxisFrame组件源码模式序列化导入数据获取文件信息导入文本导入二进制数据📈一三维绘图系统📈二多图绘制系统📈三坐标轴定制📈四定制绘图风格源码地址Python打造动态绘图系统AxisFrame组件AxisFrame是存放某一维坐标的组件,目前由一个标签,一个下拉选框和一个输入框构成。下拉选框主要目的是

Conditional DETR(ICCV 21)

ConditionalDETR(ICCV21)ConditionalDETRforFastTrainingConvergence加速detr收敛(50epoch收敛)DETR收敛慢的原因DETR训练收敛速度慢,需要500epochsDETR的CrossAttention高度依赖contentembedding(deco

热文推荐