JavaDS-学习数据结构之如果从零开始手搓顺序表,顺带学习自定义异常怎么用!
前言
笔者开始学习数据结构了,虽然笔者已经会用了,不管是C++ 中的stl亦或是Java 中的集合,为了算法比赛多少都突击过,但只知其然而不知其所以然,还是会限制发展的,因此,笔者写下这篇博客.内容是手搓一个顺序表.顺带加一点异常的使用,大伙看个乐子就好了.有错误直接私信喷我就好了,不用和我客气!
前置知识-什么是数据结构
说的简短一些,数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
前置知识-什么是顺序表?
答:说白了就是一个动态数组
官方概念如下:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表如何实现?
如图
一个接口,一个类负责实现方法,一个Main类来调用,一个我们自定义的异常来处理各种问题!!!
顺序表的接口
package LIST;public interface list
{// 新增元素,默认在数组最后新增public void add(int data);// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某个元素public boolean contains(int toFind);// 查找某个元素对应的位置public int indexOf(int toFind);// 获取 pos 位置的元素public int get(int pos);// 给 pos 位置的元素设为 valuepublic void set(int pos, int value);//删除第一次出现的关键字keypublic void remove(int toRemove);// 获取顺序表长度public int size() ;// 清空顺序表public void clear();// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display();public boolean isfull();// 负责检查顺序表是否满了public boolean isEmpty();//负责检查顺序表是否是空的
}
每个结构具体需要实现什么功能,笔者已经写在注释里了,作为一个"动态数组",也就是"CURD"而已.
没什么难的,但是不借助外力的手搓还是有点难的.
自定义异常
比起使用现有的异常,我们还是自己定义一个方便一些
package LIST;public class POSIllegal extends RuntimeException
{public POSIllegal(String message){super(message);}
}
顺序表的功能实现
前置功能
@Override
public boolean isfull()
// 检测顺序表是否以及满了
{if(usedsize==myarray.length)return true;elsereturn false;
}@Overridepublic boolean isEmpty(){return this.usedsize==0?true:false;}
设置这两个功能说实话有的没必要,但是一定要考虑到严谨,这必须加上来,以防止越界,也可以引出如果使用自定义异常!
通过这两个重写方法,也可以衍生出一个被封装的方法
private void checkcap()
{if(isfull())// 检测一下{myarray = Arrays.copyOf(myarray,myarray.length*2);// 扩容(两倍)}
}
为什么我们这里用private?因为你作为使用者,你压根用不着.这也是一种没什么必要的严谨性吧.早点养成习惯也不是什么坏事.
部分核心功能
接下来来到我们的核心功能了,我们一个个来看
增加
@Overridepublic void add(int data){checkcap();this.myarray[this.usedsize] =data;this.usedsize++;}
在指定位置增加
private void checkPos (int pos) throws POSIllegal{if(pos<0||pos>this.usedsize){throw new POSIllegal("pos不合法,你的pos是 :"+pos);}} @Overridepublic void add(int pos, int data){checkcap();try {checkPos(pos);}catch (POSIllegal e){e.printStackTrace();System.out.println("下标不符合规定");return ;}for(int i=this.usedsize-1;i>=pos;i--){this.myarray[i+1]=this.myarray[i];}this.myarray[pos]=data;this.usedsize++;}
我们首先,看看,需不需要扩容,不需要,好的,再看看有没有异常,有的话,抛出异常,让catch接收,然后return,没有异常,那就更好了,直接就可以扩容了,注意下标的边界就好了,没有难度.
得到指定位置的数据
@Overridepublic int get(int pos){try {return this.myarray[pos];} catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("越界了,数组只有"+myarray.length+"这么大");System.out.println("请你看看自己是不是选择了负数或者大于数组大小的数");return pos;}}
这里我们用了官方的异常,有个对比参考.
在指定位置替换元素
private void checkPosSet (int pos) throws POSIllegal{if(pos<0||pos>=this.usedsize){throw new POSIllegal("pos不合法,你的pos是 :"+pos);}}@Overridepublic void set(int pos, int value){try {checkPosSet(pos);}catch (POSIllegal e){e.printStackTrace();return ;}this.myarray[pos]=value;}
注意注意,这里和增加不同了,增加是可以在顺序表增加的,但是替换是不能在结尾替换的,因为你没有元素,你怎么替换?你告诉我.
获取指定位置元素
@Overridepublic int indexOf(int toFind){if(isEmpty()){return -1;}else{for(int i=0;i<this.usedsize;i++){if(this.myarray[i]==toFind)return i;}}return -1;}
这里我就没用try catch 写法了
移除第一次出现的某元素
@Overridepublic void remove(int toRemove){int idx=indexOf(toRemove);if(idx==-1){System.out.println("没有这个数字哦");}else{for(int i=idx;i<usedsize-1;i++){this.myarray[i]=this.myarray[i+1];}usedsize--;}}
其他功能
还有两个其他功能
清空,还有获得usedsize
@Overridepublic int size(){return this.usedsize;}@Overridepublic void clear(){if(isEmpty()){System.out.println("没法清理,顺序表是空的");return ;}for(int i=0;i<this.usedsize;i++){this.myarray[i]=0;}display();System.out.println("清空完成");}
主函数
package LIST;
public class Main
{public static void main(String[] args) {Mylist mylist=new Mylist();mylist.add(0,2);mylist.add(1,2);mylist.add(2,2);mylist.add(3,2);mylist.add(1,23);mylist.add(3,2);mylist.add(3,2);mylist.add(3,2);mylist.display();mylist.set(5,2324);mylist.set(7,232);mylist.add(543,242);System.out.println(mylist.size());mylist.display();mylist. clear();}
}
可以进行各种调用
也会显示异常出来
效果如图!!!!!!!
完整代码
完整代码如下
package LIST;public interface list
{// 新增元素,默认在数组最后新增public void add(int data);// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某个元素public boolean contains(int toFind);// 查找某个元素对应的位置public int indexOf(int toFind);// 获取 pos 位置的元素public int get(int pos);// 给 pos 位置的元素设为 valuepublic void set(int pos, int value);//删除第一次出现的关键字keypublic void remove(int toRemove);// 获取顺序表长度public int size() ;// 清空顺序表public void clear();// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display();public boolean isfull();// 负责检查顺序表是否满了public boolean isEmpty();//负责检查顺序表是否是空的
}
package LIST;
import java.util.Arrays;
public class Mylist implements list
{int [] myarray;public static final int number= 5;int usedsize=0;public Mylist(){this.myarray = new int[number];}
private void checkcap()
{if(isfull())// 检测一下{myarray = Arrays.copyOf(myarray,myarray.length*2);// 扩容(两倍)}
}
@Override
public boolean isfull()
// 检测顺序表是否以及满了
{if(usedsize==myarray.length)return true;elsereturn false;
}@Overridepublic boolean isEmpty(){return this.usedsize==0?true:false;}private void checkPos (int pos) throws POSIllegal{if(pos<0||pos>this.usedsize){throw new POSIllegal("pos不合法,你的pos是 :"+pos);}}private void checkPosSet (int pos) throws POSIllegal{if(pos<0||pos>=this.usedsize){throw new POSIllegal("pos不合法,你的pos是 :"+pos);}}
@Override
public void display()
{// 打印顺序表for(int i=0;i<this.usedsize;i++){System.out.print(myarray[i]);System.out.print(" ");}System.out.println();
}@Overridepublic void add(int data){checkcap();this.myarray[this.usedsize] =data;this.usedsize++;}@Overridepublic void add(int pos, int data){checkcap();try {checkPos(pos);}catch (POSIllegal e){e.printStackTrace();return ;}for(int i=this.usedsize-1;i>=pos;i--){this.myarray[i+1]=this.myarray[i];}this.myarray[pos]=data;this.usedsize++;}@Overridepublic boolean contains(int toFind){if(isEmpty()){System.out.println("找不到,因为顺序表是空的");return false;}for(int i=0;i<usedsize;i++){if(this.myarray[i]==toFind){System.out.println("找到了,它的下标是 :"+i);return true;}}System.out.println("顺序表里没有这么元素");return false;}@Overridepublic int indexOf(int toFind){if(isEmpty()){return -1;}else{for(int i=0;i<this.usedsize;i++){if(this.myarray[i]==toFind)return i;}}return -1;}@Overridepublic int get(int pos){try {return this.myarray[pos];} catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();System.out.println("越界了,数组只有"+myarray.length+"这么大");System.out.println("请你看看自己是不是选择了负数或者大于数组大小的数");return pos;}}@Overridepublic void set(int pos, int value){try {checkPosSet(pos);}catch (POSIllegal e){e.printStackTrace();return ;}this.myarray[pos]=value;}@Overridepublic void remove(int toRemove){int idx=indexOf(toRemove);if(idx==-1){System.out.println("没有这个数字哦");}else{for(int i=idx;i<usedsize-1;i++){this.myarray[i]=this.myarray[i+1];}usedsize--;}}@Overridepublic int size(){return this.usedsize;}@Overridepublic void clear(){if(isEmpty()){System.out.println("没法清理,顺序表是空的");return ;}for(int i=0;i<this.usedsize;i++){this.myarray[i]=0;}display();System.out.println("清空完成");}
}
package LIST;public class POSIllegal extends RuntimeException
{public POSIllegal(String message){super(message);}
}
结尾
可以看到,对于核心功能,我写的很草率,压根没有写完整,只是随便写了几个增删查改的功能,如果要细化还是能出很多的,交给能看到这里的读者了.
我写学过用C语言手搓顺序表,只能说,Java还是更简单一点.
需要我的完整代码,可以访问我的GitHub,链接点进去,这部分代码在JavaDS List当中
需要就点个星呗,我的GitHub有的乱,后续我会整理的.
calljsh/Call-JJ-java (github.com)
到这里我也写了快一个小时了,不知道有没有人可以看到啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
相关文章:

