数据结构基础之动态数组

news2024/11/25 18:34:01

目录

前言

1、Java中的数组

2、实现动态数组

2.1、基本类结构设计

2.2、添加元素

2.3、查询&修改元素

2.4、包含&搜索&删除

2.5、数组扩容


前言

今天我们来学习一下关于数据结构的一些基础知识,数据结构研究的是数据如何在计算机中进行组织和存储,使得我们可以更高效的获取数据或者修改数据,那么首先我们要说的就是数组。

1、Java中的数组

数组就是把数据放成一排进行存放

通过一段代码来回忆一下数组的具体使用吧:

数组最大的优点就是:快速查询(比如ages[2])。

思考:数组的大小在创建的时候就已经固定了,那么如果我们往数组里添加的元素个数超过了数组的最大容量时,该怎么办呢?

2、实现动态数组

基于上面的思考,我们就来基于Java为我们提供的数组,一步一步的实现一个动态数组,可以满足增删改查的需求,并且当元素个数超过数组容量时,可以自动扩容。

2.1、基本类结构设计

public class Array {
    private int[] data;
    private int size;

    /**
     * 构造函数,传入的是数组的容量
     *
     * @param capacity 容量
     */
    public Array(int capacity) {
        data = new int[capacity];
        size = 0;
    }

    // 无参构造,默认容量为10
    public Array() {
        this(10);
    }

    // 获取数组中的元素个数
    public int getSize() {
        return size;
    }

    // 获取数组的容量
    public int getCapacity() {
        return data.length;
    }

    //判断数组是否为空
    public boolean isEmpty() {
        return size == 0;
    }
}

2.2、添加元素

思想:向数组末尾添加元素

2.3、查询&修改元素

2.4、包含&搜索&删除

经过上面这些步骤,数组中的相关方法都已经添加好了,最后我们再把这个Array类修改为泛型类Array<Element>,让它可以添加各种数据类型的元素,这里我就不再一一修改了,后面会附上完整的代码。

接下来我们来简单测试一下我们的Array类是否可用:

执行结果如下:

2.5、数组扩容

对于扩容也很简单,就是当数组中的容量不够存储时,重新创建一个更大容量的数组,然后将原数组的数据一一更新到新数组中,当然,具体扩容成多少就由开发者自行决定了,下面来看代码:

然后我们来实际测试一下是否扩容成功:

从执行的结果中可以很明显的看出,我们的动态数组已经成功实现了扩容:

最后附上完整的Array.java类的源码吧:

public class Array<E> {
    private E[] data;
    private int size;

    /**
     * 构造函数,传入的是数组的容量
     *
     * @param capacity 容量
     */
    public Array(int capacity) {
        data = (E[]) new Object[capacity];
        size = 0;
    }

    // 无参构造,默认容量为10
    public Array() {
        this(10);
    }

    // 获取数组中的元素个数
    public int getSize() {
        return size;
    }

    // 获取数组的容量
    public int getCapacity() {
        return data.length;
    }

    //判断数组是否为空
    public boolean isEmpty() {
        return size == 0;
    }

    // 向所有元素后添加一个新元素
    public void addLast(E e) {
        add(size, e);
    }

    // 向所有元素前添加一个新元素
    public void addFirst(E e) {
        add(0, e);
    }

    // 向第index位置插入一个新元素
    public void add(int index, E e) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("数组下标异常");
        }
        if (size == data.length) {
            resize(2 * data.length);
        }
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = e;
        size++;
    }

    // 容量不够时进行扩容
    private void resize(int newCapacity) {
        E[] newdata = (E[]) new Object[newCapacity];
        for (int i = 0; i < size; i++) {
            newdata[i] = data[i];
        }
        data = newdata;
    }

    // 获取index索引位置的元素
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("数组下标异常");
        }
        return data[index];
    }

    //修改index索引位置的元素
    public void set(int index, E e) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("数组下标异常");
        }
        data[index] = e;
    }

    // 查找数组中是否有元素e
    public boolean contains(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e)) {
                return true;
            }
        }
        return false;
    }

    // 查找数组中元素e所在的索引,如果没有则返回-1
    public int findIndex(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e)) {
                return i;
            }
        }
        return -1;
    }

    // 从数组中删除index位置的元素,并且返回删除的元素
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("数组下标异常");
        }
        E ret = data[index];
        for (int i = index + 1; i < size; i++) {
            data[i - 1] = data[i];
        }
        size--;
        if (size == data.length / 4 && data.length / 2 != 0) {
            resize(data.length / 2);
        }
        return ret;
    }

    // 从数组中删除第一个元素
    public E removeFirst() {
        return remove(0);
    }

    // 从数组中删除最后一个元素
    public E removeLast() {
        return remove(size - 1);
    }

    // 从数组中删除元素e
    public void removeElement(E e) {
        int index = findIndex(e);
        if (index != -1) {
            remove(index);
        }
    }

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array:size=%d,capacity=%d\n", size, data.length))
                .append("[");
        for (int i = 0; i < size; i++) {
            res.append(data[i]);
            if (i != size - 1) {
                res.append(",");
            }
        }
        res.append("]");
        return res.toString();
    }
}

 OK,关于动态数组的相关内容就说这么多吧,下期再会!

祝:工作顺利!

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

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

相关文章

Java高级点的知识

Java 集合框架 该框架必须是高性能的。基本集合&#xff08;动态数组&#xff0c;链表&#xff0c;树&#xff0c;哈希表&#xff09;的实现也必须是高效的。 该框架允许不同类型的集合&#xff0c;以类似的方式工作&#xff0c;具有高度的互操作性。 对一个集合的扩展和适应…

WordPress 函数:add_theme_support() 开启主题自定义功能(全面)

add_theme_support() 用于在我们的当前使用的主题添加一些特殊的功能&#xff0c;函数一般写在主题的functions.php文件中&#xff0c;当然也可以再插件中使用钩子来调用该函数&#xff0c;如果是挂在钩子上&#xff0c;那他必须挂在after_setup_theme钩子上&#xff0c;因为 i…

Spring Security OAuth2四种授权模式总结 - Mysql存储客户端信息和令牌(八)

写在前面&#xff1a;各位看到此博客的小伙伴&#xff0c;如有不对的地方请及时通过私信我或者评论此博客的方式指出&#xff0c;以免误人子弟。多谢&#xff01;如果我的博客对你有帮助&#xff0c;欢迎进行评论✏️✏️、点赞&#x1f44d;&#x1f44d;、收藏⭐️⭐️&#…

Vue3 核心模块源码解析(上)

Vue3相比大家也都有所了解&#xff0c;即使暂时没有使用上&#xff0c;但肯定也学习过&#xff01;Vue3是使用TS进行重写&#xff0c;采用了MonoRepo的管理方式进行管理&#xff0c;本篇文章我们一起来看看 Vue3的使用&#xff0c;与Vue2有什么区别&#xff0c;以及我们该如何优…

【密码学】 一篇文章讲透数字证书

【密码学】 一篇文章讲透数字证书 数字证书介绍 数字证书是一种用于认证网络通信中参与者身份和加密通信的证书&#xff0c;人们可以在网上用它来识别对方的身份。 我们在上一篇博客中介绍了数字签名的作用和原理&#xff0c;数字签名可以防止消息被否认。有了公钥算法和数字签…

史上最全面的软件测试面试题总结(接口、自动化、性能全都有)

目录 思维发散 Linux 测试概念和模型 测试计划与工具 测试用例设计 Web项目 Python基础 算法 逻辑 接口测试 性能测试 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 思维发散 一个球&#xff…

二叉树——二叉搜索树的最小绝对差

二叉搜索树的最小绝对差 链接 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1a;1 示例 2&…

PowerDesigned16连接Oracle出现“Could not initialize JavaVM“时的解决步骤

PowerDesigned需要连接到数据库&#xff0c;我使用的是oracle&#xff0c;但总是连接不上&#xff0c;输出栏提示"Could not initialize JavaVM"。 经过查找资料&#xff0c;发现是PowerDesigned16是32位的&#xff0c;只能使用32位的JDK来运行JDBC驱动&#xff0c;…

如何从零开始系统的学习项目管理?

