JavaDS-学习数据结构之如果从零开始手搓顺序表,顺带学习自定义异常怎么用!

news2024/11/16 19:48:24

前言

笔者开始学习数据结构了,虽然笔者已经会用了,不管是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 位置的元素设为 value
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public 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;
    else
        return  false;
}
    @Override
    public boolean isEmpty()
    {
        return this.usedsize==0?true:false;
    }

 设置这两个功能说实话有的没必要,但是一定要考虑到严谨,这必须加上来,以防止越界,也可以引出如果使用自定义异常!

通过这两个重写方法,也可以衍生出一个被封装的方法

private  void checkcap()
{
    if(isfull())
    // 检测一下
    {
        myarray = Arrays.copyOf(myarray,myarray.length*2);
        // 扩容(两倍)
    }
}

 为什么我们这里用private?因为你作为使用者,你压根用不着.这也是一种没什么必要的严谨性吧.早点养成习惯也不是什么坏事.

部分核心功能

接下来来到我们的核心功能了,我们一个个来看

增加

    @Override
    public 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);
        }
    }   

 @Override
    public 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,没有异常,那就更好了,直接就可以扩容了,注意下标的边界就好了,没有难度.

得到指定位置的数据

    @Override
    public 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);
        }
    }

    @Override
    public void set(int pos, int value)
    {
        try {
           checkPosSet(pos);
        }
        catch (POSIllegal e)
        {
            e.printStackTrace();
            return ;
        }
        this.myarray[pos]=value;
    }

注意注意,这里和增加不同了,增加是可以在顺序表增加的,但是替换是不能在结尾替换的,因为你没有元素,你怎么替换?你告诉我.

获取指定位置元素

    @Override
    public 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 写法了

移除第一次出现的某元素

    @Override
    public 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

    @Override
    public int size()
    {
        return this.usedsize;
    }
    @Override
    public 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 位置的元素设为 value
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public 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;
    else
        return  false;
}
    @Override
    public 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();
}
    @Override
    public void add(int data)
    {
        checkcap();
            this.myarray[this.usedsize] =data;
            this.usedsize++;
    }
    @Override
    public 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++;
    }
    @Override
    public 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;
    }

      @Override
    public 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;
    }

    @Override
    public int get(int pos)
    {
        try {
            return this.myarray[pos];
        } catch (ArrayIndexOutOfBoundsException e)
        {
            e.printStackTrace();
            System.out.println("越界了,数组只有"+myarray.length+"这么大");
            System.out.println("请你看看自己是不是选择了负数或者大于数组大小的数");
           return  pos;
        }
    }
    @Override
    public void set(int pos, int value)
    {
        try {
           checkPosSet(pos);
        }
        catch (POSIllegal e)
        {
            e.printStackTrace();
            return ;
        }
        this.myarray[pos]=value;
    }
    @Override
    public 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--;
         }
    }
    @Override
    public int size()
    {
        return this.usedsize;
    }
    @Override
    public 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)

到这里我也写了快一个小时了,不知道有没有人可以看到啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

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

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

相关文章

wxPython Demo大全系列:ActivityIndicator控件分析

一、ActivityIndicator介绍 wx.ActivityIndicator 控件是 wxPython 中用于显示活动指示器的控件&#xff0c;通常用于指示程序正在执行某些后台任务或操作。它在用户界面中以动画的形式表现出活动状态&#xff0c;让用户知道应用程序正在进行处理而不是被挂起。 主要特点 可视…

Data Lakehouse:你的下一个数据仓库

作者&#xff1a;张友东 StarRocks TSC member/镜舟科技 CTO 数据分析是现代企业和组织决策过程中不可或缺的一部分&#xff0c;数据分析技术经过数十年的发展&#xff0c;需求场景从 BI 报表到数据探寻、实时预测、用户画像等不断丰富&#xff0c;技术架构经历从数据仓库、数据…

三方语言中调用, Go Energy GUI编译的dll动态链接库CEF

如何在其它编程语言中调用energy编译的dll动态链接库&#xff0c;以使用CEF 或 LCL库 Energy是Go语言基于LCL CEF开发的跨平台GUI框架, 具有很容易使用CEF 和 LCL控件库 interface 便利 示例链接 正文 为方便起见使用 python 调用 go energy 编译的dll 准备 系统&#x…

过去的六年,教会了我很多事

目录 过去六年的风风雨雨android缘起爱情缘灭顿悟收拾心情&#xff0c;再次启航面试阿里大起大落 如今时光&#xff0c;刺激且美好未来展望 过去六年的风风雨雨 android缘起 2018年&#xff0c;我从北京联合大学毕业&#xff0c;跟随着学长一起创业&#xff0c;从此开始了我的…

基于异构图的大规模微服务系统性能问题诊断

简介&#xff1a;本文介绍由南开大学、清华大学、腾讯、国家超级计算天津中心共同合作的论文&#xff1a;基于异构图的大规模微服务系统性能问题诊断。该论文已被IEEE Transactions on Services Computing期刊录用 论文标题&#xff1a;Diagnosing Performance Issues for Lar…

【计算机毕业设计】388微信小程序足球赛事及队伍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

解密网络流量监控:优化IT运维的利器

