【数据结构(邓俊辉)学习笔记】向量02——动态空间管理

news2024/11/27 0:22:57

文章目录

  • 1. 概述
  • 2. 静态空间管理缺点
  • 3. 动态空间管理
    • 3.1 扩容
      • 3.1.1 如何实现扩容
      • 3.1.2 扩容算法
      • 3.1.3 容量递增策略 VS 容量倍增策略
        • 3.1.3.1 容量倍增策略分摊分析
        • 3.1.3.2 容量递增策略分摊分析
        • 3.1.3.3 结果对比
    • 3.2缩容
      • 3.2.1 动态缩容算法实现
      • 3.2.2 动态缩容算法时间复杂度
  • 4. 总结

1. 概述

介绍动态空间管理策略

2. 静态空间管理缺点

静态空间管理的空间效率难以保证。
在这里插入图片描述
难题可归纳为:
如何才能保证向量的装填因子既不致于超过1,也不致于太接近于0?

3. 动态空间管理

3.1 扩容

3.1.1 如何实现扩容

另申请一个容量更大的数组,并将原数组中的成员集体搬迁至新的空间,释放原数组占用空间。
在这里插入图片描述

3.1.2 扩容算法

结论:新数组的容量总是取作原数组的两倍

template <typename T> void Vector<T>::expand() { //向量空间不足时扩容
   if ( _size < _capacity ) return; //尚未满员时,不必扩容
   if ( _capacity < DEFAULT_CAPACITY ) _capacity = DEFAULT_CAPACITY; //不低于最小容量
   T* oldElem = _elem;  _elem = new T[_capacity <<= 1]; //容量加倍
   for ( Rank i = 0; i < _size; i++ )
      _elem[i] = oldElem[i]; //复制原向量内容(T为基本类型,或已重载赋值操作符'=')
   /*DSA*/ //printf("\n_ELEM [%x]*%d/%d expanded and shift to [%x]*%d/%d\n", oldElem, _size, _capacity/2, _elem, _size, _capacity);
   delete [] oldElem; //释放原空间
}

为何采用容量加倍策略呢?其他策略是否可行?

3.1.3 容量递增策略 VS 容量倍增策略

分析方法:分摊分析 而不是平均分析,对这两种分析情况不清楚可以看复杂度分析

若采用平均分析,则很可能因为所做的概率分布假定与实际不符,而导致不准确的结论。比如若采用通常的均匀分布假设,认为扩容与不扩容事件的概率各半,则会得出该策略效率极低的错误结论。实际上,只要假定这两类事件出现的概率各为常数,就必然导致这种误判。而实际情况是,采用加倍扩容策略后,在其生命期内随着该数据结构的容量不断增加,扩容事件出现的概率将以几何级数的速度迅速趋近于零。对于此类算法和数据结构,唯有借助分摊分析,方能对其性能做出综合的客观评价。

分析要求:参与分摊的操作必须构成和来自一个真实可行的操作序列,而且该序列还必须足够地长。

以可扩充向量为例,可以考查对该结构的连续n次(查询、插入或删除等)操作,将所有操作中用于内部数组扩容的时间累计起来,然后除以n。只要n足够大,这一平均时间就是用于扩容处理的分摊时间成本。

考查最坏的情况,假设在此后需要连续地进行n次insert()操作。

3.1.3.1 容量倍增策略分摊分析

在这里插入图片描述
几何级数不熟悉的看算法分析
1+2 + 4 + … + 2 ∣ l o g 2 ( n − 1 ) ∣ 2^{|log_2(n-1)|} 2log2(n1) = O( 2 ∣ l o g 2 ( n − 1 ) ∣ 2^{|log_2(n-1)|} 2log2(n1)) = O(n)
扩容的均摊分析为O(1)。

3.1.3.2 容量递增策略分摊分析

在这里插入图片描述
对算术级数不熟悉的看算法分析

3.1.3.3 结果对比

在这里插入图片描述

3.2缩容

导致低效率的另一情况是,向量的实际规模可能远远小于内部数组的容量。

3.2.1 动态缩容算法实现

算法思想:

每次删除操作之后,一旦空间利用率已降至某一阈值以下,该算法随即申请一个容量减半的新数组,将原数组中的元素逐一搬迁至其中,最后将原数组所占空间交还操作系统。

