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 位置的元素设为 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)

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AI赋能】香橙派OrangePi AIpro初体验

【AI赋能】香橙派OrangePi AIpro初体验 1、初识香橙派1.1、仪式感开箱1.2、OrangePi AIpro(8T)介绍 2、上电开机2.1、开机2.2、串口调试2.2.1 两种方式登录2.2.2 相关信息 2.3、启动系统2.4、网络配置 3、连接摄像头4、目标检测4.1、Jupyter Lab模式4.2、 目标检测测试4.2.1 视…

花钱学谢宁DOE培训,投入产出比到底如何?

在当今这个快速发展的时代&#xff0c;无论是职场人士还是创业者&#xff0c;都渴望通过不断学习来提升自我能力&#xff0c;以便在竞争激烈的市场中脱颖而出。其中&#xff0c;谢宁DOE培训因其独特的理念和方法&#xff0c;吸引了众多求学者的目光。然而&#xff0c;面对不菲的…

多条文本转二维码怎么做?一键批量建码的使用技巧

怎么快速的制作多条文本信息的二维码&#xff1f;随着二维码的广泛使用&#xff0c;现在很多内容都可以通过生成二维码扫码的方式来获取信息&#xff0c;其他文本二维码就是比较常用的一种类型。那么当需要将多条不同的文本内容每条单独生成二维码时&#xff0c;有什么方法可以…

如何借VR之手,让展厅互动更精彩?

VR虚拟现实技术以其卓越的沉浸式体验为特点&#xff0c;引领用户踏入一个全新的虚拟世界&#xff0c;正因如此&#xff0c;它开始被广泛应用于展厅、商业等多个领域。那么&#xff0c;今天&#xff0c;让我们就来了解一下这种技术是如何为展厅带来精彩互动体验的吧&#xff01;…

Hudi之数据读写探究

Hudi之数据读写深入探究 1. Hudi数据写入 1-1. 写操作 Hudi数据湖中的数据更新、插入和删除操作&#xff0c;是一个基于Apache Hadoop的库&#xff0c;为数据湖提供了一种有效的方法来处理更新和增量数据&#xff0c;并支持基于时间的快照和增量数据处理。Hudi支持三种主要的…

可道云网盘的URL链接能干什么?小白必看的teamOS使用技巧

在繁复的工作日常里&#xff0c;我们每天都在与各种文件和资料打交道。由于文件夹太多&#xff0c;常常会陷入那种死活找不到想要的文件的困境中。 比如询问同事&#xff0c;合同模板在哪&#xff0c;直接发微信当然是很快的&#xff0c;但是事后想归档总是格外麻烦。比如&…

英飞凌24GHz毫米波雷达-BGT24LTR11N16家用机器人应用

BGT24LTR11N16基础描述&#xff1a; 关于BGT24LTR11N16&#xff0c;它是一款用于信号生成和接收的硅锗雷达MMlC&#xff0c;工作频率为24.00GHz至24.25GHz ISM频段。它基于24GHz基本电压控制振荡器&#xff08;VCO&#xff09;。 这颗芯片是属于1T1R&#xff0c;也就是一发一收…

10年老运营人吐血整理,给新媒体运营人的20条建议!沈阳新媒体运营培训

对于企业&#xff0c;在新媒体平台开设官方账号应该是已经成为标配。不仅是对企业新媒体运营需求量提高&#xff0c;新媒体人的薪资也是水涨船高。 另外值得注意的是&#xff0c;企业对资深新媒体运营人才尤为重视&#xff0c;这表现在他们不惜重金招聘高薪新媒体运营人才&…

Android Studio中xml预览不显示问题解决办法

具体表现&#xff1a; Android Studio的XML中可以看到视图的相对位置结构&#xff0c;但是看不到具体的模样&#xff0c;全黑&#xff0c;等于半摸黑调UI&#xff08;由于我已经修好了所以没有截图&#xff09;。不是所有的项目都会这样&#xff0c;一部分项目是正常的。 或许…

OrangePi_Kunpeng_Pro开发板测验——性能巨人

文章目录 &#x1f4d1;前言一、开箱初体验的愉悦二、产品规格概述三、前置工作四、性能测试4.1 CPU 性能测试4.1.1 单线程 CPU 测试4.1.2 多线程 CPU 测试 4.2 内存性能测试4.2.1 内存读写性能测试4.2.2 高负载内存测试 4.3 I/O 性能测试4.4 网络性能测试4.5 测试小结4.5.1 CP…

