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

线性数据结构:数组 Array

一、前言

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

数组只是个名称,它可以描述一组操作,也可以命名这组操作。数组的数据操作,是通过 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 各个入参的作用是什么?

相关文章:

线性数据结构:数组 Array

一、前言数组是数据结构还是数据类型&#xff1f;数组只是个名称&#xff0c;它可以描述一组操作&#xff0c;也可以命名这组操作。数组的数据操作&#xff0c;是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组&#xff0c;而是说&#xff0c…...

大数据开发-Hive

1、hive简介 hive是基于Hadoop的一个数据仓库工具&#xff0c;用于分析数据的。可以将结构化数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能 注&#xff1a;hive-SQL or HQL or类SQL 和标准SQL还是有一点点区别的 本质是SQL转换为MapReduce程序 用途&#xff1…...

《程序员新声》-Tech Lead 如何带领团队

收听本期播客 谢谢收听程序员新声&#xff0c;这是一款来自思特沃克&#xff08;Thoughtworks&#xff09;的播客节目。在这里&#xff0c;我们不仅讨论软件和技术领域的现状和未来&#xff0c;更关注程序员的成长世界。如何学习&#xff0c;如何晋升&#xff0c;如何带领团队…...

每日算法面试题

🧝‍♂️算法题 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。 示例 1:输入:x = 2.00000, n = 10 输出:1024.00000示例 2:输入:x = 2.10000, n = 3 输出:9.26100示例 3:输入:x...

高质量前端之自动化测试

前端自动化测试&#xff1a;Testing Library 篇 引言 前端测试 静态测试 eslint、TypeScript 单元测试 jest、mocha 集成测试 enzyme、react-testing-library、mock 爬虫 前后端解耦 为什么要引入自动化测试 测试可以让开发者站在用户的角度考虑问题&#xff0c;通过测试的手…...

2023不伤人脉的全新商城分销,一劳永逸的消费分红

2023不伤人脉的全新商城分销&#xff0c;一劳永逸的消费分红 2023-02-24 11:52梦龙 2023不伤人脉的全新商城分销&#xff0c;一劳永逸的消费分红 如今是流量为王的时代&#xff0c;但是如何将流量转化为忠实客户是个难题。不再是单向的买卖关系&#xff0c;而是从对产品的关注…...

【代码随想录训练营】【Day21】第六章|二叉树|530.二叉搜索树的最小绝对差|501.二叉搜索树中的众数|236. 二叉树的最近公共祖先

二叉搜索树的最小绝对差 题目详细&#xff1a;LeetCode.530 这道题使我第一次了解到二叉树的双指针遍历法&#xff0c;详细可以先查看卡哥的讲解视频&#xff1a;《代码随想录 — 二叉搜索树中的众数》 利用二叉搜索树的特点&#xff1a; 中序遍历二叉搜索树得到一个有序序…...

leaflet 导出图片,打印图片(A4横版或竖版)

第093个 点击查看专栏目录 本示例的目的是介绍如何在vue+leaflet中打印图片导出图片。一个简单的leaflet插件示例,添加了一个图标来打印或导出地图。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共85行)安装插…...

Java面向对象:继承特性的学习

本文介绍了面向对象的继承特性: 什么是继承 继承的概念 Java中继承的语法 在继承下父类成员的访问 super和this关键字 父类和子类构造方法 在继承下类中出现初始化代码的执行顺序 父类成员的访问权限对子类的可见性 Java的继承关系 final关键字 认识继承和组合关系 继承特性的学…...

问答系统(QA)调研

引言 智能问答系统广泛用于回答人们以自然语言形式提出的问题&#xff0c;经典应用场景包括&#xff1a;智能语音交互、在线客服、知识获取、情感类聊天等。根据QA任务&#xff0c;可以将QA大致分为5大类&#xff0c;分别为&#xff1a; 文本问答&#xff08;text-based QA&am…...

商务租车的三大优势吸引企业以租代购

随着社会机经济的高速发展&#xff0c;租车模式的日益盛行&#xff0c;租车不仅仅是受个体户的青睐&#xff0c;而作为环保经济的出行方式也让越来越多的企业开始选择以租代买&#xff0c;据调查统计&#xff0c;最早开始商务租车的群体是外企。而近几年&#xff0c;国内的很多…...

蓝桥杯的比赛流程和必考点

蓝桥杯的比赛流程和必考点 距省赛仅1个多月&#xff01;蓝桥杯的比赛流程和必考点&#xff0c;你还不清楚&#xff1f; “巷子里的猫很自由&#xff0c;却没有归宿&#xff1b;围墙里的狗有归宿&#xff0c;终身都得低头。人生这道选择题&#xff0c;怎么选都会有遗憾。” 但不…...

【数据结构】红黑树

红黑树一、红黑树的概念二、红黑树的接口2.1 插入三、验证四、源码一、红黑树的概念 红黑树也是一个二叉搜索树&#xff0c;他是通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;最长路径长度不超过最短路径长度的 2 倍保持近似平衡。他在每个节点添加了一…...

从C++的角度理解C#的Event

由于技术背景是C起家的&#xff0c;所以对于C的概念很清楚&#xff0c;遇到C#的EVENT时候&#xff0c;总感觉这个概念比较抽象&#xff0c;不容易理解&#xff0c;但是当使用函数指针和回调函数来理解EVENT的时候&#xff0c;这个概念就清晰了。 首先对于EVENT来讲&#xff0c…...

商城进货记录交易-课后程序(JAVA基础案例教程-黑马程序员编著-第七章-课后作业)

