顺序表(快速上手数据结构)

在介绍ArrayList之前, 我们需要先了解List.

List是一个接口,它继承于Collection接口(Collection又继承于最顶层的接口Iterable).  从数据结构的角度来看,List就是一个线性表(Linear List),即n个具有相同类型元素的有限序列, 在该序列上可以执行增删查改等操作.

注意: List是一个接口,不能直接用来实例化. 在集合框架中, ArrayList类和LinkedList类都实现了List接口. 我们可以通过这两个类来实例化对象. 本篇博客主要讲述ArrayList类(顺序表).

目录

顺序表

1. 新增元素

2. 在pos位置新增元素

3. 判定是否包含某个元素

4. 查找某个元素对应的位置,并返回下标 

5. 获取pos位置的元素

6. 给pos位置的元素设为value(给某位置的元素更新)

7. 删除某数字key

8. 获取顺序表的长度

9.清空顺序表


顺序表

顺序表中主要有如下几种方法:

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); //删除第一次出现的关键字keyvoid size(); //获取顺序表的长度void clear(); //清空顺序表void display(); //打印数组(不属于顺序表中的方法)
}

今天,我们就用Java来实现一遍这七种方法. 相信在我们自己实现完一遍顺序表之后,我们的代码能力和思维会有不小的提升!

首先,我们需要定义一个操作数组,用来让方法对其进行操作:

public class MyArrayList {public int[] elem; //定义一个整型类型的操作数组public int usedSize; //定义一个变量表示已使用空间 (没有初始化--默认是0)public MyArrayList() { //构造方法 (将数组长度初始化为10)this.elem = new int[10];}
}

 

1. 新增元素

void add(int data) 默认在数组的最后新增.

在这里,我们只需要在数组有数据的位置的后一个(即:usedSize位置上(例如: usedSize=5, 那么0,1,2,3,4 位置上有元素, 将新增数据放到5位置上就行))放上我们要新增的数据即可.但是:如果数组满了,还能新增吗? -- 不能,此时需要将数组扩容才能继续新增操作.

结合上面两方面的考虑,我们写出如下代码:

 public void add(int data) {if (isFull()) {elem = Arrays.copyOf(elem,2*elem.length);}this.elem[usedSize] = data;this.usedSize ++;}boolean isFull() {return (usedSize == elem.length);}

我们在main方法里调用它测试一下:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.display();}
}

 运行结果:

2. 在pos位置新增元素

在pos位置新增元素,我们需要考虑的点有以下几个: (1) 将pos位置后的元素整体向后移. (2) 插入新的数据. (3) 检查pos位置是否合法.

  • 检查pos位置是否合法: pos<0时不合法; pos>usedSize时不合法(pos=usedSize时是合法的,因为此时相当于在数组的最后新增一个元素)
  • 移动元素: 令i等于数组最后一个位置(usedSize-1), 从数组最后一个位置开始遍历数组,将 i位置上的元素赋到 i+1位置上
  • 插入数据: 将数据data放到数组下标为pos的位置上即可. 所有操作完成后, 再让usedSize++即可.

注意: pos位置不合法我们可以写一个异常出来,方便检查和处理.

根据上述步骤,我们可以写出如下代码:

    public void add(int pos, int data) {try{checkOfPosAdd(pos); //检查pos是否合法}catch(PosIllegalException e){e.printStackTrace(); //打印异常}if (isFull()) {elem = Arrays.copyOf(elem,2*elem.length); //如果数组满了需要扩容}for (int i = usedSize-1; i >= pos ; i--) {elem[i+1] = elem[i]; //向后移动元素}elem[pos] = data; //插入新的元素usedSize ++;}private void checkOfPosAdd(int pos) throws PosIllegalException {if (pos < 0 || pos > usedSize) {throw new PosIllegalException("pos位置不合法");}}

在main方法中调用:

    public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();iList.add(2,88);iList.display();}
}

运行结果: 

 

3. 判定是否包含某个元素

对于这个方法的实现, 我们只需遍历数组, 看是否有要找的数据,如果有,则返回true

代码:

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

在main方法中调用:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();System.out.println(iList.contains(2));}
}

运行结果: 

 

4. 查找某个元素对应的位置,并返回下标 

对于这个方法的实现, 我们还是遍历数组.  如果有要找的数据,则返其对应的下标; 如果没有, 则返回-1.

代码:

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

在main方法中调用:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();System.out.println(iList.indexOf(2));}
}

运行结果:

5. 获取pos位置的元素

 实现这个方法,分两步: (1) 判断pos位置是否合法. (2) 返回pos位置元素的值.

(1) pos<0 或 pos>=usedSize 时不合法(pos==UsedSize时此位置上没有元素, 所以不合法). 所以这里我们就需要写一个方法来判断pos是否合法.

(2) 返回pos位置的元素: 直接返回即可.

代码:

public int get(int pos) {try{checkPosOfGetAndSet(pos);}catch(PosIllegalException e) {e.printStackTrace();}return elem[pos];

在main方法中调用:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();System.out.println(iList.get(2));}
}

 运行结果:

6. 给pos位置的元素设为value(给某位置的元素更新)

实现这个方法, 也要分为两步: (1) 判断pos位置是否合法.  (2) 给pos位置的元素设为value

代码:

    public void set(int pos, int value) {try{checkPosOfGetAndSet(pos);}catch(PosIllegalException e){e.printStackTrace();}elem[pos] = value;}

在main方法中调用:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();iList.set(2,333);iList.display();}
}

 运行结果:

7. 删除某数字key