跨域的解决方案

1. 计算机更改跨域 1.C盘->Windows->System32->drivers->etc 2.修改hosts 文件2. Chrome浏览器的跨域设置 操作步骤&#xff1a;1.打开我的电脑——C盘 新建一个文件夹&#xff0c;命名为MyChromeDevUserData2.右键——Chrome——快捷方式——目标&#xff0c;在…

使用python绘制一个五颜六色的爱心

使用python绘制一个五颜六色的爱心 介绍效果代码 介绍 使用numpy与matplotlib绘制一个七彩爱心&#xff01; 效果 代码 import numpy as np import matplotlib.pyplot as plt# Heart shape function def heart_shape(t):x 16 * np.sin(t)**3y 13 * np.cos(t) - 5 * np.cos…

高级软件工程师带你解决MySQL死锁问题Deadlock found when trying to get lock实战案例全网唯一

高级软件工程师带你解决MySQL死锁问题Deadlock found when trying to get lock实战 前言 笔者我实际工作中&#xff0c;经常遇到mysql数据库死锁问题&#xff01;CSDN上面也有很多大神刨析解决方法&#xff01; 我在实际工作中的MySQL数据库架构很复杂&#xff0c;又涉及到主…

「异步魔法:Python数据库交互的革命」(一)

Hi&#xff0c;我是阿佑&#xff0c;今天将和大家一块打开异步魔法的大门&#xff0c;进入Python异步编程的神秘领域&#xff0c;学习如何同时施展多个咒语而不需等待。了解asyncio的魔力&#xff0c;掌握Async SQLAlchemy和Tortoise-ORM的秘密&#xff0c;让你的数据库操作快如…

Linux新增磁盘挂载分区

1. 查看磁盘分区名称 lsblk 可见&#xff0c;新增的分区为 sdb 2.格式化磁盘 mkfs.xfs -f /dev/sdb 3.挂在磁盘到 /ocean目录&#xff0c;挂在前先创建空目录 /ocean mkdir /oceanmount /dev/sdb /ocean 执行后&#xff0c;可用 df -h 查看分区是否成功 4.持久化磁盘分区&a…

如何让物理服务器可以运行多个虚拟机:VMware ESXi系统安装-详细介绍

目录 一、虚拟机&#xff08;比如VMware ESXi上的虚拟机&#xff09;及其优势 &#xff08;一&#xff09;虚拟机 &#xff08;二&#xff09;虚拟机应用和优势 1、硬件资源利用率提升 2、灵活性和可扩展性 3、高可用性 4、简化管理 5、绿色节能 6、快速响应业务需求 …

应用案例|精密制造中使用复合机器人得到显著提升

精密制造行业对设备的精度、稳定性和效率要求极高&#xff0c;而复合机器人凭借其多功能性、高度灵活性和精准控制能力&#xff0c;正逐渐成为该领域的新宠。以下是一个富唯智能复合机器人在精密制造中的应用案例。 案例背景 某知名汽车零部件制造企业&#xff0c;专注于生产…

【好书分享第十三期】AI数据处理实战108招:ChatGPT+Excel+VBA

文章目录 一、内容介绍二、内页插图三、作者简介四、前言/序言五、目录 一、内容介绍 《AI数据处理实战108招&#xff1a;ChatGPTExcelVBA》通过7个专题内容、108个实用技巧&#xff0c;讲解了如何运用ChatGPT结合办公软件Excel和VBA代码实现AI办公智能化、高效化。随书附赠了…

基于微信小程序开发的一款 高颜值在线答题刷题考试程序

大家好&#xff0c;我是兔兔。今天给大家分享的内容是&#xff0c;兔兔答题模板三的发布。 兔兔答题模板三是一款基于uniapp开发&#xff0c;后端使用PHP&#xff0c;前端使用图鸟UI的微信答题小程序应用程序。相必兔兔答题模板一和兔兔答题模板二&#xff0c;进行了系统架构的…

《Ai企业知识库》rasa-rasa Core核心-认知理解以及配置文件应用

阿丹&#xff1a; 其实在整个rasa中的关键元素和关键的核心在前面多多少少也涉及到了很多&#xff0c;这里就是开始涉及到了rasa的训练核心core。 Rasa Core: Rasa Core 是Rasa框架中的一个组件&#xff0c;它负责处理对话管理部分&#xff0c;即决定对话流程中机器人的下一步…