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

【数据结构与算法】线性表--数组

文章目录

  • 一、前言
  • 二、数组的概念
  • 三、数组的操作
    • 数组的插入
    • 数组的删除
  • 四、容器与数组
  • 五、问题:为何数组要从0开始编号,而不是1开始呢?
  • 六、总结

一、前言

常见的数据结构如下图,本文主要讲解数据结构线性表--数组

在这里插入图片描述

二、数组的概念

定义:

数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。

从概念中可以知道一下几点:

  • 数组是线性表 
    所谓的线性表就是数据排成一排,想一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。当然除了数组,链表、队列、栈等也是线性表结构
    在这里插入图片描述
  • 连续的内存空间和形同类型的数据。
    正因为有了上述两个特点,数组才能够有一个堪称“杀手锏”的特性:随机访问
    数组实现下标随机访问
    下面通过一个实际的例子来说明:
    例如有一个长度为10的int数组,int[] a = new int[10].
    在这里插入图片描述
    计算机给数组a[10]分配了一块连续的内存空间1000~1039,其中,内存块的首地址为base_address = 1000.
    计算机会为每个内存单元分配一个地址,计算机通过地址来访问内存中的数据。当计算即需要随机访问数组中的某个元素的时候,它会首先通过下面的寻址公式,计算该元素存存储的内存地址:
              a[i]_address = base_address + i * data_type_size
    其中data_type_size表示数组中每个元素的大小。
    例如,数组中存储的int类型的数据,所以,data_type_size就是4字节。

三、数组的操作

通常我们都会说,“链表适合插入、删除。时间复杂度为O(1);数组适合查找,查找时间复杂度为O(1)”,其实该种说法是不对的,正确的应该是:数组支持随机访问,根据下标随机访问的时间复杂度为O(1)。

因为,数组是适合查找操作,但是查找的时间复杂度并不是O(1),即便是排好序的数组,使用二分查找,时间复杂度也是O(logn)

数组为了保持内存的数据的连续性,会导致插入、删除这两个操作比较低效。

数组的插入

分为三种情况:

  • 数组头插入
    当我们在数组的头部插入一个元素的时候,那么所有的元素都需要向后挪一位
    在这里插入图片描述
    该种情况下的最坏时间复杂度为O(n)。

  • 数组中间插入
    在该种情况下,如果要将某个元素插入到数组中的第k个位置,就必须按照上一种方式搬移k之后的数据。
    在这里插入图片描述
    该种情况下数据插入的最坏时间复杂度为O(n)。
    但是如果说,数组只是被用来当做一个存储集合,而不考虑数组中数据的顺序的话,为了避免大规模的数据搬移操作,有一个简单的办法,就是直接将第k个位置的数据搬移到数组的最后,然后将新元素直接放到第k个位置。例如:

在这里插入图片描述
 
该种处理技巧,在特定场景下,在第k个位置插入一个元素的时间复杂度会降为O(1)。

  • 数组尾部插入
    如果是在数组尾部插入元素的话,此时,就不需要移动数据

在这里插入图片描述

该种情况下,元素插入的时间复杂度为O(1)

数组的删除

其实数组的删除操作,跟插入操作类似,同样分为三种:

  • 删除头部元素
    该种情况下,因为也数组也需要保持内存空间的连续性,所以也需要搬移数据,最坏时间复杂度为O(n)
  • 删除中间位置元素
    这种情况下,其实跟删除头部元素类似,数组为了保持内存的连续性,也需要搬移数据,不然中间会出现空洞,内存就不连续了,最坏时间复杂度也为O(n)
  • 删除尾部元素
    如果说是删除末尾元素的话,此时数组其他的数据不需要进行移动,时间复杂度为O(1)

但是在某些特殊场景下,我们并不一定需要非得追求数组中数据的连续性。如果我们将多次删除操作集中在一起执行,删除的效率是不是会提高很多呢,比如说:

现在有个数组a[10]中存储了8个元素:a,b,c,d,e,f,g,h,现在要依次删除a,b,c三个元素

在这里插入图片描述
  
为了避免数据d,e,f,g,h这几个数据搬移三次,我们可以先记录下已经删除的数据。每次的删除操作并不是真正的搬移数据,只是记录数据已经被删除。当数组中没有更多的空间的时候,我们再触发一次真正的删除操作,这样就大大减少了删除操作导致的数据搬移。

这种形式貌似跟HBase的删除操作有点类似,在每次执行delete的时候,并不是真正的从region当中执行删除操作,而是先给要删除的记录打个标记,最后在合适的时间统一进行移除底层的hfile中的数据文件

同样,如果对jvm了解的话,会发现,这种情况也同JVM的标记清除垃圾回收算法的核心思想相类似。

四、容器与数组

