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

在介绍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://xiahunao.cn/news/2960300.html

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

相关文章

Golang面试题四(GMP)

目录 1.Goroutine 定义 2.GMP 指的是什么 3.GMP模型的简介 全局队列&#xff08;Global Queue&#xff09; P的本地队列 P列表 M列表 4.有关P和M的个数问题 P的数量问题 M的数量问题 P和M何时会被创建 5.调度器P的设计策略 复⽤线程 work stealing机制 hand off…

【linux】mobaterm如何kill pycharm进程

【linux】mobaterm如何kill pycharm进程 【先赞后看养成习惯】求点赞关注收藏&#x1f600; 使用云服务器时&#xff0c;pycharm在打开状态下&#xff0c;不小心关了mobaxterm&#xff0c;然后再输入pycharm.sh就会打不开pycharm&#xff0c;显示已经打开报错&#xff1a;Com…

PyQt程序:实现新版本的自动更新检测及下载(FTP服务器实现)

一、实现逻辑 本实例采用相对简单的逻辑实现,用户在客户端使用软件时点击“检测升级”按钮,连接至FTP服务器检索是否有新版本的.exe,如果有,下载最新的.exe安装升级。 本实例服务端待下载.exe所在目录结构 本实例客户端待更新.exe所在目录结构 二、搭建服务器 可以参考…

openkylin系统通过网线连接ubuntukylin系统上网攻略

openkylin系统通过网线连接ubuntukylin系统上网攻略 主机1&#xff1a;x64 amd &#xff0c;系统&#xff1a;ubuntukylin 22.04 &#xff0c;状态&#xff1a;通过wifi连接热点进行上网&#xff0c;并共享网络。 主机2&#xff1a;x64 intel &#xff0c;系统&#xff1a;ope…

Elasticsearch:下载、启动和账号密码登录

因为我的电脑是 window&#xff0c;以下都是以 window 环境举例。 一、下载 Elasticsearch 是使用 java 开发的&#xff0c;且 7.8 版本的 ES 需要 JDK 版本 1.8 以上&#xff0c;安装前注意java环境的准备。 官网地址&#xff1a;https://www.elastic.co/cn/ 下载地址&#xf…

WebStorm2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 WebStorm是一款由JetBrains公司开发的强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于前端开发。它提供了丰富的功能和工具&#xff0c;包括代码编辑器、调试器、版本控制集成等&#xff0c;使开发人员能够更…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09;前端验证—MIME绕过有关MIMEMIME的作用 解题时有…

SpringBoot使用xxl-job分布式任务调度平台定时检测RabbitMQ的消息队列自动发出钉钉警告消息

文章目录 SpringBoot使用xxl-job分布式任务调度平台定时检测RabbitMQ的消息队列自动发出钉钉警告消息1、在pom.xml中导入xxl-job的maven依赖&#xff0c;可以看我这篇文章使用抽离出来的xxl-job的starter2、配置xxl-job的相关配置&#xff0c;若上一步使用了自己创建的starter则…

【python】flask操作数据库工具SQLAlchemy,详细用法和应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

操作系统—实现可变式分区分配算法

文章目录 实现可变式分区分配算法1.实验环境2.如何在xv6中实现分区分配算法&#xff1f;(1).xv6的内存管理机制(2).实现思路 3.最佳适应算法(1).基本思路(2).步骤(3).测试&Debug 总结参考资料 实现可变式分区分配算法 1.实验环境 因为这一次的实验仍然是在xv6中进行&#…

Adobe AE(After Effects)2021下载地址及安装教程

Adobe After Effects是一款专业级别的视觉效果和动态图形处理软件&#xff0c;由Adobe Systems开发。它被广泛用于电影、电视节目、广告和其他多媒体项目的制作。 After Effects提供了强大的合成和特效功能&#xff0c;可以让用户创建出令人惊艳的动态图形和视觉效果。用户可以…

vue的就地更新与v-for的key属性

vue的就地更新 Vue中的就地更新到底是怎么回事&#xff0c;为什么会存在就地更新的现象&#xff1f; 注意下面的例子&#xff0c;使用v-for指令时&#xff0c;没有绑定key值&#xff0c;才有就地更新的现象&#xff0c;因为Vue默认按照就地更新的策略来更新v-for渲染的元素列表…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于用户生产场景辨识的电压暂降经济损失评估》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

十大远程控制软件排名

远程控制软件在现代计算环境中扮演着至关重要的角色&#xff0c;它们使得用户能够轻松地访问和管理远程计算机或设备。随着技术的不断进步&#xff0c;市场上涌现出许多优秀的远程控制工具。以下是对当前市场上十大远程控制软件的简要排名和介绍&#xff0c;以帮助您选择最适合…

Go Plugin:动态模块的加载与问题解析_go语言加载动态库的工具(1)

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

Linux环境如何端口映射?

在网络通信中&#xff0c;端口映射是一项重要的技术&#xff0c;在Linux系统中广泛应用。它的主要作用是实现不同网络设备之间的通信&#xff0c;使得远程访问成为可能。本文将介绍Linux端口映射的基本原理和应用场景&#xff0c;并重点介绍了一种名为【天联】的组网优势。 端口…

第47期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

操作系统—GCC与编译全流程

文章目录 GCC与编译全流程1.GCC是什么&#xff1f;2.编译全流程(1).GCC到底做了哪些事情&#xff1f;(2).预处理I.预处理会做什么II.预处理器主要包含什么&#xff1f;III.宏的一些魔法 (3).编译I.基本流程II.编译优化III.一点例子 (4).汇编(5).链接(6).说到这里&#xff0c;为…

AIGC实战——VQ-GAN(Vector Quantized Generative Adversarial Network)

AIGC实战——VQ-GAN 0. 前言1. VQ-GAN2. ViT VQ-GAN小结系列链接 0. 前言 本节中&#xff0c;我们将介绍 VQ-GAN (Vector Quantized Generative Adversarial Network) 和 ViT VQ-GAN&#xff0c;它们融合了变分自编码器 (Variational Autoencoder, VAE)、Transformer 和生成对…

免费的 ChatGPT、GPTs、AI绘画(国内版)

&#x1f525;博客主页&#xff1a;白云如幻❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚…