Java顺序表(1)

🐵本篇文章将对顺序表中的方法进行模拟实现


一、线性表

线性表是指在逻辑结构上呈连续的线性结构,而在物理结构上不一定是连续的结构,常见的线性表有:顺序表、链表、栈、队列等

二、顺序表

顺序表一般采用数组来存储数据,因此它是一种逻辑结构上连续,在物理结构上也连续的数据结构,下面对顺序表的增删查改等操作用Java进行具体实现

先实现一个接口,在这个接口写上要实现的方法:

public interface IList {
    
    void add(int data); // 新增元素,默认在数组最后新增

    void add(int pos, int data); // 在 pos 位置插入元素

    boolean contains(int toFind); // 判定是否包含某个元素

    int indexOf(int toFind); // 查找某个元素对应的位置

    int get(int pos); // 获取 pos 位置的元素

    void set(int pos, int value); // 给 pos 位置的元素设为 value

    void remove(int toRemove); //删除第一次出现的关键字toRemove
 
    int size(); // 获取顺序表长度

    void clear(); // 清空顺序表

    void display(); // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
}

之后再创建一个MyArrayList类实现上述接口并重写接口中所有的方法

public class MyArrayList implements IList{
    public int[] elem; //存储数据

    public int usedSize; //已经放入顺序表中数据的个数

    public static final int DEFAULT_CAPACITY = 5; //顺序表中默认容量的大小为5
    
    public MyArrayList() {
        elem = new int[DEFAULT_CAPACITY];
    }

    /*以下是要重写IList接口中的方法*/
    ...

}

2.1 方法的实现

void add(int data); // 新增元素,默认在数组尾部新增

在数组的尾部新增一个元素,之前的ArrayList类中有一个变量为usedSize,用于记录顺序表中已存数据的个数,刚开始存入数据的时候usedSize为0,那么每次向数组中存入一个数据,usedSize就加1

public void add(int data) {
    elem[usedSize] = data;
    usedSize++;
}

写到这里还要考虑一个问题:如果数组满了怎么办,我们前面定义了数组的默认大小为5,如果已经向数组中存入了5个数据在存数据的话,就会抛出数组越界异常,所以在向数组中新增元素时要先判断一下数组满没满,如果满了则要扩容,然后再新增元素

public void add(int data) {
    if (usedSize == elem.length) {
        elem = Arrays.copyOf(elem, elem.length * 2);
    }

    elem[usedSize] = data;
    usedSize++;
}

Arrays.copyOf的方法定义如下:

public static int[] copyOf(int[] original, int newLength)

int[] original为源数组,newLength为该数组的新长度


void add(int pos, int data); // 在 pos 位置插入元素

那么接下来有一个问题,这些元素怎么移动?是从后往前移动还是从前往后移动,答案是从后往前移动,因为如果从前往后移动的话,先将2放在了3的位置处,如果再要将3移动到4位置时发现3已经被2覆盖了,所以要从5开始倒着依次向后移动

public void add(int pos, int data) {

    for (int i = usedSize; i >= pos; i--) {
               //循环条件为i >= pos,因为pos位置处的元素也要往后移动
        elem[i] = elem[i - 1];
    }

    elem[pos] = data; //移动完后,直接再pos位置处插入新增元素
}

写到这里后还要考虑两点:1.pos位置是否合法;2. 此时数组有没有满

先来看第一个:pos位置是否合法,这个很简单,我们可以在第一句加上一个判断pos的方法,如果pos不合法则抛出一个异常使程序终止

public class EmptyException extends RuntimeException{
    public EmptyException(String message) {
        super(message);
    }
}

========================================================

private void checkPosAdd(int pos) {
    if (pos < 0 || pos >= usedSize + 1) {
    //数组的下标不能为0;在一个位置插入后,必须是连续的因为前面说过顺序表在物理结构上也是连续的
        throw new PosException("下标错误");
    }
}

判断数组满没满跟之前一样,以下是该方法的最终实现:

public void add(int pos, int data) {
    checkPosAdd(pos);

    if (usedSize == elem.length) {
        elem = Arrays.copyOf(elem, 2 * elem.length);
    }

    for (int i = usedSize; i >= pos; i--) {
        elem[i] = elem[i - 1];
    }

    elem[pos] = data;
    usedSize++;
}

boolean contains(int toFind); // 判定数组中是否包含某个元素

实现这个方法很简单,只需要遍历一遍数组即可

public boolean contains(int toFind) {

    for (int i = 0; i < usedSize; i++) {
        if (elem[i] == toFind) {
            return true;
        }
    }

    return false;
}

int indexOf(int toFind); // 查找某个元素对应的位置

同样,这个方法也遍历一遍数组即可

public int indexOf(int toFind) {
    for (int i = 0; i < usedSize; i++) {
        if (elem[i] == toFind) {
            return i;
        }
    }

    return -1; //如果没有这个元素,返回-1
}