经常会有人问&#xff0c;项目管理到底应该学习一些什么&#xff1f;学习考证之后能得到什么价值&#xff1f; 以下我就总结一下内容 一&#xff0c;学习项目管理有用吗&#xff1f; 有效的项目管理带来的益处大致包括以下几个方面&#xff1a;更有效达成业务目标、满足相关…

人工智能轨道交通行业周刊-第35期(2023.2.20-2.26)

本期关键词&#xff1a;重庆智慧轨道、智能运维主机、标准轨距、地方铁路公报、景深、机器视觉应用 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通Rai…

第12天-商品维护(发布商品、商品管理、SPU管理)

1.发布商品流程 发布商品分为5个步骤&#xff1a; 基本信息规格参数销售属性SKU信息保存完成 2.发布商品-基本信息 2.1.会员等级-会员服务 2.1.1.会员服务-网关配置 在网关增加会员服务的路由配置 - id: member_routeuri: lb://gmall-memberpredicates:- Path/api/member/…

学习python第一天---前缀和

一、3956.截断数组&#xff08;前缀和&#xff09;二、前缀和&#xff08;前缀和&#xff09;[0]list(map(int,input().split()))三、子矩阵的和&#xff08;前缀和&#xff09;range(1,n1)四、K倍区间&#xff08;前缀和&#xff09;五、激光炸弹&#xff08;前缀和&#xff0…

模型部署笔记

目录模型部署工作ONNX存在的意义ONNX&#xff08;Open Neural Network Exchange&#xff09;ONNX示例模型推理示例Batch调整量化量化方式常见问题模型部署工作 训练好的模型在特定软硬件平台下推理针对硬件优化和加速的推理代码 训练设备平台&#xff1a; CPU、GPU、DSP ONN…

2023.02.26 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.模型4.1 SESSION-PARALLEL MINI-BATCHES4.2 SAMPLING ON THE OUTPUT4.3 RANKING LOSS5.实验5.1 数据集5.2 验证方式5.3 baselines5.4 实验结果6.结论深度学习元胞自动机1.定义2.构成3.特性4.思想5.统计特征流形学习1.降维2.空间3.距离…

一些硬件学习的注意事项与快捷方法

xilinx系列软件 系统适用版本 要安装在Ubuntu系统的话&#xff0c;要注意提前看好软件适用的版本&#xff0c;不要随便安好了Ubuntu系统又发现对应版本的xilinx软件不支持。 如下图&#xff0c;发行说明中会说明这个版本的软件所适配的系统版本。 下载 vivado vitis这些都可以…

IT男的一次中年破局尝试--出书

一、转战外企 接上回《人到中年——IT男择业感悟》后&#xff0c;自己从大央企去了某知名外企。外企虽然最近几年的日子已经没有10年前的辉煌与滋润&#xff0c;但相对来说&#xff0c;还能勉强找到工作与生活的平衡点。 划重点&#xff0c;35岁上下的人换工作理由&#xf…

SpringBoot+React博客论坛系统 附带详细运行指导视频

文章目录一、项目演示二、项目介绍三、项目运行截图四、主要代码一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootReact框架开发的博客论坛系统。首先&#xff0c;这是一个前后端分离的项目&#xff0c;文章编辑器…

大学物理期末大题专题训练总结-磁学大题

&#xff08;事先声明指的是简单的那个磁学大题&#xff0c;另外一类涉及储存的磁能、磁感应强度分布下次说&#xff09;求个磁通量&#xff0c;求个感应电动势&#xff0c;求个安培力大小......这个感觉是不是像你梦回高中&#xff1f;当然&#xff0c;这一块大题跟高中磁学部…

hadoop-Combiner合并、OutputFormat

一、Combiner合并 Combiner是MR程序中Mapper和Reducer之外的一种组件。 2&#xff09;Combiner组件的父类就是Reducer 3&#xff09;Combiner和Reducer的区别在与运行的位置&#xff1b;Combiner是在每一个MapTask所在的节点运行&#xff1b;Reducer是接收全局所有Mapper的输出…

c++11 标准模板(STL)(std::unordered_set)(九)

定义于头文件 <unordered_set>template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templat…