引言&#xff1a; 在当今数字化时代&#xff0c;网络流量监控是维护网络稳定与业务连续性的关键。作为一名资深网络工程师&#xff0c;我将分享一些关于网络流量监控的重要知识&#xff0c;并探讨如何在IT运维中运用这一工具优化网络性能&#xff0c;确保业务的顺畅进行。 1. 网…

微前端(无界)入门

主应用通过props给子应用传值 父子应用通过eventBus通信 通过路由同步实现记录子应用的路由状态 主应用 main.ts: import ./assets/main.cssimport { createApp } from vue import { createPinia } from pinia import WujieVue from wujie-vue3import App from ./App.vue impo…

dust3r部署踩坑全记录

目前dust3r是三维重建最新最好的技术&#xff0c;运用了ViT编码器、Transformer、注意力机制、回归等技术&#xff0c;无需相机参数标定。 但是我部署过程中有很多坑&#xff0c;记录一下。 1.OSError: CUDA_HOME environment variable is not set. Please set it to your CU…

sprongboot+vue 游泳馆管理系统

游泳馆管理系统 spring bootvue 主要有游泳课程预约、网上购票、教练预约、游泳器材管理、会员管理等功能&#xff1b; 1、管理员 登录、修改密码 购票管理&#xff1a;查看订单、删除订单、修改订单 教练管理&#xff1a;教练信息查询、修改 课程信息&#xff1a;增删改查课程…

【class19】人工智能初步---语音识别(5)

【class19】 上节课&#xff0c;我们学习了&#xff1a;语音识别模型的结构和原理&#xff0c;同时调用创建好的AipSpeech客户端实现了语音转文字功能。 本节课&#xff0c;我们将初识字幕&#xff0c;学习这些知识点&#xff1a;1. srt字幕 2. 获取时间数据 …

认识NoSql

SQL是结构化的&#xff0c;NoSql是非结构化的 SQL是关联的&#xff1a; Nosql是无关联的&#xff1a; SQL采用的是SQL查询&#xff1a; 语法固定&#xff0c;好处是&#xff1a;只要是关系型数据库&#xff08;Mysql,Oracle&#xff09;&#xff0c;都能够使用相同的语句进行查…

Re73 读论文:ULMFiT Universal Language Model Fine-tuning for Text Classification

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;Universal Language Model Fine-tuning for Text Classification 模型简称&#xff1a;ULMFiT 模型全名&#xff1a;Universal Language Model Fine-tuning ArXiv网址&#xff1a;https…

Three.js 入门介绍与环境搭建

Three.js 入门介绍与环境搭建 一、引言 Three.js 是一个强大的用于在网页上创建和展示 3D 图形的 JavaScript 库。艾斯视觉作为ui设计和前端开发服务商在这里很高兴能与你共同探讨学习&#xff1a;它使得开发者能够轻松地构建令人惊叹的 3D 场景和交互体验。在这篇文章中&…

Type ‘null‘ is not assignable to type ‘T‘. - ArkTSCheck

设置泛型将参数配置为 null 时抛出了如下异常: Type null is not assignable to type T. T could be instantiated with an arbitrary type which could be unrelated to null. <ArkTSCheck> 解决办法 在 null 后面添加 ! 即可,以表示该值不会为 null data: T null! 以…

python-web框架应用程序-Django环境搭建

python-web应用程序-Django环境搭建 一、Django入门 使用Django&#xff08;http://djangoproject.com/&#xff09;来开发一个名为“学习笔记”&#xff08;Learning Log&#xff09;的项目&#xff0c;这是一个在线日志系统&#xff0c;让你能够记录所学习的有关特定主题的知…

leetcode - 20.有效的括号(LinkedHashMap)

leetcode题目有效的括号&#xff0c;分类是easy&#xff0c;但是博主前前后后提交了几十次才通过&#xff0c;现在记录一下使用Java语言的写法。 题目链接: 20.有效的括号 题目描述&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&…

SAP 生产订单报工函数BAPI_PRODORDCONF_CREATE_TT不返回报错信息

最近财务一直反馈MES报工的数据都没有成本,然后去查看原因发现是财务当月的KP26的价格没有进行维护,导致没有收集到工单的报工成本。 但是在前台操作CO11 报工的时候,系统会给出报错的信息 但是我们在调用函数BAPI_PRODORDCONF_CREATE_TT的时候,系统并没有返回报错的信息…

Windows电脑高颜值桌面便利贴,便签怎么设置

在这个看颜值的时代&#xff0c;我们不仅在衣着打扮上追求时尚与美观&#xff0c;就连电脑桌面也不愿放过。一张唯美的壁纸&#xff0c;几款别致的小工具&#xff0c;总能让我们的工作空间焕发出不一样的光彩。如果你也热衷于打造高颜值的电脑桌面&#xff0c;那么&#xff0c;…

下一代 CI/CD:利用 Tekton 和 ArgoCD 实现云原生自动化

一、回顾目标 背景&#xff1a; ​ 部门业务上云&#xff0c;之前服务采用传统的部署方式&#xff0c;这种方式简单&#xff0c;但是不能为应用程序定义资源使用边界&#xff0c;很难合理地分配计算资源&#xff0c;而且程序之间容易产生影响。随着互联网时代的到来&#xff…