这里以25%作为装填因子的下限,但在实际应用中,为避免出现频繁交替扩容和缩容的情况,可以选用更低的阈值,甚至取作0(相当于禁止缩容)。

template <typename T> void Vector<T>::shrink() { //装填因子过小时压缩向量所占空间
   if ( _capacity < DEFAULT_CAPACITY << 1 ) return; //不致收缩到DEFAULT_CAPACITY以下
   if ( _size << 2 > _capacity ) return; //以25%为界
   T* oldElem = _elem; _elem = new T[_capacity >>= 1]; //容量减半
   for ( Rank i = 0; i < _size; i++ ) _elem[i] = oldElem[i]; //复制原向量内容
   delete[] oldElem; //释放原空间
}

3.2.2 动态缩容算法时间复杂度

与expand()操作类似,尽管单次shrink()操作需要线性量级的时间,但其分摊复杂度亦为O(1)。

4. 总结

就单次扩容或缩容操作而言,所需时间的确会高达Ω(n),因此在对单次操作的执行速度极其敏感的应用场合以上策略并不适用,其中缩容操作甚至可以完全不予考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1625732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sui主网升级至V1.23.1版本

其他升级要点如下所示&#xff1a; #17126 协议&#xff1a;Deepbook的更改将被还原。 #16673 开发者可能会看到更多编译器诊断&#xff0c;因为选择的解析错误不再阻止编译&#xff0c;并且编译器的诊断会到达后续编译阶段&#xff0c;其中可能会生成额外的诊断。 #16966…

