数据结构与算法【数组】Java实现

数组是一组元素组成的数据结构,元素类型必须相同,其次,数组内元素是连续存储的,因此数组中元素地址可以通过索引计算出来。

空间占用

在Java中,数组本质上也是一个对象,因此也存在对象头信息。那么数组的结构如下

  • 8字节的markword(用来记录对象的哈希值与经历GC回收的存活次数等信息)
  • 4字节的类指针(该部分存储了该数组的calss类型)
  • 4字节的数组大小(间接决定了数组最大能够容纳2的32次方个元素)
  • 数组元素加对齐字节(Java中所有对象大小都是8的整数倍,当存储的数组元素不是8的整数倍时,要使用对齐字节补齐)

时间复杂度

根据索引查找元素,时间复杂度是 O(1)

动态数组

静态数组在创建完毕之后,就无法更改容量大小,也不能插入和删除元素,因此,我们通常使用动态数组,而Java中也提供有默认的动态数组实现,也就是ArrayList。接下来我们自己来实现一个动态数组。

public class DynamicArray implements Iterable<Integer> {
    public DynamicArray() {
    }

    private int size = 0; //数组中元素数量
    private int capacity = 10; //数组中默认创建容量
    private int[] array = new int[capacity];

    //添加元素
    public void addList(int element) {
        checkAndGrow();
        array[size] = element;
        size++;
    }

    private void checkAndGrow() {
        //进行容量判断
        if (size == capacity) {
            //按一定比例扩容,这里扩容1.5倍
            capacity += capacity >> 1;
            //创建新数组
            int[] newArray = new int[capacity];
            System.arraycopy(array, 0, newArray, 0, capacity);
            //取代newArray
            array = newArray;
        }
    }

    //插入元素
    public void insert(int element, int index) {
        //首先进行容量判断
        if (size == capacity) {
            //进行数据扩容
        }
        //条件判断,插入的下标不能大于size
        if (index > size && index < 0) {
            return;
        }
        if (index == size) {
            addList(element);
        } else {
            //拷贝数组
            System.arraycopy(array, index, array, index + 1, size - index);
            array[index] = element;
            size++;
        }
    }

    //查询元素
    public int get(int index) {
        if (index < size && index < 0) {
            throw new RuntimeException("超出范围");
        }
        return array[index];
    }

    // 三种for循环
    public void foreach(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;

            @Override
            public boolean hasNext() {
                return i < size;
            }

            @Override
            public Integer next() {
                return array[i++];
            }
        };
    }

    public IntStream stream() {
        //将一个数组中有效值转化为流
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }

    //删除元素
    public int remove(int index) {
        int remove = array[index];
        if (index != size-1){
            System.arraycopy(array, index + 1, array, index, size - index - 1);
        }
        size--;
        return remove;
    }
}

动态数组的插入与删除元素的性能分析

  • 在数组头部与中间时,时间复杂度为O(n)
  • 在数组尾部时,时间复杂度为O(1)

二维数组

定义二维数组的语法如下

int[][] array = {

{11, 12, 13, 14, 15},

{21, 22, 23, 24, 25},

{31, 32, 33, 34, 35},

};

内存结构如下

需要注意的是,这里虽然存在对齐字节,但在内存上仍然是连续的。

对一个二维数组 Array[m][n]

  • m 是外层数组的长度,可以看作 row 行
  • n 是内层数组的长度,可以看作 column 列
  • 当访问 Array[i][j],0≤i≤m, 0≤j≤n时,就相当于
    • 先找到第 i 个内层数组(行)
    • 再找到此内层数组中第 j 个元素(列)

遍历二维数组时,先遍历row再遍历column效率比先遍历column再遍历row更高,原因在于CPU在读取内存中的数据时,一次性读取64字节放入缓存,而一个数组元素只有4字节,其余60字节会读取该数组元素的临近数据一起放入缓存,因此在遍历column时可以在缓存中读取数据,从而速度更快。

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

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

相关文章

04-详解SpringBoot自动装配的原理,依赖属性配置的实现,源码分析