大多数语言中提供了容器类,比如java中提供了ArrayList,但是具体与数组相比较,优势在哪里呢?

  • ArrayList
    ArrayList最大的优势就是可以将很多数组操作的细节封装起来.
    ArrayList支持动态扩容,每次存储空间不够的时候,会自动将空间扩容为原来的1.5倍大小。但是同样,动态扩容涉及到内存的申请和数据的搬移,也是比较耗时的。所以,如果实现能确定好需要存储的数据大小,最好在创建Arraylist的时候事先指定数据大小。
  • 数组
    数组本身在定义的时候需要预先指定大小,因为需要分配连续的内存空间。如果我们申请了大小为10的数组,当第11个数据需要存储到数组中时,我们就需要重新分配一块更大的空间,将原来的数据复制过去,然后再将新的数据插入。

五、问题:为何数组要从0开始编号,而不是1开始呢?

从数组的模型上来看的话,“下标"嘴确切的定义应该是"偏移(offset)”.也就是说,如果用a来表示数组的话,a[0]就表示偏移为0的位置,也就是首地址,a[k]就表示偏移为k个type_size的位置,所以计算a[k]的内存地址只需要使用下面的这个公式即可:

a[k]_address = base_address + k * type_size

如果是从1开始编号的话,那么计算数组元素a[k]的内存地址就成了:

a[k]_address = base_address + (k-1) * type_size

对于当中的参数的含义,base_address:数组的首地址,正如文章开头画的图表示的事1000,k表示的则是数组的下标,type_size则表示数组存储的数据的大小,如果存储的是一个int型的数据,那么就是4字节。

对比上面两个公式,并结合文章开头说话的图验证一下,可以发现,从1开始编号,每次随机访问数组元素都多了一次减法运算,对于CPU来说的话,那就是多了一次减法指令。

数组作为非常基础的数据结构,通过下标随机访问数组元素有事非常基础的编程操作,效率的优化就要尽可能的做大极致。所以为了减少一次减法操作,数组选择了从0开始编号,而不是从1开始编号。

六、总结

  1. Java ArrayList无法存储基本数据类型,比如int,Long,需要封装为Integer,Long类,而Autoboxing,Unboxing择优一定的性能消耗,所以如果特别关注性能,或者希望使用基本类型,既可以选用数组。

  2. 如果数据大小事先已知,并且对数据的操作非常简单,用不用到ArrayList提供的大部分方法,也可使用  数组。

  3. 当要表示多维数组时,用数组往往会更加直观。比如Object[][] array;而用容器的话则需要这样定义:ArrayList<ArrayList> array.

相关文章:

【数据结构与算法】线性表--数组

文章目录一、前言二、数组的概念三、数组的操作数组的插入数组的删除四、容器与数组五、问题&#xff1a;为何数组要从0开始编号&#xff0c;而不是1开始呢&#xff1f;六、总结一、前言 常见的数据结构如下图&#xff0c;本文主要讲解数据结构线性表--数组。 二、数组的概念 …...

剑指offer排序专题

剑指offer排序专题 jz3 数组中重复的数字描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的&#xff0c;但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如&#xff0c;如果输入长度为7的数组[…...

已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py

已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py 文章目录报错问题报错翻译报错原因解决方法1&#xff1a;easy_install 来安装pip解决方法2&#xff1a;本地安装pip《100天精通Python》专栏推荐白嫖80g Python全栈视频报错问题 粉丝群里面的一个小伙伴遇到问题…...

3 步走,快速上手 API 接口测试

开始 API 接口测试之前&#xff0c;我们需要弄清接口测试的含义&#xff1a; 接口测试就是根据接口清单&#xff0c;模拟客户端向服务端发送请求数据&#xff0c;并获取响应数据后&#xff0c;查看响应数据是否符合预期的过程。 整个过程可以分为三个步骤&#xff1a; 第一步&…...

爬虫-day1-正则表达式作业

利用正则表达式完成下面的操作: 一、不定项选择题 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括&#xff08;ABD &#xff09; A. r"\(?\d{3}\)?-?\d{8}" B. r"[0-9()-]" C. r"[0-9(-)]*\d*&…...

【半监督医学图像分割 2023 CVPR】RCPS

文章目录【半监督医学图像分割 2022 CVPR】RCPS摘要1. 介绍2. 相关工作2.1 医学图像分割2.1 半监督学习2.3 对比学习3. 方法3.1 整体概述3.2 纠正伪监督3.3 双向Voxel对比学习。4. 实验【半监督医学图像分割 2022 CVPR】RCPS 论文题目&#xff1a;RCPS: Rectified Contrastive …...

【UVM实战练习项目】2、UVM验证环境基本框架搭建(实例一)(纯软件环境,方便日后测试使用)