JavaDS-学习数据结构之如果从零开始手搓顺序表,顺带学习自定义异常怎么用!
前言 笔者开始学习数据结构了,虽然笔者已经会用了,不管是C 中的stl亦或是Java 中的集合,为了算法比赛多少都突击过,但只知其然而不知其所以然,还是会限制发展的,因此,笔者写下这篇博客.内容是手搓一个顺序表.顺带加一点异常的使用,大伙看个乐子就好了.有错误直接私信喷我就好了…...

汽车IVI中控开发入门及进阶(二十三):i.MX8
前言: IVI市场的复杂性急剧增加,而TimeToMarket在几代产品中从5年减少到2-3年。Tier1正在接近开放系统的模型(用户可以安装应用程序),从专有/关闭源代码到标准接口/开放源代码,从软件堆栈对系统体系结构/应用层/系统验证和鉴定的完全所有权,越来越依赖第三方中间件和平…...

HarmonyOS(29)onMeasureSize和PlaceChildren (View的测量和布局)
onMeasureSize和PlaceChildren onMeasureSize和PlaceChildren 说明官方使用示例参考资料 onMeasureSize和PlaceChildren 说明 在Android开发中View的测量onMeasure和布局onLayout是自定义组件必备的两个方法,HarmonyOS对自定义布局也提供了两个方法: on…...
如何管理和维护组件库?
管理和维护组件库是一个关键的任务,因为它直接关系到产品的稳定性和功能的实现。以下是一些有效的方法来管理和维护组件库: 创建清晰的命名和文件结构:为每个组件分配一个有意义的名称,并根据功能和类型进行有层次的分类。确保文件…...

