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

文章目录

  • 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),因此在对单次操作的执行速度极其敏感的应用场合以上策略并不适用,其中缩容操作甚至可以完全不予考虑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024最新Nessus 免费安装 附详细安装教程

免责声明 请勿利用文章内的相关技术从事非法测试。由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任&#xff0c;请遵守网络安全法律。本次仅用于测试&#xff0c;请完成测试后24小时之…

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

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

用docker方式安装openGauss数据库的事项记录

文章目录 &#xff08;一&#xff09;背景&#xff08;二&#xff09;安装&#xff08;2.1&#xff09;安装docker&#xff08;2.2&#xff09;安装openGauss &#xff08;三&#xff09;运行&#xff08;3.1&#xff09;运行openGauss镜像&#xff08;3.2&#xff09;连接open…

区块链技术与应用学习笔记(5-7节)——北大肖臻课程

​ 目录 ​BTC实现 基于交易的账本模式&#xff1a; UTXO集合&#xff1a; 交易费用&#xff1a; BTC网络 1.应用层&#xff1a; 2.网络层&#xff1a; 3传播层&#xff1a; 什么是鲁棒&#xff1f; BTC挖矿&#xff1a; 出块奖励&#xff1a; 挖矿难度调整&#…

Centos安装/更新Docker

首先要配置好Centos 配置好静态IP 替换yum源为阿里云 Docker是什么&#xff1f; Docker 是一种开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后部署到任何流行的 Linux 机器上。是一种虚拟化的技术&#xff0c;可以把…

基于socket编程实现TCP和UDP的通信流程

socket编程的常用函数&#xff0c;可以参考以下这篇博客 socket编程-----常用socket编程函数https://blog.csdn.net/ZZZCY2003/article/details/138071210 关于TCP的三次挥手、四次挥手过程和UDP的报文分析可以参考以下两篇博客 计算机网络--运输层https://blog.csdn.net/ZZ…

深度学习-N维数组和访问元素

目录 N维数组访问元素 N维数组 N维数组是机器学习和神经网络的主要数据结构 访问元素 最后一个子区域中的::是跳的意思&#xff0c;这个区域说明的是从第一个元素&#xff08;即第一行第一列那个&#xff09;对行开始跳3下循环下去直到行结束、对列开始跳2下循环下去直到列…

如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题

&#x1f42f; 如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题 &#x1f43e; 文章目录 &#x1f42f; 如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题 &#x1f43e;摘要引言正文&#x1f4d8; 识别问题&#x1f4d9; 内存配置调整步骤1: 定位vmoptions文件步骤2: 修改…

C++初阶之入门

零、什么是C C是基于C语言而产生的&#xff0c;它既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的基于对象的程序设计&#xff0c;还可以进行面向对象的程序设计。 C缺点之一&#xff0c;是相对许多语言复杂&#xff0c;而且难学难精。许多人说学…

为什么g++编译后的cpp文件名字为a,out

文章目录 为什么g编译后的cpp文件名字为a,out能修改默认名变成cpp文件名吗关于作者 为什么g编译后的cpp文件名字为a,out 在使用g编译C源代码时&#xff0c;默认情况下生成的可执行文件名为 a.out。这是由于在Unix和类Unix系统上&#xff0c;编译器的默认行为是将生成的可执行文…

可视化+多人协同技术原理和案例分享

前言 hi&#xff0c;大家好&#xff0c;我是徐小夕&#xff0c;之前和大家分享了很多可视化低代码的技术实践&#xff0c;最近也做了一款非常有意思的文档搭建引擎——Nocode/Doc&#xff1a; 也做了一些分享&#xff1a; Nocode/Doc&#xff0c;可视化 零代码打造下一代文件编…

Unity读书系列《Unity3D游戏开发》——脚本(一)

文章目录 前言一、脚本模版及其拓展1、脚本模版2、拓展脚本模版 二、脚本的生命周期三、脚本的执行顺序四、脚本序列化1、序列化数据2、serializedObject3、监听部分元素修改事件 五、定时器与间隔定时器六、工作线程&#xff08;多线程&#xff09;总结 前言 脚本在Unity的重…

Rust HTTP 客户端:易于使用、功能强大 | 开源日报 No.228

seanmonstar/reqwest Stars: 8.9k License: Apache-2.0 reqwest 是一个易于使用且功能强大的 Rust HTTP 客户端。 异步和阻塞客户端支持普通数据、JSON、urlencoded 和 multipart 数据格式可定制的重定向策略支持 HTTP 代理和系统原生 TLS 或 rustls 的 HTTPSCookie 存储功能…

RoadBEV:鸟瞰图中的道路表面重建

1. 代码地址 GitHub - ztsrxh/RoadBEV: Codes for RoadBEV: road surface reconstruction in Birds Eye View 2. 摘要 本文介绍了RoadBEV&#xff1a;鸟瞰图中的道路表面重建。道路表面条件&#xff08;特别是几何形状&#xff09;极大地影响了自动驾驶汽车的驾驶性能。基于…

就业班 第三阶段(nginx) 2401--4.22 day1 nginx1 http+nginx初识+配置+虚拟主机

一、HTTP 介绍 HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据&#xff08;HTML 文件…

ubuntu安装Qv2ray2.7.0及配置

需要下载两个文件&#xff0c;一个是zip文件&#xff0c;一个是AppImage执行程序。 执行AppImage需要先下载fuse sudo apt install libfuse2然后为AppImage赋予执行权限 sudo chmod x ./Qv2ray-v2.7.0-linux-x64.AppImage执行,执行前可以解压zip文件 ./Qv2ray-refs.tags.v1…

操作系统(Operating System)知识点复习——第十一章 I/O管理与磁盘调度

目录 0.前言 1.I/O设备 2.I/O功能的组织 3.Operating System Design Issues 4.I/O缓冲 4.1 单缓冲Single Buffer 4.2 双缓冲Double Buffer 4.3 循环缓冲 5.磁盘调度Disk Scheduling 5.1 磁盘性能参数 5.2 磁盘调度策略 ①First-in&#xff0c;first-out(FIFO) ②Pr…

鸿蒙ArkUI实战开发-如何通过上下滑动实现亮度和音量调节

场景说明 在音视频应用中通常可以通过上下滑动来调节屏幕亮度和音量大小&#xff0c;本例即为大家介绍如何实现上述UI效果。 说明&#xff1a; 由于当前亮度和音量调节功能仅对系统应用开发&#xff0c;所以本例仅讲解UI效果的实现。 效果呈现 本例效果如下&#xff1a; 当在…

决策树分析及其在项目管理中的应用

决策树分析是一种分类学习方法&#xff0c;其主要用于解决分类和回归问题。在决策树中&#xff0c;每个内部节点表示一个属性上的测试&#xff0c;每个分支代表一个属性输出&#xff0c;而每个叶节点则代表类或类分布。通过从根节点到内部节点的路径&#xff0c;可以构建一系列…

Haystack

文章目录 关于 Haystack提供 NLP项目所有阶段的功能 Building blocks组件 Components管道 Pipelines代理 Agents 基本使用 - RAG 关于 Haystack 官网&#xff1a;https://haystack.deepset.ai官方文档&#xff1a;https://docs.haystack.deepset.ai/docs/intro教程&#xff1a…