顺序表详解(Java)

目录

顺序表

初始化

方法实现

1> display 遍历(简单)

2> isFull 是否为满

3> size 顺序表的大小

 4> add 增加在最后位置(考虑是否满了) (难)

5> add 增加到指定位置(是否为满)

6> isEmpty 是否为空

7> contain  是否包含某个元素 (简单)

8> indexOf 查找某个位置的元素 

 9> get 获取 pos 位置的元素

10> set 给 pos 位置的元素设为 value 

11> remove 移除某个数据

12> clear 清空顺序表

如何使用

小结


线性表定义: 

是 n 个具有相同特性的数据元素的有限序列.线性表示一种在实际中广泛使用的数据结构, 常见的线性表: 顺序表. 链表. 栈. 队列.

线性表在逻辑上是线性结构, 但在物理结构上并不一定是连续的. 线性表在物理上存储时, 通常以数组和链式结构的形式存储

顺序表

顺序表是一个动态扩容的数组.

我们来实现一个顺序表, 需要通过这个数组写一些方法实现各种功能.

初始化

先来给顺序表创建一个数组.

    public static final int DEFAULT_SIZE = 10;
    public int[] elem;
    public int usedSize = 0;
    public MyArrayList() {
        this.elem = new int[DEFAULT_SIZE];
    }

 分配一个数组, usedSize 表示这个数组初始时里面0个数据, DEFAULT_SIZE 表示数组默认大小为10.我们也可以自己创建顺序表时来指定数组的默认大小, 通过构造函数传参来实现.

    public MyArrayList(int size) {
        this.elem = new int[size];
    }

方法实现

如何实现各种功能, 先来实现一个接口, 通过这个接口来说明我们想要实现的功能:

package myList;

public interface IList {
    // 新增元素,默认在数组最后新增
    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 myList;

public class MyArrayList implements IList{
    public static final int DEFAULT_SIZE = 10;
    public int[] elem;
    public int usedSize = 0;
    public MyArrayList() {
        this.elem = new int[DEFAULT_SIZE];
    }
    public MyArrayList(int size) {
        this.elem = new int[size];
    }

    @Override
    public void add(int data) {

    }

    @Override
    public void add(int pos, int data) {

    }

    @Override
    public boolean contains(int toFind) {
        return false;
    }

    @Override
    public int indexOf(int toFind) {
        return 0;
    }

    @Override
    public int get(int pos) {
        return 0;
    }

    @Override
    public void set(int pos, int value) {

    }

    @Override
    public void remove(int toRemove) {

    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public void clear() {

    }

    @Override
    public void display() {

    }

    @Override
    public boolean isFull() {
        return false;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }
}

1> display 遍历(简单)

    @Override
    public void display() {
        for(int i = 0; i < this.usedSize; i++) {
            System.out.println(this.elem[i]+ " ");
        }
        System.out.println();
    }

2> isFull 是否为满

    @Override
    public boolean isFull() {
        return this.usedSize == elem.length;
    }

3> size 顺序表的大小

    @Override
    public int size() {
        return this.usedSize;
    }

 4> add 增加在最后位置(考虑是否满了) ()

注意: 满了就扩容: 怎么扩容? 使用 copyOf 方法.

    @Override
    public void add(int data) {
        if(isFull()) {
            elem = Arrays.copyOf(elem, 2*elem.length);
        }
        this.elem[this.usedSize] = data;
        usedSize++;
    }

5> add 增加到指定位置(是否为满)

注意: 看放的位置是否合法, 不能是负数或者太靠后不连贯了.

解决方法: 写一个方法来检查位置是否合法, 不合法的话抛出异常

此处的异常是自定义异常

package myList;

public class PosIllegality extends Exception {
    public PosIllegality(String msg) {
        super(msg);
    }
}
    private void checkPosOnAdd(int pos) throws PosIllegality {
        if(pos < 0 || pos > usedSize) {
            System.out.println("位置不合法");
            throw new PosIllegality("插入元素下标异常: " + pos);
        }
    }

代码实现:  