SQLite FTS5 扩展(三十)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite的知名用户(二十九) 下一篇:SQLite 的命令行 Shell(三十一&#xff09; 1. FTS5概述 FTS5 是一个 SQLite 虚拟表模块&#xff0c;它为数据库应用程序提供全文搜索功能。在最基本的形式中&#xff0c; 全文搜索引擎允许…

【LAMMPS学习】八、基础知识(4.5)TIP5P水模型

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

JVS物联网平台驱动网关管理:智能化与自动化的探索

驱动网关的管理 驱动网关是对驱动进程进行生命周期的管理&#xff0c;包括驱动进程的创建、启停、更新、结束等管理功能。 如下图所示&#xff1a; 驱动代理程序是驱动网关的管理程序&#xff0c;每个驱动网关对应于一个驱动代理程序&#xff0c;驱动代理程序初始版本是安装在…

Nginx解决跨域访问难题:轻松实现跨域资源共享!

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 跨域资源共享&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;是一种网络浏览器的安全功能&#xff0c;它限制了一个源&#xff08;域、协议和端口…

算法----BF算法KMP算法

请想象一个情景&#xff1a; 当你脑海中突然浮现出一个词&#xff0c;你该怎么去找到这个词的有关内容&#xff1f; 打开我们浏览器的搜索框&#xff0c;输入你想的这个词&#xff0c;然后点击Enter。浏览器就会自动搜索与该词匹配的内容。 这个过程实际上可以简化成以下形式…

常用的时间序列分析方法总结和代码示例

时间序列是最流行的数据类型之一。视频&#xff0c;图像&#xff0c;像素&#xff0c;信号&#xff0c;任何有时间成分的东西都可以转化为时间序列。 在本文中将在分析时间序列时使用的常见的处理方法。这些方法可以帮助你获得有关数据本身的见解&#xff0c;为建模做好准备并…

删除docker的容器与镜像

如果您想要卸载通过 docker pull influxdb 命令下载的 InfluxDB 容器&#xff0c;您需要执行以下步骤&#xff1a; 1. **停止正在运行的 InfluxDB 容器**&#xff1a; 首先&#xff0c;您需要停止任何正在运行的 InfluxDB 容器。您可以使用以下命令来查找正在运行的 InfluxD…

15 JavaScript学习:循环

JavaScript循环语句概念和分类 JavaScript中的循环语句用于重复执行特定的代码块&#xff0c;直到指定的条件不再满足。下面是JavaScript中常用的循环语句以及它们的概念和分类&#xff1a; for 循环&#xff1a;for循环通过指定起始条件、循环条件和递增/递减步长来进行迭代。…

C++程序在Windows平台上各种定位内存泄漏的方法

一、前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏&#xff0c;因为Linux在开发领域的使用场景大多是跑服务器&#xff0c;再加上它的开源属性&#xff0c;相对而言&#xff0c;处理问题容易形成“统一”的标准。而在Windows平台&#xff0c;服务器和客户端…

云计算时代:SFP、SFP+、SFP28、QSFP+和QSFP28光纤模块详解

随着数据中心的快速发展和云计算的广泛应用&#xff0c;高速、高效率的光纤网络传输成为关键需求。在众多光纤模块中&#xff0c;SFP、SFP、SFP28、QSFP和QSFP28是最常见的几种类型。本文将为您详细解析这几种光纤模块之间的区别&#xff0c;帮助您更好地了解和选择适合自己需求…

VS2019中配置C++ OpenCV 4.5.4完整指南

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…

C# 图像处理 添加水印

方法1&#xff0c;使用自带的画刷进行绘制水印 示例代码 public partial class Form1 : Form{public Form1(){InitializeComponent();}string photoPathstring.Empty;Bitmap image null;private void button1_Click(object sender, EventArgs e) //选择照片{OpenFileDialog d…

JavaWeb-自学JSP组件报告

自学JSP组件报告 一、组件资源及作用 1. commons-fileupload-1.2.2.jar 组件作用&#xff1a;用于处理HTTP文件上传请求&#xff0c;提供了文件上传的解析和存储功能。它允许开发者在Web应用中轻松实现文件上传功能。 2. commons-io-2.4.jar 组件作用&#xff1a;提供了一…

免单优选:电商销售新模式,低门槛高回报引领消费热潮

免单优选&#xff0c;一种颠覆传统的电商销售新模式&#xff0c;其核心在于通过价格优化策略、创新的奖励机制以及社交网络的深度应用&#xff0c;来激发消费者的购买欲望&#xff0c;进而推动销售实现快速增长。 一、坚守法律底线&#xff0c;打造透明奖励体系 免单优选模式坚…

POCEXP编写—POC编写实战

POC&EXP编写—POC编写实战 1. 概念引入2. POC编写2.1. GET与POST2.2. thinkcmf文件包含(Get请求)2.2.1. POC验证2.2.1.1. 漏洞存在复现 2.2.2. 编写POC2.2.2.1. 脚本报错2.2.2.2. 脚本美化2.2.2.3. 脚本测试2.2.2.4. 注意事项 2.3. Struts2 S2-061 远程命令执行漏洞(Get请求…

Hot 100总结【leetcode】

文章目录 哈希1. 1 两数之和2. 49 字母异或词分组3. 128 最长连续序列4. 283 移动零5. 11 盛最多水的容器6. 15 三数之和7. 42 接雨水 滑动窗口8. 3 无重复的最长子串9. 438 找到字符串中所有字母异位词子串10. 560 和为k的子数组11. 239 滑动窗口最大值12. 76 最小覆盖子串 普…

SpringBoot + kotlin 协程小记

前言&#xff1a; Kotlin 协程是基于 Coroutine 实现的&#xff0c;其设计目的是简化异步编程。协程提供了一种方式&#xff0c;可以在一个线程上写起来像是在多个线程中执行。 协程的基本概念&#xff1a; 协程是轻量级的&#xff0c;不会创建新的线程。 协程会挂起当前的协…

KT-0850 三箱社交箱

01简介 社交一般指社会交往。 社会交往 &#xff0c;简称“社交”&#xff08;socializing&#xff09;&#xff0c;是指在一定的历史条件下&#xff0c;个体之间相互往来&#xff0c;包括物质、精神交流的社会活动。三箱社交(Three-chamber Sociability)箱行为实验是一种经典…

【蓝桥2025备赛】容斥原理

容斥原理 背景&#xff1a;两个集合相交 高中的韦恩图&#xff0c;我们知道两个集合相交时我们可以通过简单的计算来认识相关的性质 集合相交的区域是 A ∩ B A\cap B A∩B ,集合的并集是 A ∪ B A\cup B A∪B ,那怎么用集合表示 A ∪ B A\cup B A∪B 我们可以看作是A集合…