数据结构(三)- 数据的基本操作—增删查

2023-11-15

数据结构(三)- 增删查



前言

数据最基本的操作—增删查。

一、代码对数据的处理

在上篇文章数据结构(二) - 时间复杂度与空间复杂度中出现的一个例子,在一个数组中找出出现次数最多的那个元素的数值。例如,输入数组 a = [1,2,3,4,5,5,6] 中,只有 5 出现了两次,其余都是 1 次。显然 5 出现的次数最多,则输出 5。为了降低时间复杂度,引入了 k-v 的字典的数据结构。那么问题来了,究竟是什么原因,促使我们想到了使用字典的数据结构呢?如果不使用字典,改为使用数组行不行呢?

为了回答这些问题,我们先看一下究竟此处代码需要对数据进行哪些操作。我们提到过,这段代码处理数据的核心思路是:

第一步,根据原始数组计算每个元素出现的次数;

第二步,根据第一步的结果,找到出现次数最多的元素。

首先,我们来分析第一步统计出现次数的处理。此时,你还不知道应该采用什么数据结构。

对于每一次的循环,你得到了输入数组中的某个元素 a[ i ] 。接着,你需要判断这个元素在未知的数据结构中是否出现过:

如果出现了,就需要对出现的次数加 1。

如果没有出现过,则把这个元素新增到未知数据结构中,并且把次数赋值为 1。
这里的数据操作包括以下 3 个。

查找: 看能否在数据结构中查找到这个元素,也就是判断元素是否出现过。

新增: 针对没有出现过的情况,新增这个元素。

改动: 针对出现过的情况,需要对这个元素出现的次数加 1。

接下来,我们一起分析第二步。访问数据结构中的每个元素,找到次数最多的元素。这里涉及的数据操作很简单,只有查找。

因此,这段代码需要高频使用查找的功能。此时,第一步的查找动作嵌套在 for 循环中,如果你的代码不能在 O(1) 的时间复杂度内完成,则代码整体的时间复杂度并没有下降。而能在 O(1) 的时间复杂度内完成查找动作的数据结构,只有字典类型。这样,外层 for 循环是 O(n) 的时间复杂度,内部嵌套的查找操作是 O(1) 的时间复杂度。整体计算下来,就仍然是 O(n) 的时间复杂度。字典的查找是通过键值对的匹配完成的,它可以在 O(1) 时间复杂度内,实现对数值条件查找。

现在,我们换个解决方案。假设采用两个数组,分别按照对应顺序记录元素及其对应的出现次数。数组对于元素的查找只能逐一访问,时间复杂度是 O(n)。也就是说,在 O(n) 复杂度的 for 循环中,又嵌套了 O(n) 复杂度的查找动作,所以时间复杂度是 O(n²)。因此,这里的数据结构,只能采用字典类型。

二、数据处理的基本操作

不管是数组还是字典,都需要额外开辟空间,对数据进行存储。而且数据存储的数量,与输入的数据量一致。因此,消耗的空间复杂度相同,都是 O(n)。由前面的分析可见,同样采用复杂的数据结构,消耗了 O(n) 的空间复杂度,其对时间复杂度降低的贡献有可能不一样。因此,我们必须要设计合理的数据结构,以达到降低时间损耗的目的。

而设计合理的数据结构,又要从问题本身出发,我们可以采用这样的思考顺序:

首先我们分析这段代码到底对数据先后进行了哪些操作。

然后再根据分析出来的数据操作,找到合理的数据结构。

这样我们就把数据处理的基本操作梳理了出来。今后,即使你遇到更复杂的问题,无非就是这些基本操作的叠加和组合。只要按照上述的逻辑进行思考,就可以轻松设计出合理的数据结构,

其实,代码对数据处理的操作类型非常少。代码对数据的处理就是代码对输入数据进行计算,得到结果并输出的过程。数据处理的操作就是找到需要处理的数据,计算结果,再把结果保存下来。这个过程总结为以下操作:

找到要处理的数据。这就是按照某些条件进行查找。

把结果存到一个新的内存空间中。这就是在现有数据上进行新增。

把结果存到一个已使用的内存空间中。这需要先删除内存空间中的已有数据,再新增新的数据。

