线性数据结构:数组 Array

news/2024/4/25 13:55:55/文章来源:https://blog.csdn.net/qq_63815371/article/details/129201325

一、前言

数组是数据结构还是数据类型?

数组只是个名称,它可以描述一组操作,也可以命名这组操作。数组的数据操作,是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组,而是说,通过连续的索引 idx,也可以线性访问相邻的数据。

那么当你定义了数据的存储方式,也就定义了数据结构。所以它也是被归类为数据结构。

二、数组数据结构

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

数组的特点:

  1. 数组是相同数据类型的元素集合(int 不能存放 double)

  1. 数组中各元素的存储是有先后顺序的,它们在内存中按照这个顺序连续存放到一起。内存地址连续。

  1. 数组获取元素的时间复杂度为O(1)

1. 一维数组

一维数组是最常用的数组,其他很多数据结构的变种也都是从一维数组来的。例如 HashMap 的拉链寻址结构,ThreadLocal 的开放寻址结构,都是从一维数组上实现的。

2. 二维数组

二维以及多维数组,在开发场景中使用到的到是不多,不过在一些算法逻辑,数学计算中到是可以使用。

三、实现数组列表

1. 基本设计

数组是一个固定的、连续的、线性的数据结构,那么想把它作为一个自动扩展容量的数组列表,则需要做一些扩展。

/*** 默认初始化空间*/
private static final int DEFAULT_CAPACITY = 10;
/*** 空元素*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/*** ArrayList 元素数组缓存区*/
transient Object[] elementData;
  1. 初始化 ArrayList 阶段,如果不指定大小,默认会初始化一个空的元素。这个时候是没有默认长度的。

  1. 那么什么时候给初始化的长度呢?是在首次添加元素的时候,因为所有的添加元素操作,也都是需要判断容量,以及是否扩容的。那么在 add 添加元素时统一完成这个事情,还是比较好处理的。

  1. 之后就是随着元素的添加,容量是会不足的。当容量不足的是,需要进行扩容操作。同时还得需要把旧数据迁移到新的数组上。所以数据的迁移算是一个比较耗时的操作

2. 添加元素

这是一份简化后的 ArrayList#add 操作

  1. 判断当前容量与初始化容量,使用 Math.max 函数取最大值最为最小初始化空间。

  1. 接下来是判断 minCapacity 和元素的数量,是否达到了扩容。首次创建 ArrayList 是一定会扩容的,也就是初始化 DEFAULT_CAPACITY = 10 的容量。

  1. Arrays.copyOf 实际上是创建一个新的空间数组,之后调用的 System.arraycopy 迁移到新创建的数组上。这样后续所有的扩容操作,也就都保持统一了。

  1. ArrayList 扩容完成后,就是使用 elementData[size++] = e; 添加元素操作了。

小贴士:若是不懂System.arraycopy可以看我的另一篇文章

https://blog.csdn.net/qq_63815371/article/details/129200269?spm=1001.2014.3001.5501

3. 移除元素

ArrayList 的重点离不开对 System.arraycopy 的使用,它是一个本地方法,可以让你从原数组的特定位置,迁移到新数组的指定位置和迁移数量。如图 2-5 所示,数据迁移 测试代码在 java-algorithms

删除元素

