[1] 顺序表实现

一、引入顺序表

提出问题:

顺序表底层是一个数组,为什么不是直接操作数组就好了,还要单独写一个类,说底层是数组呢??

因为顺序表可以有更多的操作:

比如一个数组,我们没有办法知道,里面有几个有效的数据。

 二、顺序表的实现

1、顺序表所具备的方法

public class MyArraylist {
    public int[] elem;
    public int usedSize;
    public MyArraylist(){
        this.elem = new int[10];
    }
    // 打印顺序表
    public void display() {

    }
    // 新增元素,默认在数组最后新增
    public void add(int data) {

    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        
    }
    // 判定是否包含某个元素
    public boolean contains(int toFind) { 
        return true;
    }
    // 查找某个元素对应的位置
    public int indexOf(int toFind) { 
        return -1;
    }
    // 获取 pos 位置的元素
    public int get(int pos) { 
        return -1; 
    }
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        
    }
    //删除第一次出现的关键字key
    public void remove(int key) { 
        
    }
    // 获取顺序表长度
    public int size() { 
        return 0; 
    }
    // 清空顺序表
    public void clear() {
        
    }
}

2、实现各个方法

(1)打印顺序表

    // 打印顺序表
    /*
    根据usedSize判断,不能根据数组长度判断
     */
    public void display() {
        for (int i = 0; i < usedSize; i++) {
            System.out.print(this.elem[i]+" ");
        }
    }

(2)新增元素,默认在数组最后新增

 /*
       判断当前顺序表是不是满的
       true:满    false:空
     */
    public boolean isFull(){
//        if(this.usedSize == this.elem.length){
//            return true;
//        }else return false;
        //优化
        return this.usedSize == this.elem.length;
    }
    // 新增元素,默认在数组最后新增
    /*
       需要判断当前数组是否满了,为此写一个isFull方法
       1、不满进行插入
       2、满的进行扩容
     */
    public void add(int data) {
        //扩容
        if(isFull()){
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        this.elem[this.usedSize] =data;
        usedSize++;
    }

 (3)在 pos 位置新增元素

 // 在 pos 位置新增元素
    /*
      1、在数据结构当中,每次存储元素的时候,一定要有一个前驱信息,即插入数据不能跳着插
      2、注意事项:
        2.1 判断pos位置的合法性
        2.2 判断顺序表是否已满
        2.3 插入数据 -> 1.挪动数据 2.插入数据
    */
    private boolean checkPosInAdd(int pos){ //封装起来,使得程序更安全
        if(pos <0 || pos >this.usedSize){
            return false;
        }
        return true;
    }
    public void add(int pos, int data) {
        //判断下标是否合法
        if(!checkPosInAdd(pos)){
            throw new MyArrayListIndexIllegal("pos位置不合法");
        }
        //判断是否满的
        if(isFull()){
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //挪数据
        for (int i = this.usedSize-1; i <=pos ; i--) {
            this.elem[i+1] = this.elem[i];
        }
        this.elem[pos] = data;
        usedSize++;
    }

自定义异常:

public class MyArrayListIndexIllegal extends RuntimeException{
    public MyArrayListIndexIllegal(){

    }
    public MyArrayListIndexIllegal(String message){
        super(message);
    }
}

(4)判定是否包含某个元素

 // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(elem[i] == toFind){
                return true;
            }
        }
        return false;
    }

(5)查找某个元素对应的位置

如果数组存放的是类类型, 如Person person = new Person();

此时需要重写equals方法

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(elem[i] == toFind){
                return i;
            }
        }
        return -1;
    }

(6) 获取 pos 位置的元素

    // 获取 pos 位置的元素
    private boolean checkPosInGet(int pos){
        if(pos<0 || pos>=this.usedSize){
            return false;
        }return true;
    }
    private boolean isEmpty(){
        return this.usedSize == 0;
    }
    public int get(int pos) {
        if(!checkPosInGet(pos)){
            throw new MyArrayListIndexIllegal("获取pos下标时,位置不合法");
        }
        if(isEmpty()){
            throw new MyArrayListEmptyException("获取元素的时候,数组为空");
        }
        return this.elem[pos];
    }

自定义异常:

public class MyArrayListEmptyException extends RuntimeException{
    public MyArrayListEmptyException(){

    }
    public MyArrayListEmptyException(String message){
        super(message);
    }
}

(7) 给 pos 位置的元素设为 value

    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        if(!checkPosInGet(pos)){
            throw new MyArrayListIndexIllegal("获取pos下标时,位置不合法");
        }
        this.elem[pos] =value;
    }

(8)删除第一次出现的关键字key

    //删除第一次出现的关键字key
    /*
    1.顺序表不为空
    2。顺序表有所要删除的元素key
    3.找到key的下标i
    4.将elem[i+1]的值覆盖elem[i]的值 即elem[i] = elem[i+1],usedSize--;
    5.注意:如果是引用类型的数组,就需要把elem[i] = null;
     */
    public void remove(int key) {
        if(isEmpty()){
            throw new MyArrayListEmptyException("顺序表为空,不能删除");
        }
        int index = indexOf(key);
        if(index > 0){
            for (int i = index; i < usedSize-1; i++) {
                elem[i] = elem[i+1];
            }
            System.out.println("删除完成");
            this.usedSize--;
        }else {
            System.out.println("不存在你要删除的对象");
        }
    }

(9)获取顺序表长度

    // 获取顺序表长度
    public int size() {
        return this.usedSize;
    }

(10)清空顺序表

    // 清空顺序表
    public void clear() {
      this.usedSize = 0;
      /*
      如果是引用数据类型,需要一个一个置为空
      for (int i = 0; i < this.usedSize;i++) {
            elem[i] = null;
        }
        this.usedSize = 0;
       */
        /*
        或者直接把elem置为空,但这样太粗暴了,直接把elem回收了,就不能对elem进行操作了
           this.elem =null;
         */
    }

三、源码

_20230409 · benxiangsj/java learning - 码云 - 开源中国 (gitee.com)icon-default.png?t=N2N8https://gitee.com/benxiangsj/java-learning/tree/fe7ae6e425c4a0ed5bd886a923630e2293c90ff8/_20230409/

猜你喜欢

转载自blog.csdn.net/benxiangsj/article/details/130038639