我与顺序表有个约会

今天来讲讲的数据结构初学中常见的一种——顺序表

当然我们来讲讲什么是顺序表先。

顺序表是属于线性表的一种。

那线性表又是什么呢?

线性表是一种逻辑上连续,但物理上(内存地址不一定连续)不一定连续。

而我们的顺序表呢是一种逻辑上连续,物理上也连续的结构。

既然这样的话,我们顺序表自然可以想到用数组作为底层来实现啦。

既然是一种数据结构,那我们来用java语言实现下基本的操作吧——增删查改

实现这些之前我们我们要创建一些文件先。

图中所示,创建了一个List接口和一个MyArrayList类。

那为啥创建这个List接口呢,是为了将我们的实现的方法放在里面,然后让这个MyArrayList接口来实现它。当然不创键这个接口也行,直接在MyArrayList类里面进行创建方法也是ok的。

那让我们先看看List接口中都有些什么方法吧:

public interface List {
    //将要写的方法放在这里实现
    void add(int data);//数据尾插
    void add(int pos,int data);//指定位置之前插入数据
    boolean FindIndex(int toFind);//查找是否包含此元素
    int IndexOf(int toFind);//查找某个元素对应的位置
    int get(int pos);//获取pos位置的元素
    void set(int pos,int value);//将pos位置的元素更新——>value
    void remove (int toRemove);//删除第一次出现的关键字key
    int size();//获取数组的长度
    void clear();//清空数组
    void display();//展示顺序表的元素
    boolean isFull();//数组是否满了
}

既然底层是数组实现的,那么我们怎么较快速的知道数组是否满了呢?这时候我们用一个变量usedsized来记录当前一个位置。

那就看看代码是咋样的吧。

public class MyArrayList implements List{
        int []arr;
        int usedSized;
        public MyArrayList(){
            this.arr=new int[10];
        }
}

这里呢我们写定数组的大小为10个元素。

那么数组基本的就结构创建完了。来实现下基本的方法吧。

比如增加功能,增加之前我得想一个细节问题——如果数组满了?我们咋办?那么肯定得扩容咯。

再来想下数组怎么判断是否为满的?

这样子的话我们先实现数组是否为满的这个方法:

为满判断:

 public boolean isFull() {
      //如何判断为满,当数组长度等于uesdSize
      return  usedSized==arr.length;
    }

接下来才可以增加元素进去。

增加数组元素:
 

public void add(int data) {
        if(isFull()){
            //首先判断数组是否满了,满了就要扩容
            arr= Arrays.copyOf(arr,2*arr.length);
        }
        //增添数据
        this.arr[usedSized]=data;
        usedSized++;
    }

不过我们得注意下,useSized得记得+1。

增加元素还有个方法呢,让我们玩点另外一个不同,在pos位置前增加一个元素。

pos位置前增元素

那么问题来了,pos位置这个位置合不合法呢?那肯定是不能保证的是吧,因为我们可以随便输入咯,所以我们得判断以下是否合法的,

那么不用简单的ifelse来判断。用一个异常来告诉我们pos是不合法的。

所以我们创建一个异常类:

public class PosNotLegalException extends RuntimeException {
    public PosNotLegalException(){

    }
    public PosNotLegalException(String error){
      super(error);
    }
    }

我们这个异常类得继承这个运行时异常,因为我们运行时才能确定这个pos是否合法的。

然后我们在add方法里再用try catch语句进行打印这个异常:
代码实现:

public void add(int pos, int data) {//在指定位置插入数据
           //判断pos是否合法
            try{
                checkPos(pos);
            }catch (PosNotLegalException e){
                e.printStackTrace();
            }
            //指定位置前插入元素
        for(int i=usedSized-1;i>=pos;i--){
            arr[i+1]=arr[i];
        }
        arr[pos]=data;
        usedSized++;
    }
public void checkPos(int pos)throws PosNotLegalException{
            if(pos<0||pos>usedSized){
                System.out.println("pos位置不合法!");
            }
    }

说明:怎么插入呢,先把pos和usedsized之间的元素往右移动,空出一个空格就可以插入元素。

值得注意的是,我们add方法在这里是进行方法的重载了的。

接下来我们实现另一个方法:
查找某个元素对应的位置:

先上代码再来说过程:

public int IndexOf(int toFind) {
            //查找对应元素的位置
        for(int i=0;i<usedSized;i++){
            if(arr[i]==toFind){
                return i;
            }
        }
        return -1;
    }

这个过程是挺简单的,用一个循环来遍历0--usedsized范围内。

如果我们数组的值等于这给定的tofind就返回下标。

与此类似的是另一个方法是:


查找是否包含此元素:
 

public boolean FindIndex(int toFind) {
            //寻找该元素是否存在
        for(int i=0;i<arr.length;i++){
            if(arr[i]==toFind){
                return true;
            }
        }
       return  false;
    }

逻辑简单这里就不多赘叙了。

接下来我们实现一个更简单的的方法:


获取pos位置的元素:


直接上代码: 

public int get(int pos) {
            //依旧是判断pos位置是否合法
        try{
            checkPos(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }

        return arr[pos];
    }

当然我们这里也是需要用一个异常处理来判断下pos位置知否合法的呢。

这些简单点的方法还有几个呢,那我们一起来处理它们吧。

获取数组长度:

public int size() {
            //获取数组的长度
        int count=0;
        for (int i=0;i<usedSized;i++){
            count++;
        }
        return count;
    }

方法呢用一个循环和一个计数器就好了。

打印数组:
 

 public void display() {
    //如何展示数组数据?遍历数组打印
        for(int i=0;i<usedSized;i++){
            int tmp=arr[i];
            System.out.print(tmp+" ");
        }
    }

前面写了增加和查找的方法,那么接下来写个改的方法吧。

更新元素:

先上代码:
 

public void set(int pos, int value) {
        //将pos元素设置相对应的值,依旧要判断是否合法
        try{
            checkPos(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }
        for(int i=0;i<arr.length;i++){
            if(i==pos){
                arr[i]=value;
                return;
            }
        }
    }

同样我们这里也需要判断下pos位置是否合法。

思路也是挺简单的,直接遍历数组。然后找到后,重新赋值。

接下来还有个有点小难的方法呢:


删除所提供的数字:

先上代码:

public void remove(int toRemove) {
            //删除第一次出现的关键字
        int pos = IndexOf(toRemove);
        if(pos == -1) {
            System.out.println("没有要删除的数字!");
            return;
        }
        for (int i = pos; i < usedSized-1; i++) {
            arr[i] = arr[i+1];
        }
        usedSized--;

    }

思路呢,也是蛮简单的,先将把toRmove传给 Indexof,然后这个方法找到在哪,然后在循环中,将pos--usedsized之间的元素中的后一个元素进行覆盖,这样呢就完成了删除。

最后一个方法就是清空数组:

清空数组:
 

 public void clear() {
            //两种办法,循环置为null、或者usedSized=0;
         usedSized=0;

    }

但这里是基本类型,赋值null是不行的。

至此,我们简易的顺序表已写完。

完!

  • 50
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值