使用Python和wxPython将PNG文件转换为JPEG文件
简介: 在图像处理中,有时候我们需要将PNG格式的图像文件转换为JPEG格式。本篇博客将介绍如何使用Python编程语言和wxPython图形用户界面库,以及Pillow图像处理库来实现这一转换过程。通过本文的指导,您将学习如何快速将指定文件夹…...

spark的简单学习二
一 spark sql基础 1.1 Dataframe 1.介绍: DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维表 格,除了数据以外,还掌握数据的结构信息,即schema。同时,与Hive类似,DataFrame也支 持…...
测试文章27-这是一篇测试文章请忽略
这是一篇测试文章请忽略 这是测试的文字,如有打扰请谅解。稍后测试完毕会删除 测试代码块 public static void main(String[] args){System.out.println("Hello, World!"); } aaa...
卡方分布和 Zipf 分布模拟及 Seaborn 可视化教程
卡方分布 简介 卡方分布是一种连续概率分布,常用于统计学中进行假设检验。它描述了在独立抽样中,每个样本的平方偏差之和的分布。卡方分布的形状由其自由度 (df) 参数决定,自由度越大,分布越平缓。 参数 卡方分布用两个参数来…...

音视频开发13 FFmpeg 音频 相关格式分析 -- AAC ADTS格式分析
这一节,我们学习常用的音频的格式 AAC,重点是掌握 AAC的传输格式 ADTS 头部的信息,目的是 : 当音频数据有问题的时候,如果是AAC的编码,在分析 头部信息的时候能够根据头部信息 判断问题是否出现在 头部。 A…...