经过对代码的拆解,你会发现即便是很复杂的代码,它对数据的处理也只有这 3 个基本操作,增、删、查。只要你围绕这 3 个数据处理的操作进行分析,就能得出解决问题的最优方案。常用的分析方法可以参考下面的 3 个步骤:

首先,这段代码对数据进行了哪些操作?

其次,这些操作中,哪个操作最影响效率,对时间复杂度的损耗最大?

最后,哪种数据结构最能帮助你提高数据操作的使用效率?

这 3 个步骤构成了设计合理数据结构的方法论。围绕第一步和第二步的数据处理的操作,我会再补充一些例子帮助你理解。而第三个方面就需要你拥有足够扎实的数据结构基础知识了,我会在后面的课程中详细讨论。

数据操作与数据结构的案例

我们先来看一个关于查找的例子。查找,就是从复杂的数据结构中,找到满足某个条件的元素。通常可从以下两个方面来对数据进行查找操作:

根据元素的位置或索引来查找。

根据元素的数值特征来查找。

针对上述两种情况,我们分别给出例子进行详细介绍。

例 1,我们来看第二个例子,对于一个数组,找到数组中的第二个元素并输出。

这个问题的处理很简单。由于数组本身具有索引 index ,因此直接通过索引就能查找到其第二个元素。别忘了,数组的索引值是从 0 开始的,因此第二个元素的索引值是 1 。不难发现,因为有了 index 的索引,所以我们就可以直接进行查找操作来,这里的时间复杂度为 O(1)。

例 2,我们来看第二个例子,如果是链表,如何找到这个链表中的第二个元素并输出呢?

链表和数组一样,都是 O(n) 空间复杂度的复杂数据结构。但其区别之一就是,数组有 index 的索引,而链表没有。链表是通过指针,让元素按某个自定义的顺序“手拉手”连接在一起的。

既然是这样,要查找其第二个元素,就必须要先知道第一个元素在哪里。以此类推,链表中某个位置的元素的查找,只能通过从前往后的顺序逐一去查找。不难发现,链表因为没有索引,只能“一个接一个”地按照位置条件查找,在这种情况下时间复杂度就是 O (n)。

例 3,我们再来看第三个例子,关于数值条件的查找。

我们要查找出,数据结构中数值等于 5 的元素是否存在。这次的查找,无论是数组还是链表都束手无策了。唯一的方法,也只有按照顺序一个接一个地去判断元素数值是否满足等于 5 的条件。很显然,这样的查找方法时间复杂度是 O(n)。那么有没有时间复杂度更低的方式呢?答案当然是:有。
我们遇到过要查找出数组中出现次数最多的元素的情况。我们采用的方法是,把数组转变为字典,以保存元素及其出现次数的 k-v 映射关系。而在每次的循环中,都需要对当前遍历的元素,去查找它是否在字典中出现过。这里就是很实际的按照元素数值查找的例子。如果借助字典的数据类型,这个例子的查找问题,就可以在 O(1) 的时间复杂度内完成了。

例 4,我们再来看第四个例子,关于复杂数据结构中新增数据,这里有两个可能.

第一个是在一个复杂数据结构的最后,新增一条数据。

第二个是在一个复杂数据结构的中间某个位置,新增一条数据。

这两个可能性的区别在于,新增了数据之后,是否会导致原有数据结构中数据的位置顺序改变。接下来,我们分别来举例说明。

在复杂数据结构中,新增一条数据。假设是在数据结构的最后新增数据。此时新增一条数据后,对原数据没有产生任何影响。因此,执行的步骤是:

首先,通过查找操作找到数据结构中最后一个数据的位置;

接着,在这个位置之后,通过新增操作,赋值或者插入一条新的数据即可。

如果是在数据结构中间的某个位置新增数据,则会对插入元素的位置之后的元素产生影响,导致数据的位置依次加 1 。例如,对于某个长度为 4 的数组,在第二个元素之后插入一个元素。则修改后的数组中,原来的第一、第二个元素的位置不发生变化,第三个元素是新插入的元素,第四、第五个元素则是原来的第三、第四个元素。

我们再来看看删除。在复杂数据结构中删除数据有两个可能:

第一个是在这个复杂数据结构的最后,删除一条数据。

第二个是在这个复杂数据结构的中间某个位置,删除一条数据。

这两个可能性的区别在于,删除了数据之后,是否会导致原有数据结构中数据的位置顺序改变。由于删除操作和新增操作高度类似,我们就不再举详细阐述了。

通过上述例子的学习之后,你就可以对它们进行组合,去玩转更复杂的数据操作了,我们再来看一个例子。

例 5,在某个复杂数据结构中,在第二个元素之后新增一条数据。随后再删除第 1 个满足数值大于 6 的元素。我们来试着分析这个任务的数据操作过程。这里有两个步骤的操作:

第一步,在第二个元素之后新增一条数据。这里包含了查找和新增两个操作,即查找第二个元素的位置,并在数据结构中间新增一条数据。

第二步,删除第 1 个满足数值大于 6 的元素。这里包含查找和删除两个操作,即查找出第 1 个数值大于 6 的元素的位置,并删除这个位置的元素。

因此,总共需要完成的操作包括,按照位置的查找、新增和按照数据数值的查找、删除。

总结

经过我们的分析,数据处理的基本操作只有 3 个,分别是增、删、查。其中,增和删又可以细分为在数据结构中间的增和删,以及在数据结构最后的增和删。区别就在于原数据的位置是否发生改变。查找又可以细分为按照位置条件的查找和按照数据数值特征的查找。几乎所有的数据处理,都是这些基本操作的组合和叠加。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构(三)- 数据的基本操作—增删查 的相关文章

  • git 使用总结

    1 本地安装git 略 2 创建github账号 略 3 本地配置 配置用户名和邮箱 git config global user name xiaobuisme git config global user email 81954469
  • Codemonkey 编码冒险课程

    转自 https blog csdn net mmh19891113 article details 80704745 Codemonkey 编码冒险课程 1 200 关卡 我们并没有按照他们官方的来划分关卡 官方是1 100 101 20
  • 在struts框架下实现文件的上传

    由于jspsmartupload上传文件 当前端页面没有file控件时 后端用jspsmartupload控件upload时将会走入一个死循环 现在采用struts自己提供的功能实现文件的上传 1 前端页面upload jsp

