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状态…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...