我们首先要判断这个数字书是否在数组里面.然后在删除(删除的方法是"覆盖"--用后面的数据覆盖前面的数据从而实现对前面数据的删除)

代码:

    public void remove(int toRemove) {int pos = indexOf(toRemove);if (pos == -1) {System.out.println("没有要删除的数字");return; //为什么要写return? 有必要吗?}for (int i = pos; i < usedSize-1; i++) {elem[i] = elem[i+1];}this.usedSize--;

在main方法中调用:

public class Test {public static void main(String[] args) {IList iList = new MyArrayList();//实例化一个MyArraList的对象.iList.add(1);iList.add(2);iList.add(3);iList.display();iList.remove(2);iList.display();}
}

 运行结果:

8. 获取顺序表的长度

 代码:

    public int size() {return this.usedSize;}

9.清空顺序表

本例中:数组是基本类型(int)的, 所以我们只需要把usedSize置为0即可. 但是如果数组中存放的时引用类型,那么即使将usedSize置为0,堆上存放的对象还是被栈上的变量引用着(但是这些对象没用了),这样的话就会造成内存泄漏,形成不必要的内存损失.

所以: 数组中如果存放的是引用类型, 需要先将数组元素置为null, 再将usedSize置为0.

    public void clear() {usedSize = 0;}

 以上就是本篇博客的全部内容啦,如果喜欢小编的文章,可以点赞,评论,收藏~

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BetterDisplay Pro for Mac 显示器校准和优化软件

BetterDisplay Pro for Mac是一款适用于Mac电脑的显示器校准和优化软件。它可以帮助用户校准显示器的颜色、亮度、对比度和伽马值等参数&#xff0c;使得显示器更加准确和清晰&#xff0c;提高用户的工作效率。 BetterDisplay Pro for Mac v2.0.11激活版下载 这款软件具有直观的…

cesium primitive 移动 缩放 旋转 矩阵

旋转参考&#xff1a;cesium 指定点旋转rectangle Primitive方式 矩阵篇-CSDN博客 平移参考&#xff1a;cesium 调整3dtiles的位置 世界坐标下 相对坐标下 平移矩阵-CSDN博客 一、primitive方式添加polygon let polygonInstance new Cesium.GeometryInstance({geometry: Ce…

快速入门Spring Data JPA

Spring Data JPA是Spring Data框架的一小部分&#xff0c;它能够让开发者能够更加简单的对数据库进行增删改查。 由于Spring Data JPA可以自动生成SQL代码所以一般情况下&#xff0c;简单的增删查改就可以交给Spring Data JPA来完成&#xff0c;而复杂的动态SQL等用MyBatis来完…

分类损失函数与评估指标

目录 1 评估指标 1.1 准确率 1.2 精确率 1.3 召回率 1.4 F1 score 1.5 ROC曲线 1.6 AUC 1.7 PRC曲线的优势 2 损失函数 1. 负对数似然损失 2. 交叉熵损失 3. 指数损失 3 分类问题为什么用交叉熵损失不用 MSE 损失 1 评估指标 混淆矩阵 TP(True Positive) ---- 正…

xxl-job使用自动注册节点,ip不对,如何解决????

很明显这时我们本机的ip和我们xxl-job自动注册的ip是不一致的&#xff0c;此时该如何处理呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 方法一&#xff1a;在配置文件中&#xff0c;将我们的ip固定写好。 ### xxl-job executor server-info xxl.job.executor.ip写你的…

【LAMMPS学习】八、基础知识(3.3)使用分布式网格

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

Vue加载glb / gltf模型(如何在vue中使用Three.js,vue使用threejs加载glb模型)

简介&#xff1a;Three.js 是一个用于在 Web 上创建和显示 3D 图形的 JavaScript 库。它提供了丰富的功能和灵活的 API&#xff0c;使开发者可以轻松地在网页中创建各种 3D 场景、模型和动画效果。可以用来展示产品模型、建立交互式场景、游戏开发、数据可视化、教育和培训等等…

配置路由器实现互通

1.实验环境 实验用具包括两台路由器(或交换机)&#xff0c;一根双绞线缆&#xff0c;一台PC&#xff0c;一条Console 线缆。 2.需求描述 如图6.14 所示&#xff0c;将两台路由器的F0/0 接口相连&#xff0c;通过一台PC 连接设备的 Console 端口并配置P地址&#xff08;192.1…

C++|运算符重载(2)|运算符重载的方法与规则

写在前面 上篇介绍到&#xff0c;为什么要进行运算符重载&#xff1a;是因为我们希望预定义的内部运算符&#xff0c;在特定的类对象上亦可以直接使用。 C|运算符重载&#xff08;1&#xff09;|为什么要进行运算符重载-CSDN博客https://blog.csdn.net/weixin_74197067/artic…

Spring Boot 多环境配置:YML 文件的三种高效方法

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

06节-51单片机-LCD1602调试工具

欢迎订阅专栏&#xff0c;持续为您更新&#xff01; 1.LCD1602调试工具 使用LCD1602液晶屏作为调试窗口&#xff0c;提供类似printf函数的功能&#xff0c;可实时观察单片机内部数据的变换情况&#xff0c;便于调试和演示。 本文提供的LCD1602代码属于模块化的代码&#xff…

Java集合-泛型(Generic)

目录 1、泛型(Generic) 1.1 泛型方法 1.2 泛型类 1.3 泛型接口 1.4 泛型通配符 1、泛型(Generic) 当集合中存储的对象类型不同时&#xff0c;那么会导致程序在运行的时候的转型异常 import java.util.ArrayList; import java.util.Iterator; public class Demo5 { pub…