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

news2024/11/16 7:41:49

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

空间占用

在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时可以在缓存中读取数据,从而速度更快。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP原生类总结利用

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

新的开始吧

项目答辩终于结束了&#xff1a; 学习规划 下面先对自己的目前的情况来说&#xff1a; 学长学姐让我先把vue和boot学完&#xff0c;所以我打算先把vue3和boot学一下&#xff0c;但是每天还要花一点时间在六级的听力和阅读上面&#xff0c;还有就是算法&#xff1b; 下面进行…

换根dp学习笔记

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

HarmonyOS 学习记录

时光荏苒,岁月如梭,韶华不负,未来可期。转眼间已经30岁了&#xff0c;学习的重要性不言而喻&#xff0c;在接下来的日子里记录下自己学习HarmonyOS的过程。增加一下知识储备&#xff0c;防患于未然嘛 不得不说华为的开发文档写的不错&#xff0c;开发工具直接安装后自动配置环境…

RLHF讲解

RLHF包含了两个至关重要的步骤&#xff1a; 训练Reward Model用Reward Model和SFT Model构造Reward Function&#xff0c;基于PPO算法来训练LLM frozen RMfrozen SFT ModelActor π Φ R L \pi_{\Phi}^{R L} πΦRL​ initialized from SFT ModelCritic V η V_\eta Vη​ i…

基于springboot实现结合疫情情况的婚恋系统【项目源码】

基于springboot实现结合疫情情况的婚恋系统演示 SpringBoot框架 SpringBoot是一个全新开源的轻量级框架。基于Spring4.0设计&#xff0c;其不仅继承了Spring框架原来有的优秀特性&#xff0c;而且还通过简化配置文件来进一步简化了Spring应用的整个搭建以及开发过程。另外在原…

头歌答案HTML——基础

目录 HTML——基础 第1关&#xff1a;初识HTML&#xff1a;简单的Hello World网页制作 任务描述 第2关&#xff1a;HTML结构&#xff1a;自我简介网页 任务描述 HTML——基本标签 第1关&#xff1a;创建第一个 HTML 标签 任务描述 第2关&#xff1a;创建 任务描述 …

【Liunx】服务器解决 跨域问题

首先打开后端的站点 在站点设置内打开 "配置文件" 然后在 “server_name 本机ip ”下方添加跨域配置,添加成功后重启nginx即可 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS, PUT, DELETE; add_header A…

使用Python分析时序数据集中的缺失数据

大家好&#xff0c;时间序列数据几乎每秒都会从多种来源收集&#xff0c;因此经常会出现一些数据质量问题&#xff0c;其中之一是缺失数据。 在序列数据的背景下&#xff0c;缺失信息可能由多种原因引起&#xff0c;包括采集系统的错误&#xff08;例如传感器故障&#xff09;…

ROS基础知识复习

【置顶】感谢参考&#xff1a;https://zhuanlan.zhihu.com/p/662074088 0.背景 工作一年多没有做 ROS 相关的开发了&#xff0c;最近找工作想做回这一块来&#xff0c;根据参考内容&#xff0c;抽时间给这边的基础知识敲一遍复习一下 1.环境检查 打开了之前的笔记本&#x…

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

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

git分支与tag标签的介绍与使用)

git分支与tag标签的介绍与使用 一.什么是分支与标签1.2.开发环境分层 二git分支介绍2.1分支操作2.2.IDEA中操作分支 三、Git标签的讲解3.1.GitBashHere操作标签3.2. IDEA中操作标签 一.什么是分支与标签 分支&#xff08;Branches&#xff09;&#xff1a; 功能开发&#xff…

html菜单的基本制作

前面写过一点网页菜单的博文&#xff1b;下面再复习一些技术要点&#xff1b; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.…

GetSimple CMS忘记密码

GetSimple CMS是一个超简单的 CMS&#xff0c;适合建立个人网站等只需要极少数页面的网站。在站上百科上&#xff0c;是这么说的&#xff1a; GetSimple是一款基于XML存储数据的开源内容管理系统&#xff0c;且易于安装和定制&#xff0c;无需MySQL支持。提供撤销保护和备份功能…

RK3399平台开发系列讲解(应用篇)文件属性 stat 函数

🚀返回专栏总目录 文章目录 一、struct stat 结构体二、st_mode 变量三、struct timespec 结构体沉淀、分享、成长,让自己和他人都能有所收获!😄 📢Linux 下可以使用 stat 命令查看文件的属性,其实这个命令内部就是通过调用 stat()函数来获取文件属性的,stat 函数是 …

详解Java:抽象类和接口

前言&#xff1a;在前文中我们学习认知到了多态的使用和相关知识&#xff0c;算是打开了Java世界的大门&#xff0c;而本次要分享的抽象类和接口则是我们在面向对象编程中最常用的编程结构之一 目录 一.抽象类 abstract 抽象类特性 二.接口 语法规则 接口使用 接口特…

[笔记]深入解析Windows操作系统《番外》windows关键进程解释

文章目录 前言一、Linux起源与发展二、什么是shell1.什么是Shell 总结 前言 一、Linux起源与发展 二、什么是shell 1.什么是Shell 总结 以上就是今天要讲的内容&#xff0c;本文仅仅简单介绍了linux命令行的使用。 参考&#xff1a; shells 概念 centOS7中的几个Ctrl组合…

原型模式 rust和java的实现

文章目录 原型模式介绍优点缺点使用场景 实现java 实现rust 实现 rust代码仓库 原型模式 原型模式&#xff08;Prototype Pattern&#xff09;是用于创建重复的对象&#xff0c;同时又能保证性能。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当…

Spring-ProxyFactory

ProxyFactory选择cglib或jdk动态代理原理 ProxyFactory在生成代理对象之前需要决定是使用JDK动态代理还是CGLIB技术&#xff1a; public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {Overridepublic AopProxy createAopProxy(AdvisedSupport co…

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

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