随机推荐

  • 使用Process Monitor工具监测进程对注册表和文件的操作

    使用Process Monitor工具监测进程对注册表和文件的操作 在C C 中编写代码实现 Process Monitor是一款功能强大的Windows系统工具 它可以用于监测和记录系统中的进程对注册表和文件的操作 通过使用Process
  • SQL注入攻击介绍

    SQL注入攻击介绍 一 SQL注入攻击简介 SQL注入攻击是指 后台数据库操作时 如果拼接外部参数到SQL语句中 就可能导致欺骗服务器执行恶意的SQL语句 造成数据泄露 删库 页面篡改等严重后果 按变量类型分为 数字型 字符型 按HTTP提
  • tomcat开启远程管理Manager

    启动tomcat 点击Manager App 403错误 根据提示 有两个地方需要修改 一个是开启允许远程访问 否则只能本机访问 另一个是打开manager gui 添加用户权限 1 开启远程访问 两种方式 a 打开若没有则新建 conf
  • Elasticsearch Java API四种实现方式

    0 题记 之前Elasticsearch的应用比较多 但大多集中在关系型 非关系型数据库与Elasticsearch之间的同步 以上内容完成了Elasticsearch所需要的基础数据量的供给 但想要在海量的数据中找到和自己相关的业务数据
  • 使用hbuilderx开发小程序项目遇到的问题

    因为在hbuilderx打开项目 文件结构与开发者工具中打开不一致 例如hbuilderx中只有一个 vue文件 开发者工具中则是四个文件wxml wxss js json分别对应结构 样式 代码逻辑 和组件页面配置 配置组件相关 在hbu
  • C++ 并行编程(thread)---多线程

    C 并行编程 多线程 1 并发与并行 2 进程和线程 2 1 常规解释 2 2 总结 2 3 具体理解 2 4 为什么使用多线程 2 5 进程和线程的区别 3 C 中的多线程 3 1 存储持续性 补充 4 从头文件
  • CSDN竞赛52期总结

    1 题目名称 投篮 小明投篮 罚球线投球可得一分 在三分线内投篮得分可以得到2分 在三分线以外的地方投篮得分可以得到3分 连续投 进得分累计 一旦有一个球没投进则得分清零 重新计算 现给出所有得分记录 清零不计入得分 请你计算一下小明 最多
  • gitlab仓库更换地址后pull、push无效,怎么办?轻松解决;

    你有没有遇到一个情况 公司说自己的git地址发生变化 你觉得没有什么 但是当下班时候 我们要提交代码了 发现push不了了 下边我们就解释一下这个事情 第一 原因 因为原来你的clone地址是老的地址 现在是新的地址 所以发生错误 第二 解
  • 服务器和操作系统怎么看,服务器和操作系统怎么看

    服务器和操作系统怎么看 内容精选 换一换 您需要提前准备好符合条件的镜像文件 并了解操作系统的已知问题 参见已知问题 表1中 文件系统 网络 驱动相关的配置需要在虚拟机内部完成 强烈建议您在原平台的虚拟机实施修改后 再导出镜像文件 当然 您
  • 淘宝联盟(淘客)/京东联盟(京东客)/拼多多(多多客)常用接口整理

    一 淘宝客常用接口整理 1 商品ID高佣转链API 描述 通过商品ID进行高佣链接 生成带优惠券的二合一最高佣金的链接 如该商品没有优惠券 则除了生成二合一链接外 还会生成该商品的淘客链接 同样为最高佣金 接口地址 http open 21
  • steam教育文化传承的必要性

    建构主义认为 学习者需要借助文化知识参与到一个群体当中去学习相关知识和技能 学习的过程离不开文化的参与 而知识的学习和技能的掌握依靠的也不仅仅是学习个体与外在环境之间的相互作用 还需要文化的参与 传统文化传承是文化因素 集体智慧在某一共同体
  • 7.19黄金连续砸盘上涨还会跌吗?空单被套怎么办?

    近期有哪些消息面影响黄金走势 今日黄金多空该如何研判 黄金消息面解析 周三 7月19日 亚市盘中 现货黄金高位震荡 目前交投于1976美元 盎司附近 因隔夜美gu大涨打压避险情绪 但金价仍守住了隔夜大部分涨幅 周二金价强势上涨近30美元 顶
  • Vue的简单使用

    第一个Vue程序 1 导入开发版本Vue js 2 使用简洁的模板语法把数据渲染到页面上 的作用是和下面的数据联系起来 div message div 3 创建Vue实例对象 设置el属性和data属性 var app new Vue el
  • java 验证码识别demo

    pom依赖坐标
  • 1222. 可以攻击国王的皇后

    文章目录 Tag 题目来源 题目解读 解题思路 方法一 从白国王出发 方法二 从黑皇后出发 写在最后 Tag 模拟 数组 题目来源 1222 可以攻击国王的皇后 题目解读 在一个 8 8 8 times 8 8 8 的棋盘上 有若干个
  • elasticsearch 简介和创建索引初步

    简介 ElasticSearch是一个开源的分布式搜索引擎 具备高可靠性 支持非常多的企业级搜索用例 像Solr4一样 是基于Lucene构建的 支持时间时间索引和全文检索 官网 http www elasticsearch org 它对外
  • lssvm实例

    clc clear close all 产生训练样本 xn train1 1 2 200 训练样本 每一列为一个样本 xn train2 1 1 100 dn train1 xn train1 2 xn train2 训练目标 行向量 dn
  • 2022产业区块链年度峰会暨FISCO BCOS五周年生态大会

    作为深圳国际金融科技节系列活动之一 由深圳市地方金融监督管理局指导 微众银行 金链盟主办的 2022产业区块链年度峰会暨FISCO BCOS五周年生态大会 将于2月24日下午 在深圳前海华侨城JW万豪酒店举行 此次大会以 数实相生 链筑可持
  • 垂直广告是什么意思_爆火的广告投放方式,抖音Feed流是什么?

    借势2020年的魔幻 短视频行业发展得如火如荼 年初的集体空闲 带动了各大短视频平台的发展 大量抖音创作者的涌入 也让出圈变得越来越难 为了更快出圈 有效利用流量 DOU 和Feed流应运而生 之前已经跟大家讲过DOU 投放的相关事宜 这期
  • 数据结构(三)- 数据的基本操作—增删查

    数据结构 三 增删查 文章目录 数据结构 三 增删查 前言 一 代码对数据的处理 二 数据处理的基本操作 总结 前言 数据最基本的操作 增删查 一 代码对数据的处理 在上篇文章数据结构 二 时间复杂度与空间复杂度中出现的一个例子 在一个数组