自动装配原理 依赖属性配置 提供Bean用来封装配置文件中对应属性的值 Data public class Cat {private String name;private Integer age; }Data public class Mouse {private String name;private Integer age; }cartoon:cat:name: "图多盖洛"age: 5mouse:name: …

若依Linux与Docker集群部署

若依Linux集群部署 1. 若依2.MYSQL Linux环境安装2.1 MYSQL数据库部署和安装2.2 解压MYSQL安装包2.3 创建MYSQL⽤户和⽤户组2.4 修改MYSQL⽬录的归属⽤户2.5 准备MYSQL的配置⽂件2.6 正式开始安装MYSQL2.7 复制启动脚本到资源⽬录2.8 设置MYSQL系统服务并开启⾃启2.9 启动MYSQL…

XoT:一种新的大语言模型的提示技术

这是微软在11月最新发布的一篇论文&#xff0c;题为“Everything of Thoughts: Defying the Law of Penrose Triangle for Thought Generation”&#xff0c;介绍了一种名为XOT的提示技术&#xff0c;它增强了像GPT-3和GPT-4这样的大型语言模型(llm)解决复杂问题的潜力。 当前提…

PHP原生类总结利用

再SPL介绍 SPL就是Standard PHP Library的缩写。据手册显示&#xff0c;SPL是用于解决典型问题(standard problems)的一组接口与类的集合。打开手册&#xff0c;正如上面的定义一样&#xff0c;有许多封装好的类。因为是要解决典型问题&#xff0c;免不了有一些处理文…

kr 第三阶段(九)64 位逆向

X64 汇编程序 64 位与 32 位的区别 更大的内存 64 位 CPU 与 32 位 CPU 的区别 引脚根数&#xff1a; x86 程序&#xff1a;20 根x64 程序&#xff1a;52 根&#xff0c;实际寻址的有 48 根&#xff0c;所以最大内存是 0~256T 寻址区间&#xff1a; x86 程序&#xff1a;0x0…

python实现一个简单的桌面倒计时小程序

本章内容主要是利用python制作一个简单的桌面倒计时程序&#xff0c;包含开始、重置 、设置功能。 目录 一、效果演示 二、程序代码 一、效果演示 二、程序代码 #!/usr/bin/python # -*- coding: UTF-8 -*- """ author: Roc-xb """import tkin…

汽车ECU的虚拟化技术初探(二)

目录 1.概述 2.U2A虚拟化方案概述 3.U2A的虚拟化功能概述 4.虚拟化辅助功能的使能 5.留坑 1.概述 在汽车ECU的虚拟化技术初探(一)-CSDN博客里&#xff0c;我们聊到虚拟化技术比较关键的就是vECU的虚拟地址翻译问题&#xff0c;例如Cortex-A77就使用MMU来进行虚实地址的转换…

阿里云国际站:专有宿主机

文章目录 一、专有宿主机的概念 二、专有宿主机的优势 三、专有宿主机的应用场景 一、专有宿主机的概念 专有宿主机&#xff08;Dedicated Host&#xff0c;简称DDH&#xff09;是阿里云专为企业用户定制优化的解决方案。具有物理资源独享、部署更灵活、配置更丰富、性价比…

遇到问题,我该如何提问?

作为IT行业的从业者&#xff0c;我们深知程序员在保障系统安全、数据防护以及网络稳定方面所起到的重要作用。他们是现代社会的护城河&#xff0c;用代码构筑着我们的未来。那程序员的护城河又是什么呢&#xff1f;是技术能力的深度&#xff1f;是对创新的追求&#xff1f;还是…

Linux yum,vim详解

yum是什么 yum是一个Linux系统预装的指令&#xff0c;yum的功能是可以对app进行搜索&#xff0c;下载&#xff0c;相当于Linux下的应用商店。 yum是读取Linux中镜像文件中的网页地址&#xff0c;下载用户所输入的命令。 如何使用yum下载软件 yum install -y(所有选项都yes) …

换根dp学习笔记