    @Override
    public void add(int pos, int data) {
        try {
            checkPosOnAdd(pos);
        }catch (PosIllegality e) {
            e.printStackTrace();
            return;
        }
        if(isFull()) {
            elem = Arrays.copyOf(elem, 2*elem.length);
        }
        for (int i = usedSize-1; i >= pos; i--) {
            elem[i+1] = elem[i];
        }
        elem[pos] = data;
        usedSize++;
    }

步骤:

1> 检查位置合法性

2> 检查是否数组满了

3> 开始进行位移: 从最后一个有效的数据开始往后移动, 当i< pos 时结束, 存放元素到 pos位置, usedSize++

6> isEmpty 是否为空

    @Override
    public boolean isEmpty() {
        return this.usedSize == 0;
    }

7> contain  是否包含某个元素 (简单)

注意: 看是否为空

    @Override
    public boolean contains(int toFind) {
        if(isEmpty()) {
            return false;
        }
        for(int i = 0; i < this.usedSize; i++) {
            if(toFind == elem[i]) {
                return true;
            }
        }
        return false;
    }

8> indexOf 查找某个位置的元素 

注意: 看是否为空

    @Override
    public int indexOf(int toFind) {
        if(isEmpty()) {
            return -1;
        }
        for(int i = 0; i < this.usedSize; i++) {
            if(toFind == elem[i]) {
                return i;
            }
        }
        return -1;
    }

9> get 获取 pos 位置的元素

注意: 判断位置是否合法, 其中的异常是自定义异常

package myList;

public class MyArrayListEmpty extends Exception {
    public MyArrayListEmpty(String msg) {
        super(msg);
    }
}
package myList;

public class PosIllegality extends Exception {
    public PosIllegality(String msg) {
        super(msg);
    }
}

    @Override
    public int get(int pos) throws MyArrayListEmpty {
        try {
            checkPosOnGet(pos);
        }catch (PosIllegality e) {
            e.printStackTrace();
            return -1;
        }
        if(isEmpty()) {
            throw new MyArrayListEmpty("获取指定下标元素时, 顺序表为空!");
        }
        return elem[pos];
    }
    private void checkPosOnGet(int pos) throws PosIllegality {
        if(pos < 0 || pos > usedSize) {
            System.out.println("不合法");
            throw new PosIllegality("获取指定下标的元素异常: " + pos);
        }
    }

10> set 给 pos 位置的元素设为 value 

注意:  pos 位置是否合法

package myList;

public class PosIllegality extends Exception {
    public PosIllegality(String msg) {
        super(msg);
    }
}
    @Override
    public void set(int pos, int value) {
        try {
            checkPosOnSet(pos);
        } catch (PosIllegality e) {
            throw new RuntimeException(e);
        }
        elem[pos] = value;
    }
    private void checkPosOnSet(int pos) throws PosIllegality {
        if(pos < 0 || pos > usedSize) {
            System.out.println("不合法");
            throw new PosIllegality("获取指定下标的元素异常: " + pos);
        }
    }

11> remove 移除某个数据

注意: 看是否有这个数据.没有的话可以抛出异常.有的话就依次覆盖前一个数据

    @Override
    public void remove(int toRemove) {
        int index = indexOf(toRemove);
        if(index == -1) {
            System.out.println("没有找到这个数字!");
            return ;
        }
        for(int i = index; i < this.usedSize-1; i++) {
            elem[i] = elem[i+1];
        }
        usedSize--;
    }

12> clear 清空顺序表

最简单的一种方式

    @Override
    public void clear() {
        this.usedSize = 0;
    }

当里面的数据时引用数据类型时需要释放内存

    @Override
    public void clear() {
        for (int i = 0; i < usedSize; i++) {
            elem[i] = null;
        }
        this.usedSize = 0;
    }

如何使用

可以通过 main 函数调用这个类中方法

package myList;

/**
 * 类的使用者
 */
public class Test {
    public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.display();
    }
}

小结

当添加元素或者删除元素时 注意: usedSize++ 或者 usedSize--

加入和删除 注意实现的过程.

注意下标不合法等异常

  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值