【实验7-2】商城进货记录交易 【任务介绍】 1.任务描述 每个商城都需要进货&#xff0c;而这些进货记录整理起来很不方便&#xff0c;本案例要求编写一个商城进货记录交易的程序&#xff0c;使用字节流将商场的进货信息记录在本地的csv文件中。程序具体要求如下&#xff1a; …...

【正点原子FPGA连载】第十七章双核AMP实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十七章双核AMP…...

内存管理框架---页(一)

文章目录物理内存的模型非一致内存访问--NUMA一致内存访问模型--UMA内存管理架构页页框管理页描述符页描述符字段flags字段详解gfp_mask 标志获得页alloc_pages__get_free_pages获得填充为0的页释放页kmallocvmalloc参考资料你用心写的每一篇文章&#xff0c;可能会带别人和自己…...

华为OD机试真题Python实现【流水线】真题+解题思路+代码(20222023)

流水线 题目 一个工厂有m条流水线 来并行完成n个独立的作业 该工厂设置了一个调度系统 在安排作业时,总是优先执行处理时间最短的作业 现给定流水线个数m 需要完成的作业数n 每个作业的处理时间分别为 t1,t2...tn 请你编程计算处理完所有作业的耗时为多少 当n > m时 首先…...

「JVM 编译优化」Graal 编译器

文章目录1. 历史背景2. 构建编译调试环境3. JVMCI 编译器接口4. 代码中间表示5. 代码优化与生成1. 历史背景 Graal 编译器在 JDK 9 以 Jaotc 提前编译工具的形式首次加入到官方的 JDK 中&#xff0c;JDK 10 开始提供替换&#xff08;得益于 HotSpot 编译器接口&#xff0c;Jav…...

蓝牙标签操作指南

一、APP安装指南 1.APP权限问题 电子标签APP安装之后&#xff0c;会提示一些权限的申请&#xff0c;点击允许。否则某些会影响APP的正常运行。安装后&#xff0c;搜索不到蓝牙标签&#xff0c;可以关闭App&#xff0c;重新打开。 2.手机功能 运行APP时候&#xff0c;需要打开…...

嵌入式 Linux Shell编程

目录 1、shell脚本 2、执行shell脚本 3、shell脚本编写 3.1 shell变量 3.2 标准变量或环境变量 3.4 变量赋值有五种格式 3.5 运算符和表达式 关系运算符 布尔运算符 3.6 Test命令用法 1、判断表达式 2、判断字符串 3.判断整数 4、判断文件 3.7 数组 1、数组定义…...

Web前端学习:一

编辑器的基础使用 编辑器推荐使用&#xff1a; HBuilderx&#xff08;免费中文&#xff09;&#xff08;建议使用&#xff09; Sublime&#xff08;免费英文&#xff09; Sublime中文设置方法&#xff0c;下载语言插件&#xff1a; 1、进入Sublime后&#xff0c;ShiftCtrlP…...

SpringBoot集成Redis实现分布式会话

在单体应用的时代&#xff0c;Session 会话直接保存在服务器中&#xff0c;实现非常简单&#xff0c;但是随着微服务的流行&#xff0c;现代应用架构基本都是分布式架构&#xff0c;请求随机的分配到后端的多个应用中&#xff0c;此时session就需要共享&#xff0c;而存储在red…...

2023年关于身份安全的4 个预测

如果您身处技术领域&#xff0c;就会知道现在是时候盘点过去的一年&#xff0c;展望未来 365 天将影响业务、创新以及我们工作方式的因素的季节。这不是一门精确的科学&#xff0c;我们也不总是对的。但是推测很有趣&#xff0c;当我们看到其中一些趋势成为现实时会更有趣。本文…...

Linux期末考试应急

Linux期末考试应急 虚拟机添加硬盘、分区、格式化、挂载、卸载 fdisk -l#查看系统现有分区fdisk <指定磁盘>#指定磁盘分区sudo mkfs.ext3 <指定分区>#格式化磁盘###挂载磁盘1.新建一个目录sudo mkdir /mnt/test2.将指定分区挂载到对应目录sudo mount /dev/sdb10 /…...

mars3d对geojson图层分属性设置样式

开发中可能会遇到如下需求&#xff0c;在全省的数据中按某个属性⾼亮展示某市区。此时就需要使⽤分属性样式的api了。⽂档如下。GeoJsonLayer - Mars3D API文档属性是根据⽮量数据的属性进⾏匹配。可以通过 layer.graphics[0]?.attr ⽅式获取。 指导有哪些属性之后先设置…...

三、锁相关知识

文章目录锁的分类可重入锁、不可重入锁乐观锁、悲观锁公平锁、非公平锁互斥锁、共享锁深入synchronized类锁、对象锁synchronized的优化synchronized实现原理synchronized的锁升级重量锁底层ObjectMonitor深入ReentrantLockReentrantLock和synchronized的区别AQS概述加锁流程源…...

C语言数据类型

C 数据类型 在 C 语言中&#xff0c;数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间&#xff0c;以及如何解释存储的位模式。 C 中的类型可分为以下几种&#xff1a; 1 基本类型&#xff1a; 它们是算术类型&#xff0c;…...

华为OD机试真题Python实现【水仙花数】真题+解题思路+代码(20222023)

水仙花数 题目 所谓的水仙花数是指一个n位的正整数其各位数字的n次方的和等于该数本身, 例如153 = 1^3 + 5^3 + 3^3,153是一个三位数 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇总 输入 第一行输入一个整数N, 表示 N 位的正整数 N 在3…...

【华为OD机试模拟题】用 C++ 实现 - 非严格递增连续数字序列(2023.Q1)

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