数据结构与算法--顺序表(Java)

news2024/11/13 21:42:59

📝个人主页🌹:誓则盟约
⏩收录专栏⏪:Java SE
🤡往期回顾🤡:Java SE--基本数据类型(详细讲解)
🌹🌹期待您的关注 🌹🌹

什么是顺序表?

  • 顺序表是一种线性表的数据结构。
  • 顺序表是用一组地址连续的存储单元依次存储线性表中的数据元素。

顺序表的主要特点:

  1. 逻辑上相邻的元素在物理位置上也相邻。
  2. 可以随机访问表中的任意元素,通过元素的位置序号可以在 O(1) 的时间复杂度内直接获取对应元素。
  3. 插入和删除操作的效率相对较低。例如,在顺序表的中间位置插入一个元素,需要移动大量后续元素,时间复杂度为 O(n) ;删除操作同理。

顺序表的优点:

  1. 随机访问速度快,能够快速获取指定位置的元素。
  2. 存储密度高,不需要额外的指针来链接元素。

顺序表的缺点:

  1. 长度固定,不易扩展。
  2. 插入和删除操作可能涉及大量元素的移动,效率较低。

        举个例子,如果有一个顺序表存储了学生的成绩 [85, 90, 78, 95, 88] ,如果要获取第三个学生的成绩,直接通过索引 2 就能快速得到 78 。但如果要在第二个位置插入一个新成绩 80 ,就需要将后面的元素 90, 78, 95, 88 依次向后移动一位,然后再插入 80 。

        顺序表在很多程序设计中都有应用,比如简单的数组实现、一些对随机访问要求较高而插入删除操作较少的场景等,今天我们用java来简单实现一下顺序表。


构造方法:    

    首先,构造一个顺序表,需要int capacity 表示顺序表的内存大小(这里先传入一个值作为参数,后面内存不够用我们会有专门申请内存的方法)、int size表示表里面元素的个数、Object [] array 来命名这个顺序表,这时候一个最基本的顺序表就被构造出来了,以下是代码实现:

public class Linear_List<E> {

    private  int capacity = 10;
    private int size=0;
    private Object [] array = new Object [capacity];

添加方法:

        要对顺序表array进行添加操作,需要传入两个参数 泛型 element 以及 int index,代表在index下标插入 泛型 element。

        注意:这里需要判断 index 和 size 的大小,如果index<0 || index>size,则理应抛出错误。

        在index位置插入元素,只需要将原来index以及index后面的元素往后移一位,空出来的位置给element即可。下面是添加方法的代码实现:

public void add(E element , int index) {
        if (index<0 || index>size)
            throw new IndexOutOfBoundsException("Index out of bounds");
        for (int i = size; i >index; i--) {
        array[i] = array[i-1];
        }
        array[index] = element;
        size++;
    }

        但是当顺序表中存储的元素数量达到当前分配的存储空间上限时,就需要进行扩容。具体来说,常见的情况有:

  • 持续向顺序表中添加元素,导致已分配的存储空间被填满。

        例如,最初分配的顺序表空间能存储 10 个整数,当已经存储了 10 个整数后,如果还需要继续添加新的整数,就需要扩容。

  • 事先无法准确预估元素数量,且实际存储的元素数量超出了初始的预计。

        假设一个用于存储用户订单信息的顺序表,由于促销活动导致订单数量大幅增加,超出了初始分配的空间。

  • 业务需求发生变化,导致需要存储更多的元素。

        比如原本的系统只需要存储一个月内的交易记录,但业务调整后需要存储半年甚至更长时间的交易记录,原有的顺序表空间可能就不够了。

        在进行扩容时,通常会重新分配一块更大的连续存储空间,并将原有的元素复制到新的空间中。扩容的策略可以是按照一定的比例增加空间,例如每次扩容为原来的两倍;也可以是增加固定的大小,如每次增加一定数量的存储单元,原来的那块空间也并不会造成空间浪费,通常会被JVM的垃圾回收机制自动回收。