int get(int pos); // 获取 pos 位置的元素

要先判断一下pos位置是否合法

private void checkPosGet(int pos) {
    if (pos < 0 || pos >= usedSize) {
              //这里pos >= usedSize 的原因是usedSize代表当前已存数据的个数,该位置还没有放元素
        throw new PosException("下标错误");
    }
}

get方法的最终实现:

public int get(int pos) {
    checkPosGet(pos);
    return elem[pos];
}

void set(int pos, int value); // 给 pos 位置的元素设为 value

该方法的实现和get方法几乎一致

public void set(int pos, int value) {
    checkPosGet(pos);
    elem[pos] = value
}

void remove(int toRemove); //删除第一次出现的关键字toRemove

在移动元素之前,要先得到toRemove的下标,可以直接利用刚刚实现的indexOf方法,得到下标后开始移动元素,移动完元素就相当于已经将toRemove删除了,那么让usedSize减1

public void remove(int toRemove) {

    int pos = indexOf(toRemove);
    for (int i = pos; i < usedSize - 1; i++) {
        elem[i] = elem[i + 1];
    }

    usedSize--;
}

在方法的开始还要判断一下数组是否为空,如果为空则不能删除,可以抛出一个异常

public class EmptyException extends RuntimeException{
    public EmptyException(String message) {
        super(message);
    }
}

=======================================================

public void remove(int toRemove) {
    if (usedSize == elem.length) {
        throw new EmptyException("顺序表为空");
    }

    int pos = indexOf(toRemove);

    for (int i = pos; i < usedSize - 1; i++) {
        elem[i] = elem[i + 1];
    }

    usedSize--;
}

int size(); // 获取顺序表长度

直接返回usedSize即可

int size() {
    return usedSize;
}

void clear(); // 清空顺序表

具体实现:

    public void clear() {
        usedSize = 0; //这里的顺序表中放的都是int类型而非引用类型,所以,不用将每个元素置空
                //如果顺序表中的元素都是引用类型则应遍历数组,将每个元素置空,再将usedSize置为0                                                         
    }


void display(); // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的

遍历数组并打印即可:

public void display() {
    for (int i = 0; i < usedSize; i++) {
        System.out.print(elem[i] +" ");
    }
    System.out.println();
}

🙉本篇文章到此结束,下一篇文章将对ArrayList进行讲解

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

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

相关文章

ELF文件格式解析二

使用objdump命令查看elf文件 objdump -x 查看elf文件所有头部的信息 所有的elf文件。 程序头部&#xff08;Program Header&#xff09;中&#xff0c;都以 PT_PHDR和PT_INTERP先开始。这两个段必须在所有可加载段项目的前面。 从上图中的INTERP段中&#xff0c;可以看到改段…

Android App打包加固后的APK无法安装问题

最近开发的一个应用要上架&#xff0c;正常流程打完包后去加固&#xff0c;由于以前一直用的是360的加固助手&#xff0c;这里开始也是选择用它。 使用360加固&#xff1a; 问题一、开始出现的问题是说应用未签名无法加固&#xff0c;我明明是签名后打的包&#xff0c;怎么会…

十分钟部署清华 ChatGLM-6B,实测效果超预期(Linux版)

前段时间&#xff0c;清华公布了中英双语对话模型 ChatGLM-6B&#xff0c;具有60亿的参数&#xff0c;初具问答和对话功能。 最&#xff01;最&#xff01;最重要的是它能够支持私有化部署&#xff0c;大部分实验室的服务器基本上都能跑起来。因为条件特殊&#xff0c;实验室网…

介绍几种常见的质数筛选法

质数筛选法 1.暴力筛选法 :smirk:2.普通优化 :rofl:3.埃氏筛法:cold_sweat:4.线性筛选法:scream: 质数&#xff1a;除了1和他本身没有其它因数的正整数就是质数。1不是质数&#xff0c;2是质数。 1.暴力筛选法 &#x1f60f; 原理 求x的质数&#xff0c;令y从2到 x \sqrt[]{x…

资源素材网站源码,功能齐备,界面干净整洁,附带安装教程

搭建教程 简单安装说明&#xff1a; 1、整站程序上传后台 2、然后导入数据库文件到数据库&#xff0c; 3、修改conf里面的conf的数据库名字及密码 4、配置伪静态 规则&#xff1a; location ~* \.(htm)$ { rewrite "^(.*)/(.?).htm(.*?)$" $1/index.php?$2…

Docker安装Jenkins,配置Maven和Java

前言 这是一个java的springboot项目&#xff0c;使用maven构建 安装准备 需要将maven和jdk安装在服务器上&#xff0c;Jenkins需要用到&#xff0c;还有创建一个jenkins的目录&#xff0c;安装命令如下&#xff1a; docker run -d -uroot -p 9095:8080 -p 50000:50000 --n…

20240109适配selinux让移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通