public E remove(int index) {E oldValue = (E) elementData[index];int numMoved = size - index - 1;if (numMoved > 0) {// 从原始数组的某个位置,拷贝到目标对象的某个位置开始后n个元素System.arraycopy(elementData, index + 1, elementData, index, numMoved);}elementData[--size] = null; // clear to let GC do its workreturn oldValue;
}
  • ArrayList 的元素删除,就是在确定出元素位置后,使用 System.arraycopy 拷贝数据方式移动数据,把需要删除的元素位置覆盖掉。

  • 此外它还会把已经删除的元素设置为 null 一方面让我们不会在读取到这个元素,另外一方面也是为了 GC

4. 获取元素

public E get(int index) {return (E) elementData[index];
}
@Override
public String toString() {return "ArrayList{" +"elementData=" + Arrays.toString(elementData) +", size=" + size +'}';
}

获取元素就比较简单了,直接从 elementData 使用索引直接获取即可。这个是一个 O(1) 操作。也正因为搜索元素的便捷性,才让 ArrayList 使用的那么广泛。同时为了兼容可以通过元素来获取数据,而不是直接通过下标,引出了 HashMap 使用哈希值计算下标的计算方式,也引出了斐波那契散列。它们的设计都是在尽可能减少元素碰撞的情况下,尽可能使用贴近 O(1) 的时间复杂度获取数据。

四、数组列表测试

@Test
public void test_array_list() {cn.bugstack.algorithms.data.array.List<String> list = new ArrayList<>();list.add("01");list.add("02");list.add("03");list.add("04");list.add("05");list.add("06");list.add("07");list.add("08");list.add("09");list.add("10");list.add("11");list.add("12");System.out.println(list);list.remove(9);System.out.println(list);
}

测试结果

ArrayList{elementData=[01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, null, null, null], size=12}
ArrayList{elementData=[01, 02, 03, 04, 05, 06, 07, 08, 09, 11, 12, null, null, null, null], size=11}Process finished with exit code 0
  • 测试案例中包括了在我们自己实现的 ArrayList 中顺序添加元素,逐步测试扩容迁移元素,以及删除元素后数据的迁移。

  • 最终的测试结果可以看到,一共有12个元素,其中idx=9的元素被删除前后,元素的迁移变化。

五、常见面试问题

  1. 数据结构中有哪些是线性表数据结构?

  1. 数组的元素删除和获取,时间复杂度是多少?

  1. ArrayList 中默认的初始化长度是多少?

  1. ArrayList 中扩容的范围是多大一次?

  1. ArrayList 是如何完成扩容的,System.arraycopy 各个入参的作用是什么?

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

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

相关文章

内网渗透(五十六)之域控安全和跨域攻击-非约束委派攻击

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

Linux下java服务占用cpu过高如何处理

Linux下java服务占用cpu过高如何处理 top命令查看进程信息 top按下shiftp,按cpu使用率排行,可见进程1932占用最高,并且是一个java服务 使用jps命令确认java服务 [rootVM-16-16-centos ~]# jps 1011 Jps 9462 yuan_back-0.0.1-SNAPSHOT.jar 1932 spigot-1.18.jar查找异常进程中…

利用关联来发现复杂攻击模式

日志是网络活动的重要依据&#xff0c;包含了关于您网络上所有用户和系统活动的详尽信息。基本日志分析可帮助您轻松地对数百万个日志进行分类&#xff0c;并挑选出可以表明存在可疑活动的日志&#xff0c;识别与正常网络活动不符的异常日志。通常&#xff0c;单独查看某个日志…

GCC:从源文件到可执行文件

GCC&#xff1a;从源文件到可执行文件 假设我们有hello.c 文件 #include <stdio.h> int main(){printf("hello world!\n");return 0; }怎么在linux上利用GCC命令生产可执行文件&#xff08;单文件编译&#xff09;呢&#xff1f; 一、流程 C文件从源文件到…

5.35 综合案例2.0 -称重数据上传云端

综合案例2.0 - 称重数据上传云端案例说明连线功能实现1.阿里云平台连接代码应用开发3.1新建‘普通项目’3.2关联产品和设备3.3新建‘移动应用’3.4添加组件3.5配置组件信息3.6保存预览案例说明 使用hx711串口模块称重,结合IOT studio制作手机APP远程控制并采集物体重量。 hx7…

称重传感器差分输入信号隔离转换直流放大变送器0-±10mV/0-±20mV转0-10V/4-20mA

主要特性DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输出…

Oracle——物化视图

文章目录含义物化视图的语法物化视图的创建1、自动刷新的物化事务 ON COMMIT2、非自动刷新的物化视图 ON demand关于手动刷新物化视图的删除资料参考含义 什么是物化视图&#xff1f; 物化视图&#xff0c;通俗点说就是物理化的视图。 什么叫物理化&#xff1f; 将视图以表结构…

可怕,chatGPT用3小时教会我数据分析

chatGPT这玩意真的是我的救星,用它作为我的Python教练,我用三个小时学会了数据处理(Pandas)和绘图(matplotlib)。 这两个库的学习,在之前已经困扰了我7个月。之前卡壳的原因,是我一直没有耐心从零开始,按照教材设置的教程去学习Python——我擅长在项目中学习,一点一点…

SpringMVC框架知识详解(入门版)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

「RISC-V Arch」SBI 规范解读(下)

第六章 定时器扩展&#xff08;EID #0x54494D45"TIME"&#xff09; 这个定时器扩展取代了遗留定时器扩展&#xff08;EID #0x00&#xff09;&#xff0c;并遵循 v0.2 中定义的调用规约。 6.1 函数&#xff1a;设置定时器&#xff08;FID #0&#xff09; struct sbi…

TensorFlow-Keras - FM、WideAndDeep、DeepFM、DeepFwFM、DeepFmFM 理论与实战

目录 一.引言 二.浅层模型概述 1.LR 2.FM 3.FMM 4.FwFM 5.FmFM 三.常用推荐算法实现 Pre.数据准备 1.FM 2.WideAndDeep 3.DeepFM 4.DeepFwFM 5.DeepFmFM 四.总结 1.函数测试 2.函数效果与复杂度对比[来自FmFM论文] 3.More 一.引言 推荐系统中常见的 CTR 模型…

梯度下降优化器:SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam -> AdamW

目录 1 前言 2 梯度概念 3 一般梯度下降法 4 BGD 5 SGD 6 MBGD 7 Momentum 8 SGDM&#xff08;SGD with momentum&#xff09; 9 NAG(Nesterov Accelerated Gradient) 10 AdaGrad 11 RMSProp 12 Adadelta 13 Adam 13 Nadam 14 AdamW 15 Lion&#xff08;EvoLve…

【C++进阶】一些小知识点

const限定符 用const给字面常量起个名字&#xff08;标识符&#xff09;&#xff0c;这个标识符就称为标识符常量&#xff1b;因为标识符常量的声明和使用形式很像变量&#xff0c;所以也称常变量。声明方式&#xff1a; const int a 77; const float PI 3.14159f&#xff…

算法设计与分析期末考试复习(二)

分治法 将一个难以直接解决的大问题&#xff0c;分割成一些规模较小的相同问题&#xff0c;以便各个击破&#xff0c;分而治之。最好使子问题的规模大致相同。 分解&#xff08;Divide&#xff09;&#xff1a;将一个难以直接解决的大问题&#xff0c;分割成一些规模较小的子…

【拿好了!Linux 运维必备的 13 款实用工具!】

​本文介绍几款 Linux 运维比较实用的工具&#xff0c;希望对 Linux 运维人员有所帮助。 查看进程占用带宽情况 – Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽。 下载&#xff1a; http://sourceforge.net/projects/nethogs/files/ne…

ZYNQ双核处理器独立运行AMP

一、简介多核处理器从多核的结构上是否一致&#xff0c;分为两种基本架构&#xff1a;同构多核架构和异构多核架构。同构多核处理器是指系统中的处理器在结构上是相同的&#xff1b;而异构处理器是指系统中的处理器在结构上是不同的&#xff0c;这些处理器可以是通用处理器&…

pyqt5通过CANoe COM Server来操作CANoe仿真工程

文章目录前言一、COM接口技术二、UI界面设计三、功能实现四、工程运行测试前言 继续学习《CANoe开发从入门到精通》。 今天在《CANoe仿真工程开发》的基础上&#xff0c;开发实现pyqt5应用程序来操控CANoe工程。 一、COM接口技术 COM&#xff08;Component Object Model&…

vue-cli引入wangEditor、Element,封装可上传附件的富文本编辑器组件(附源代码直接应用,菜单可调整)

关于Element安装引入&#xff0c;请参考我的另一篇文章&#xff1a;vue-cli引入Element Plus&#xff08;element-ui&#xff09;&#xff0c;修改主题变量&#xff0c;定义全局样式_shawxlee的博客-CSDN博客_chalk variables 1、安装wangeditor npm i wangeditor --savewangE…

【OpenFOAM】-olaFlow-算例10-wavemakerTank

算例路径&#xff1a; olaFlow\tutorials\wavemakerTank 算例描述&#xff1a; 采用 Flap和Piston两种方式的动网格进行造波 学习目标&#xff1a; 了解 olaDyMFlow 的使用&#xff1b;理解动网格使用和参数设置&#xff0c;理解 dynamicMotionSolverFvMesh 参数设置&#xff1…

【华为OD机试模拟题】用 C++ 实现 - 环中最长子串(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…