最近模拟赛经常做到&#xff0c;于是我就学习了一下。 算法原理 换根 d p dp dp的题一般都会给出一个无根树&#xff0c;因为以不同的点为根时&#xff0c;问题的答案不一样&#xff0c;所以它会让你输出答案的最大或最小值。 暴力去做这种题&#xff0c;就是以每个点为根然…

为什么要用“交叉熵”做损失函数

大家好啊&#xff0c;我是董董灿。 今天看一个在深度学习中很枯燥但很重要的概念——交叉熵损失函数。 作为一种损失函数&#xff0c;它的重要作用便是可以将“预测值”和“真实值(标签)”进行对比&#xff0c;从而输出 loss 值&#xff0c;直到 loss 值收敛&#xff0c;可以…

springboot项目使用Swagger3

一、Swagger介绍 号称世界上最流行的Api框架&#xff1b;Restful Api 文档在线自动生成工具>Api文档与API定义同步更新直接运行&#xff0c;可以在在线测试API 接口支持多种语言&#xff1a;&#xff08;java&#xff0c;Php…&#xff09; 二、Swagger3 准备工作 1、在p…

学习c#的第七天

目录 C# 封装 概念 Public 访问修饰符 Private 访问修饰符 Protected 访问修饰符 Internal 访问修饰符 Protected Internal 访问修饰符 总结 C# 封装 概念 在面向对象程序设计中&#xff0c;封装是一种将数据和方法包含在一个单元中&#xff0c;并控制对这些数据和方…

海康Visionmaster-Qt+VS 二次开发环境如何配置?

1 新建 Qt 工程&#xff0c;添加 Qt 模块 Core、GUI、Active Qt 和 Container Widgets 2 拷贝 DLL:VM\VisionMaster4.0.0\Development\V4.0.0\ComControl\bin\x64 下的所有拷贝到项目工程输出目录下&#xff0c;如下图所示&#xff0c;项目的输出路径是 Dll 文件夹。 3 第一…

AOMedia发布免版税沉浸音频规范IAMF

11月10日&#xff0c;开放媒体联盟&#xff08;AOMedia&#xff09;发布了旗下首个沉浸式音频规范IAMF&#xff08;https://aomediacodec.github.io/iamf/&#xff09;&#xff0c;IAMF是一种编解码器无关的容器规范&#xff0c;可以携带回放时间渲染算法和音频混音的信息&…

Spring Data JPA 实现集成实体对象数据库的创建、修改时间字段自动更新

JPA提供了一种事件监听器的机制&#xff0c;用于SQL审计&#xff0c;通过监听器我们可以很快速地去自动更新创建时间、修改时间&#xff0c;主要步骤如下&#xff1a; 一、创建基础实体&#xff0c;包含了创建和修改时间&#xff0c;然后让其他真正的实体继承该实体&#xff0…

59基于matlab的爬行动物搜索算法(Reptile search algorithm, RSA)

基于matlab的爬行动物搜索算法&#xff08;Reptile search algorithm, RSA&#xff09;一种新型智能优化算法。该算法主要模拟鳄鱼的捕食行为&#xff0c;来实现寻优求解&#xff0c;具有收敛速度快&#xff0c;寻优能力强的特点。程序已调通&#xff0c;可直接运行。 59matlab…

3分钟带你了解前端缓存-HTTP缓存

前情提要 前端缓存分为下面三大类&#xff0c;本文主要讲解HTTP缓存~ 1. HTTP缓存 强缓存协商缓存 2. 浏览器缓存 本地小容量缓存本地大容量缓存 3. 应用程序缓存 HTML5应用程序缓存 缓存作用 减少了冗余的数据传输减少服务器的负担提高了网站的性能加快加载网页速度 …

JPA Buddy快速创建update、find、count、delete、exists方法

JPA Buddy快速创建update、find、count、delete、exists方法&#xff0c;JPA默认提供的CrudRepository\JpaRepository提供的方法比较少&#xff0c;一般我们会手写一些方法&#xff0c;这里我们选择通过JPA Buddy快速生成&#xff0c;之前文章中讲到了JPA Buddy原本是IDEA收费插…