本节基于DUT完成UVM验证环境的基本框架搭建,实现对UVM理论知识点进行巩固练习,具体内容包括:如何创建激励、如何建立sequencer、如何连接sequencer和driver,如何集成agent、如何构建env等。 正式开始之前让我们再来回顾下搭建验证环境的过程:首先进行数据建模sequence_ite…...

【web前端初级课程】第四章 什么是JavaScript

目录 一、JavaScript在前端的三种写法 二、常见的弹框 三、变量 四、常量 五、数据类型 六、运算符 七、循环及函数 八、相关练习 前言 JavaScript是一个面向对象的&#xff0c;弱数据类型的&#xff0c;解释型的&#xff0c;动态脚本语言。 面向对象更符合我们对事物…...

数字中国建设进行时:吉林大学党委常务副书记冯正玉一行调研实在智能

两会前夕&#xff0c;中共中央、国务院印发了《数字中国建设整体布局规划》&#xff0c;明确了加快数字中国建设的重点任务。《规划》强调&#xff0c;要加强整体谋划、统筹推进&#xff0c;把各项任务落到实处。在强化人才支撑的第四要点上&#xff0c;指出统筹布局一批数字领…...

面试官灵魂拷问[二]:SQL 语句中 where 条件后写上 1=1 是什么意思?

面试官灵魂拷问系列又来更新啦! “SQL 语句中 where 条件后写上 11 是什么意思&#xff1f;” 这玩意就跟很多新语言支持尾部逗号的原理一样的。 比如 Kotlin 支持数组写成 [1, 2, 3, 4, ] &#xff0c;注意4后边那个逗号&#xff0c;为什么呢&#xff1f;因为当你增加一个项…...

进程与线程的关系

一、 进程 进程&#xff08;Process&#xff09;是程序的一次动态执行过程&#xff0c;它对应了从代码加载、执行至执行完毕的一个完成过程&#xff0c;这个过程也是进程本身从产生、发展至消亡的过程。 操作系统同时管理一个计算机系统中的多个进程&#xff0c;让计算机…...

自定义异常

自定义异常 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外&#xff0c;用户还可以自定义异常。用户自定义异常类&#xff0c;只需继承Exception类即可。在程序中使用自定义异常类&#xff0c;大体可分为以下几个步骤&#xff1a; 创建自定义异常类。在…...

基于springboot物资管理系统(程序+数据库)

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…...

蓝桥杯Web组备赛笔记6

目录 一、ElementUI 1、安装 2、简单使用 3、例子 4、其他内容的学习 二、echarts 1、简介 2、考点 3、安装 4、配置项&#xff1a;使用echarts的三步走 5、13届蓝桥真题&#xff08;3&#xff09;布局切换 6、数据格式处理&#xff1a;14届蓝桥模拟赛 1 期&#x…...

python控制语句

&#x1f34b;在本次的博客当中&#xff0c;我们来认识一下python语言的新的部分——python语言的控制语句。在我们的python语言当中控制语句大致分为三类&#xff1a;1.选择语句&#xff0c;2.循环语句&#xff0c;3.跳转语句。当我们在编写代码的时候可以根据代码的逻辑的需求…...

华为OD机试题【最小叶子节点】用 Java 解 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:最小叶子节点 题目 二叉树也可…...

【linux】多线程控制详述

文章目录一、进程控制1.1 POSIX线程库1.2 创建线程pthread_create1.2.1 创建一批线程1.3 终止线程pthread_exit1.4 线程等待pthread_jion1.4.1 线程的返回值&#xff08;退出码&#xff09;1.5 取消线程pthread_cancel1.6 C多线程1.7 分离线程pthread_detach二、线程ID值三、线…...

SpringCloud学习-实用篇01

以下内容的代码可见&#xff1a;SpringCloud_learn/day01 1.认识微服务 单体架构和分布式架构 体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 优点&#xff1a;架构简单&#xff0c;部署成本低缺点&#xff1a;耦合度高 分布式架构&#…...

如何使用python删除一个文件?好用到上头.....

人生苦短&#xff0c;我用python 若想利用python删除windows里的文件&#xff0c; 这里需要使用os模块 那接下来就看看利用os模块是如何删除文件的吧~ 具体实现方法如下&#xff01; 更多学习资料:点击此处跳转文末名片获取 os.remove(path) 删除文件 path. 如果path是一…...

java学习笔记——权限修饰符、内部类

2.1 概述 在java中提供了四种访问权限&#xff0c;使用不同的访问权限修饰符修饰时&#xff0c;被修饰的内容会有不同的访问权限&#xff0c; public&#xff1a;公共的 protected&#xff1a;受保护的 default&#xff1a;默认的 private&#xff1a;私有的 2.2 不同权限的…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...