周三晚19:00 | 数据资源入表案例拆解,他们如何应对入表难点?
数据资源入表的具体场景是怎样的?如何应对数据资源入表难点? 6月5日,即周三晚19:00,讲师-星光数智首席数据架构师 魏战松将继续带来关于《数据要素资产运营》的主题直播,为大家拆解数据资源入表的具体案例。 累计77…...

树的知识总结
一:树的基本术语(只写了查漏的部分 1 双亲:就是父节点 2 层序编号 3 有序无序树 4 森林 二:逻辑结构上与线性结构的比较 三:树的存储结构 ①双亲表示节点法:...

工业安全智勇较量,赛宁网安工业靶场决胜工业网络攻防对抗新战场
2024年1月30日,工信部发布《工业控制系统网络安全防护指南》(工信部网安〔2024〕14号),围绕安全管理、技术防护、安全运营、责任落实四方面提出安全防护要求,强调聚焦安全薄弱关键环节,强化技术应对策略&am…...

一种一维时间序列信号的广义小波变换方法(MATLAB)
地震波在含油气介质中传播时,其高频分量往往比低频分量衰减更快。据此,地震波的高频分量和低频分量之间的差异值可以用于分析含油气衰减位置,从而间接指示出含油气储层。对于时频域中的地震波衰减分析,一般地,利用地震…...
【GIC400】——驱动代码实现
文章目录 驱动代码实现IRQ 中断处理GIC 驱动GIC 使用使用示例系列文章 【ARMv7-A】——异常与中断 【ARMv7-A】——异常中断处理概述 【ARMv7-A】——进入和退出异常中断的过程 【GIC400】——PLIC,NVIC 和 GIC 中断对比 【GIC400】——GIC 简介 【GIC400】——GIC 相关的 CP1…...
如何在 Vue 组件中正确地使用 data 函数?
在 Vue 组件中正确使用 data 函数有以下几点需要注意: 返回一个对象: data 函数必须返回一个对象,这个对象包含了组件实例需要用到的所有数据属性。export default {data() {return {message: Hello, Vue!,count: 0}} }不要使用箭头函数: data 函数不应该使用箭头函数 () >…...
.Net 基于MiniExcel的导入功能接口示例
/// <summary>/// 导入/// </summary>/// <param name"formFile"></param>/// <returns></returns>[HttpPost("Import")]public async Task<ExecResult> Import(IFormFile formFile){try{if (formFile null) t…...

流量焦虑?别担心,Xinstall一站式App推广解决方案来了!
在移动互联网时代,App已经成为人们日常生活中不可或缺的一部分。然而,对于众多开发者来说,如何有效地推广自己的App,吸引更多的用户,却是一个不小的挑战。今天,我们将为大家介绍一款强大的App推广工具——X…...

降薪潮要开始了么?
互联网要全面迎来降薪潮了么,最近这个观念一直冲击着我 起因就是,前一段一位朋友降薪40%拿到了offer;还有一位金融机构的人力资源负责人朋友告诉我,最近来的很多互联网人都是降薪来的,普遍降30-50%不等 我就在想&…...

网络服务DHCP的安装
DHCP的安装 检查并且安装dhcp有关软件包 rpm -qc dhcp #检查是否存在dhcp yum install -y dhcp #进行yum安装查看系统的配置文件 切换到对应目录查看相关文件配置,发现是空目录。 将官方提供的example复制到原配置文件中 cp /usr/share/doc/dhcp-4.2.5/dhcpd.…...
SELinux:安全增强型Linux
SELinux:安全增强型Linux 作用: 可以保护linux系统的安全为用户分配最小的权限 状态: Enforcing:强制保护Permissive:宽松状态Disabled:禁用 为了安全性考虑,希望SELinux设置为Enforcing状态…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...