        通常把扩容操作放在添加方法内部,因为在添加元素时才会有可能需要用到扩容操作,以下是添加了扩容操作的添加方法的代码实现:

public void add(E element, int index) {
    // 如果索引不在有效范围内,抛出异常
    if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index out of bounds");
    // 如果当前元素数量达到容量,进行扩容操作
    if (size >= capacity) {  
        int newCapacity = capacity * 2;  // 新容量为原容量的两倍
        Object[] newArray = new Object[newCapacity];  // 创建新的数组
        System.arraycopy(array, 0, newArray, 0, size);  // 将原数组内容复制到新数组
        array = newArray;  // 更新数组引用
        capacity = newCapacity;  // 更新容量
    }
    // 将指定索引及之后的元素向后移动一位
    for (int i = size; i > index; i--) {
        array[i] = array[i - 1];
    }
    array[index] = element;  // 在指定索引位置插入新元素
    size++;  // 元素数量加 1
}

删除方法:

        首先,要检查删除操作中指定的索引是否合法。如果索引小于 0 或者大于等于顺序表的当前元素数量,就会抛出一个索引越界的异常,因为这样的索引不存在有效的元素可删除。

        若索引合法,就将指定索引位置之后的元素依次向前移动一位,覆盖要删除的元素位置。然后,把原本顺序表的最后一个位置设置为 null,并将顺序表的元素数量减 1,表示完成了一个元素的删除操作。以下是删除方法的代码实现:

public E remove(int index) {
        if (index<0 || index>size-1)  throw new IndexOutOfBoundsException("Index out of bounds");
        E key = (E) array[index];
        for (int i = index; i <size; i++) {
            array[i] = array[i+1];
        }size--;
        return key;
    }

判空和get方法:

        判空方法通常用于判断顺序表是否为空。这可以通过检查顺序表中元素的数量来实现。如果元素数量为 0 ,则认为顺序表为空。

        get方法用于获取顺序表中指定索引位置的元素。在实现时,需要先检查索引的合法性,如果索引不合法(小于 0 或大于等于元素数量),则抛出异常。如果索引合法,就返回该索引位置的元素。以下是两种方法的代码实现:

 public boolean is_Empty(){
        return size==0;
    }

    public E get(int index) {
        if (index<0 || index>size-1)  throw new IndexOutOfBoundsException("Index out of bounds");
        return (E) array[index];
    }

转字符串输出(toString)方法:

        toString方法其主要目的是将顺序表的相关信息以字符串的形式进行展示。通常会先获取顺序表中实际存储元素的数组部分,并将其转换为字符串表示。同时,还会获取顺序表中当前元素的数量。

        当调用顺序表对象的 toString 方法时,就能得到一个清晰反映顺序表内部状态的字符串描述,方便进行输出、调试或其他需要以字符串形式获取顺序表信息的操作。以下是toString方法的代码实现:

    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < size; i++){
        builder.append(array[i]).append(" "); }
        return builder.toString();
    }

完整代码实现:

public class Linear_List<E> {

    private  int capacity = 10;
    private int size=0;
    private Object [] array = new Object [capacity];
    public void add(E element , int index) {
        if (index<0 || index>size)
            throw new IndexOutOfBoundsException("Index out of bounds");
        if (size>=capacity){  // 扩容
            int newCapacity = capacity*2;
            Object[] newArray = new Object[newCapacity];
            System.arraycopy(array,0,newArray,0,size);
            array = newArray;
            capacity = newCapacity;
        }
        for (int i = size; i >index; i--) {
        array[i] = array[i-1];
        }
        array[index] = element;
        size++;
    }

    public E remove(int index) {
        if (index<0 || index>size-1)  throw new IndexOutOfBoundsException("Index out of bounds");
        E key = (E) array[index];
        for (int i = index; i <size; i++) {
            array[i] = array[i+1];
        }size--;
        return key;
    }

    public boolean is_Empty(){
        return size==0;
    }

    public E get(int index) {
        if (index<0 || index>size-1)  throw new IndexOutOfBoundsException("Index out of bounds");
        return (E) array[index];
    }

    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < size; i++) { builder.append(array[i]).append(" "); }
        return builder.toString();
    }
}