20240109适配selinux让移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通 2024/1/9 10:46 缘起&#xff1a;使用友善之臂的Android11可以让EC20上网&#xff0c;但是同样的修改步骤&#xff0c;Toybrick的Android11不能让EC20上网。 最后确认是selinux的问题&#…

UGUI Image图像控件替换图片

代码为探索而来&#xff0c;不是最优代码&#xff0c;请按需使用。 Unity3d引擎版本&#xff1a;Uinty3d 20233.2.3f1 补充一下图片如何改成Texture2D&#xff1a; 1、将图片导入unity。 2、选择图片&#xff0c;按下图操作&#xff0c;点击应用即可。 脚本代码&#xff1a…

【ECShop电子商务系统__软件测试作业】ECSHOP系统搭建文档+接口测试用例+接口文档+接口测试脚本

一、选题题目可选《ECShop电子商务系统》、《EPShop电子商城系统》或者自选其它的开源系统(至少有十个以上的功能模块的系统&#xff0c;不得选功能少、简单的系统)。 软件测试作业 说明:接口测试相关资料 二、具体要求 1、搭建测试系统并写出搭建被测系统的全过程。 2、根…

Spark---RDD序列化

文章目录 1 什么是序列化2.RDD中的闭包检查3.Kryo 序列化框架 1 什么是序列化 序列化是指 将对象的状态信息转换为可以存储或传输的形式的过程。 在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的…

使用curl命令在Linux中进行HTTP请求

在Linux中&#xff0c;curl是一个非常强大的命令行工具&#xff0c;用于发送HTTP请求。它允许用户发送各种类型的HTTP请求&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;并能够处理响应数据。 首先&#xff0c;确保您的Linux系统已经安装了curl。如果未安装&#xff0c;…

数组和函数实践:扫雷游戏玩法和棋盘初始化(1)

各位少年&#xff0c;大家好&#xff0c;我是博主那一脸阳光&#xff0c;我们学会了数组&#xff0c;exturn声明外部文件&#xff0c;static修饰静态变量&#xff0c;那么很显然&#xff0c;我们需要用到我们学习这些&#xff0c;实现一个扫雷游戏。 扫雷游戏介绍以及玩法 在地…

数据库高可用mha

MHA搭建的步骤 一.配置主从复制 1.初始化环境 #在四台服务器上初始化环境 systemctl stop firewalld systemctl disable firewalld setenforce 0 2.修改 Master、Slave1、Slave2 节点的主机名 #在Master上 hostnamectl set-hostname mysql1 su#在Slave1 hostnamectl set-h…

乐鑫ESP32与SD NAND的协同应用|MK-米客方德

SD NAND在乐鑫ESP32上的作用 SD NAND是贴片式TF卡&#xff0c;可以用于存储数据&#xff0c;比如视频图片或者代码 乐鑫ESP32一颗具有双核处理器的嵌入式系统芯片&#xff0c;有丰富的外设接口&#xff0c;包括Wi-Fi、蓝牙、UART、SPI、I2C等&#xff0c;使其适用于各种物联网…

【Blog】记录一下如何让自己的自建网站让百度搜索收录

记录一下如何让自己的自建网站让百度搜索收录 目录 记录一下如何让自己的自建网站让百度搜索收录一、前言二、开始操作1、第一步&#xff1a;进入设置2、第二步&#xff1a;开始设置3、第三步&#xff1a;让百度收录我们自己的文章 三、知识点记录1、注意事项2、可能会出现的问…

Python虚拟环境轻松配置:Jupyter Notebook中的内核管理指南

问题 在Python开发中&#xff0c;一些人在服务器上使用Jupyter Notebook中进行开发。一般是创建虚拟环境后&#xff0c;向Jupyter notebook中添加虚拟环境中的Kernel&#xff0c;后续新建Notebook中在该Kernel中进行开发&#xff0c;这里记录一下如何创建Python虚拟环境以及添…

uniApp 顶部导航栏右侧添加文字按钮

{"path" : "pages/allin/MessageCenter/MessageCenter","style" : {"navigationBarTitleText": "消息中心","enablePullDownRef…

MyBatisPlus学习笔记一

1、简介 MyBatisPlus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatisMyBatisMyBatis的的基础上只做增强不做改变&#xff0c;为简化开发&#xff0c;提高效率而生。 官网&#xff1a;MyBatis-Plus mybatisplus通过扫描实体类&#xff0c;并基于…

系统添加深色模式实现方案

业务需求,夜间看系统太刺眼,要求添加夜间模式 效果如下: 依赖如下: 参考了官方解决方案,尝试后没有有效的解决. 官方解决方案 后续打算换框架,发现antdesign pro vue版本的暗黑模式禁用了. ant design pro 预览地址 思路: 引入andesign 暗黑模式的样式 , 手动修改自定义类…

python代码练习:双指针法

题目一&#xff1a;移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…