当前位置: 首页 > news >正文

数据结构:数组:插入操作(Insert)与删除操作(Delete)

目录

插入操作(Inserting in an Array)

在纸上模拟你会怎么做?

代码实现 

复杂度分析

删除操作(Deleting from an Array)

在纸上模拟一下怎么做?

代码实现

复杂度分析


插入操作(Inserting in an Array)

我们要讲的是:在一个数组中插入一个新元素,在任意合法的位置上,保持其他元素的顺序不乱。

给定一个数组:

A = [2, 4, 6, 8, 10]

现在你希望:在第 索引 2(也就是元素 6 之前)插入一个数字 99。

A = [2, 4, 99, 6, 8, 10]

在纸上模拟你会怎么做?

如果你用笔把这些数字排在格子里,加入一个空格,你会发现:

✅ 第一步:把从第2个位置开始的元素都向后移动一格,为99腾出位置。

[2][4][ ][6][8][10]↑插入位

你需要从右往左这样搬:

10 → [5] → [6]8 → [4] → [5]6 → [3] → [4]

✅ 第二步:然后把 99 放到空出的位置上(索引 2)

[2][4][99][6][8][10]

代码实现 

你在做的是 一个插入操作,其本质逻辑是:

📌 思路:

从最后一个元素开始,逐个后移,直到你腾出目标位置为止,然后放入新元素。

插入操作的本质:

  1. 从插入位置开始,所有后面的元素向后移动一格

  2. 把新元素插入目标位置

  3. 长度 + 1

 假设我们要在数组 A 中,插入 value 到索引 pos:

void insert(int A[], int& length, int pos, int value) {// 1. 从最后一个元素开始,向后搬运for (int i = length - 1; i >= pos; i--) {A[i + 1] = A[i];  // 向后挪一格}// 2. 把新值放进去A[pos] = value;// 3. 长度+1length++;
}

注意事项与边界处理

细节说明
插入位置是否合法?必须满足 0 ≤ pos ≤ length
数组是否已满?如果是静态数组,你必须预留空间
是否需要手动调整 length?是的,插入后 length+1
插入到尾部?就是 A[length] = value

复杂度分析

时间复杂度分析 

移动次数依赖于插入位置

插入位置 pos向后移动的元素个数最坏的移动数
最前面(pos = 0n 个元素需要后移✅ 最坏情况 O(n)
中间(pos = n/2n/2 个元素后移平均情况 O(n)
最末尾(pos = n0 个元素移动✅ 最好情况 O(1)
情况移动次数复杂度
最好情况(末尾插入)0 次移动O(1)
最坏情况(头部插入)n 次移动O(n)
平均情况≈ n/2 次移动O(n)

 ✅ 因此,插入操作的总体时间复杂度为:O(n)

空间复杂度分析

  • 如果你在原数组中操作(已有多余空间),空间复杂度是 O(1)(只需要一个临时变量)

  • 如果你在 动态扩容数组 中插入(如 std::vector),插入时如果超容量,可能要分配新内存,空间复杂度变为 O(n)(拷贝新数组)


删除操作(Deleting from an Array)

在一个数组中删除某个位置上的元素,并保持其他元素的顺序不变。

A = [2, 4, 6, 8, 10]

你希望从中删除索引为 2 的元素 6,目标是:

A = [2, 4, 8, 10]

在纸上模拟一下怎么做?

你可以把数组想象成一排格子,每个格子装着一个数:

[2][4][6][8][10]↑ 要删掉的元素

你不能真正“删掉”一个格子 —— 因为数组的长度是固定的

你只能“覆盖”它。

你可以从删除位置的下一个元素开始,把它们往前搬一格,覆盖前面的内容:

从后往前搬目标
A[3] = 8 → A[2]覆盖 6
A[4] = 10 → A[3]覆盖 8
[2][4][8][10][10]

(最后一个 10 是重复的,可以忽略,或者设置为0、垃圾值)

代码实现

删除操作的本质:

删除数组中某个位置的元素,需要从后往前逐个移动元素来“填空”,最后更新长度。 

删除过程:

  1. pos+1 开始,把所有元素向前搬一格

  2. 覆盖掉被删除的元素

  3. 更新数组长度

void deleteAt(int A[], int& length, int pos) {// 1. 从 pos+1 开始,向前搬一格for (int i = pos + 1; i < length; i++) {A[i - 1] = A[i];}// 2. 长度减 1length--;
}

边界与注意事项

检查项说明
删除位置是否有效?0 ≤ pos < length
是否需要更新数组长度?是的,必须减 1
是否要清空最后一个位置?通常不用,逻辑上长度变短即可

复杂度分析

时间复杂度

要移动多少个元素?需要花多少时间?

情况一:删除第一个元素(pos = 0

你需要移动全部 n−1 个元素(A[1] → A[0], A[2] → A[1], ..., A[n−1] → A[n−2])

所以:移动次数 = n - 1 → 最坏情况

时间复杂度:O(n) 

情况二:删除中间位置(pos = n/2

你需要移动一半的元素(从 pos+1 到 n−1)

 移动次数 ≈ n/2

时间复杂度仍是 O(n)(常数系数不影响阶) 

情况三:删除最后一个元素(pos = n - 1

你不需要移动任何元素,直接逻辑删除即可

移动次数 = 0

最好情况:O(1)

平均时间复杂度

如果删除位置是随机的,每个位置被删除的概率相同,那平均要移动:

结论:平均移动次数是 (n - 1)/2

🕒 平均时间复杂度也是 O(n)

空间复杂度

  • 你没有开辟任何新空间

  • 所有操作都是在原数组上完成

空间复杂度:O(1)(常数)

http://www.dtcms.com/a/267594.html

相关文章:

  • PageRank:互联网的马尔可夫链平衡态
  • 利用已有的 PostgreSQL 和 ZooKeeper 服务,启动dolphinscheduler-standalone-server3.1.9 镜像
  • Redis基础(6):SpringDataRedis
  • Java创建型模式---工厂模式
  • java多线程--死锁
  • CppCon 2018 学习:Standard Library Compatibility Guidelines (SD-8)
  • 未成功,做个记录,SelfHost.HttpSelfHostServer 如何加载证书
  • 【Prometheus】Grafana、Alertmanager集成
  • 小架构step系列05:Springboot三种运行模式
  • 理想汽车6月交付36279辆 第二季度共交付111074辆
  • 基于微信小程序的校园跑腿系统
  • MySQL——9、事务管理
  • Java-继承
  • 远程协助软件:Git的用法
  • STM32第15天串口中断接收
  • 数据结构:数组抽象数据类型(Array ADT)
  • oracle的内存架构学习
  • Hashcat 最快密码恢复工具实践指南
  • jvm架构原理剖析篇
  • C++ Qt 基础教程:信号与槽机制详解及 QPushButton 实战
  • virtualbox+vagrant私有网络宿主机无法ping通虚拟机问题请教
  • Apache 配置文件提权的实战思考
  • 数据库-元数据表
  • docker容器中Mysql数据库的备份与恢复
  • Java的AI新纪元:Embabel如何引领智能应用开发浪潮
  • 一文讲清楚React中setState的使用方法和机制
  • 应用标签思路参考
  • wsl查看磁盘文件并清理空间
  • Django跨域
  • 什么是单点登录SSO?有哪些常用的实现方式?