“静静地目送,享受这一刻,在混乱之中。”——《xingyu_xuan》

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

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

相关文章

前端养成记-实现一个低配版简单版本的vue3表单自定义设计组件

简介&#xff1a; 通过使用了最新的vue3,vite2,TypeScript等主流技术开发&#xff0c;并配合使用vuedraggable 插件以及antd design vue 组件库实现低配版本的自定义表单设计组件&#xff1b; 项目地址&#xff1a;https://gitee.com/hejunqing/vue3-antdv-generator

GLSL教程 第8章:几何着色器

目录 8.1 几何着色器的介绍 几何着色器的主要功能&#xff1a; 几何着色器的工作流程&#xff1a; 8.2 实现基本的几何变换 示例&#xff1a;将三角形扩展成多个三角形 8.3 几何着色器的高级应用 1. 粒子系统 2. 光晕效果 3. 线框模型 小结 几何着色器是图形管线中的一…

Linux——管理本地用户和组(详细介绍了Linux中用户和组的概念及用法)

目录 一、用户和组概念 &#xff08;一&#xff09;、用户的概念 &#xff08;二&#xff09;、组的概念 补充组 主要组 二、获取超级用户访问权限 &#xff08;一&#xff09;、su 命令和su -命令 &#xff08; 二&#xff09;、sudo命令 三、管理本地用户账户 &…

Java面试八股之什么是声明式事务管理,spring怎么实现声明式事务管理?

什么是声明式事务管理&#xff0c;spring怎么实现声明式事务管理&#xff1f; 声明式事务管理是一种编程范式&#xff0c;它允许开发人员通过声明性的配置或注解&#xff0c;而不是硬编码事务处理逻辑&#xff0c;来指定哪些方法或类应该在其上下文中执行事务。这种方法将事务…

Kadane 算法 | 53. 最大子数组和 + 918. 环形子数组的最大和

目录 1 维基百科2 53. 最大子数组和2.1 代码思路2.2 完整代码 3 918. 环形子数组的最大和3.1 代码思路3.2 完整代码 1 维基百科 最大子数组问题 在计算机科学中&#xff0c;最大子数组问题的目标是在数组的一维方向找到一个连续的子数组&#xff0c;使该子数组的和最…

Axious的请求与响应

Axious的请求与响应 1.什么是Axious Axious是一个开源的可以用在浏览器和Node.js的异步通信框架&#xff0c;它的主要作用就是实现AJAX异步通信&#xff0c;其功能特点如下&#xff1a; 从浏览器中创建XMLHttpRequests ~从node.js创建Http请求 支持PromiseAPI 拦截请求和…

[UVM源代码研究] 聊聊UVM中的callback机制

1. callback机制是什么&#xff1f; 以最高效的方式完成芯片验证&#xff0c;一直以来都是验证人员的首要目标&#xff0c;那么最直接的方式就是环境的移植和重用&#xff0c;一个优秀的验证工程师&#xff0c;在开发环境的过程中&#xff0c;一定会考虑环境的继承和重用。 继…

c++ 智能指针shared_ptr与make_shared

shared_ptr是C11引入的一种智能指针&#xff0c;‌它允许多个shared_ptr实例共享同一个对象&#xff0c;‌通过引用计数来管理对象的生命周期。‌当最后一个持有对象的shared_ptr被销毁时&#xff0c;‌它会自动删除所指向的对象。‌这种智能指针主要用于解决资源管理问题&…

简单小案例分析

一、容器和实例关系 <div class"app"><h1>Hello,{{name}}</h1> </div> <div class"app"><h1>Hello,{{name}}</h1> </div><script>//创建Vue实例new Vue({el:".app", //el用于指定当前V…

北大延毕硕士×INFJ | 我解脱了

前言 拿了双证&#xff0c;我终于能静下心来复盘一下我延毕一年的经历了。 给后面也许有相同困境的朋友们做个参考或者心理疏导作用。 延毕的原因 我延毕的主要原因是论文研三的时候论文没有完成&#xff0c;我们专业的论文一般是6个月全身心投入可以完成。我这个人是典型的…

7月24日JavaSE学习笔记

序列化版本控制 序列化&#xff1a;将内存对象转换成序列&#xff08;流&#xff09;的过程 反序列化&#xff1a;将对象序列读入程序&#xff0c;转换成对象的方式&#xff1b;反序列化的对象是一个新的对象。 serialVersionUID 是一个类的序列化版本号 private static fin…

77.WEB渗透测试-信息收集-框架组件识别利用(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;76.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;16&#xff09; java&#xff…

The Llama 3 Herd of Models.Llama 3 模型论文全文

现代人工智能(AI)系统是由基础模型驱动的。本文提出了一套新的基础模型,称为Llama 3。它是一组语言模型,支持多语言、编码、推理和工具使用。我们最大的模型是一个密集的Transformer,具有405B个参数和多达128K个tokens的上下文窗口。本文对Llama 3进行了广泛的实证评价。我们…

【Django】前端技术HTML常用标签(开发环境vscode)

文章目录 安装两个常用插件HTML常用标签定义文档类型DOCTYPE网页的结构html/head//title/body/div标题h1/h2/h3/h4/h5分割线hr段落 p列表ul/li&#xff0c;ol/li超链接a文本span图片img按钮button表格table&#xff08;table、tr、th、td&#xff09;表单form 安装两个常用插件…

深度学习环境配置——总结下近期遇到的”坑“

文章目录 1. 问题1&#xff1a;硬件选择的误区2. 问题2&#xff1a;操作系统的适配难题3. 问题3&#xff1a;深度学习框架的安装陷阱4. 问题4&#xff1a;CUDA与cuDNN的版本匹配问题5. 问题5&#xff1a;网络配置的瓶颈6. 问题6&#xff1a;数据预处理的技巧7. 问题7&#xff1…

CVPR`24 | 4D编辑哪家强?浙大首次提出通用指导4D编辑框架:Instruct 4D-to-4D

文章链接&#xff1a;https://arxiv.org/pdf/2406.09402 项目地址&#xff1a;https://immortalco.github.io/Instruct-4D-to-4D/ 今天和大家一起学习的是Instruct 4D-to-4D&#xff0c;可以通过2D扩散模型实现4D感知和时空一致性&#xff0c;以生成高质量的指令引导的动态场景…

用户使用算力共享平台流程

目录 用户使用算力共享平台流程 一、用户注册与认证 二、接入算力资源 三、任务发布与管理 四、商业调度与资源分配 五、任务执行与结果验证 六、支付与结算 七、评价与信誉建立 算力架构概述 “以案赋能” | 首届“华彩杯”算力应用创新大赛全国总决赛获奖案例选编

【JUC】Java锁介绍

文章目录 阿里锁开发规范乐观锁和悲观锁悲观锁乐观锁 synchronized 类锁、对象锁synchronized有三种应用方式锁相关的8种案例演示&#xff08;对象锁、类锁&#xff09;标准访问ab两个线程&#xff0c;请问先打印邮件还是短信&#xff1f;sendEmail钟加入暂停3秒钟&#xff0c;…

【Python机器学习】决策树的构造——递归构建决策树

我们可以采用递归的原则处理数据集&#xff0c;递归结束的条件是&#xff1a;程序遍历完所有划分数据集的属性&#xff0c;或者每个分支下的所有实例都具有相同的分类。如果所有实例具有相同的分类&#xff0c;则得到一个叶子节点或者终止块。任何到达叶子节点的数据必然属于叶…

软考:软件设计师 — 7.软件工程

七. 软件工程 1. 软件工程概述 &#xff08;1&#xff09;软件生存周期 &#xff08;2&#xff09;软件过程 软件开发中所遵循的路线图称为 "软件过程"。 针对管理软件开发的整个过程&#xff0c;提出了两个模型&#xff1a;能力成熟度模型&#xff08;CMM&#…