数据结构——数组(JAVA)

实现动态数组

在数据结构中,有一种数据结构叫数组。在很多人眼中数组很简单,不就是int[] num = new int[10];嘛
如果这样想的小盆友就答错特错了。
先上代码吧,这是动态数组实现的实现


/**
 * Created by XiaoXian on 2020/5/18.
 */
public class Array<E> {

    private E[] data;
    //数组游标,一开始指向0
    private int size;

    /**
     * 构造函数,传入数组的容量capacity构造Array
     * @param capacity
     */
    public Array(int capacity) {
        data = (E[])new Object[capacity];
        size = 0;
    }

    /**
     * 无参数的构造函数,默认数组的容量capacity=10
     */
    public Array() {
        this(10);
    }

    /**
     * 返回数组是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 获取数组中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    /**
     * 获取数组的容量
     * @return
     */
    public int getCapacity(){
        return data.length;
    }

    /**
     * 在index索引的位置插入一个新元素e
     * @param index
     * @param e
     */
    public void add(int index,E e){

        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add失败,index < 0 || index > size");
        }

        if (size == data.length){
            resize(2 * data.length);
        }

        for (int i=size-1;i>=index;i--){
            data[i+1]=data[i];
        }
        data[index]=e;
        size++;
    }

    /**
     * 向所有元素后添加一个新元素
     * @param e
     */
    public void addLast(E e){
        add(size,e);
    }

    /**
     * 在所有元素前添加一个新元素
     * @param e
     */
    public void addFirst(E e){
        add(0,e);
    }

    /**
     * 获取index索引位置的元素
     * @param index
     * @return
     */
    public E get(int index){
        if (index <0 || index >=size){
            throw new IllegalArgumentException("查询失败,索引越界");
        }
        return data[index];
    }

    /**
     * 修改index索引位置的元素为e
     * @param index
     * @param e
     */
    public void set(int index,E e){
        if (index <0 || index >=size){
            throw new IllegalArgumentException("查询失败,索引越界");
        }
        data[index]=e;
    }

    /**
     * 查找数组中是否有元素e
     * @param e
     * @return
     */
    public boolean contains(E e){
        for (int i=0;i<size;i++){
            if (data[i]==e){
                return true;
            }
        }
        return false;
    }

    /**
     * 查找数组中元素e所在的索引,如果不存在元素e,则返回-1
     * @param e
     * @return
     */
    public int find(E e){
        for (int i=0;i<size;i++){
            if (data[i]==e){
                return i;
            }
        }
        return -1;
    }

    /**
     * 从数组中删除index位置的元素, 返回删除的元素
     * @param index
     * @return
     */
    public E remove(int index){
        if (index < 0 || index >=size){
            throw new IllegalArgumentException("删除失败,索引越界");
        }
        E ret = data[index];
        for (int i=index+1;i<size;i++){
            data[i-1]=data[i];
        }
        size--;
        data[size]=null;//可有可无
        if (size == data.length/4 && data.length / 2 != 0){
            resize(data.length/2);
        }
        return ret;
    }

    /**
     *从数组中删除元素e
     * @param e
     */
    public void removeElement(E e){
        int index = find(e);
        if (index != -1){
             remove(index);
        }
    }

    /**
     * 从数组中删除第一个元素, 返回删除的元素
     * @return
     */
    public E removeFirst(){
        return remove(0);
    }

    /**
     * 从数组中删除最后一个元素, 返回删除的元素
     * @return
     */
    public E removeLast(){
        return remove(size-1);
    }

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array的size:%d  capacity:%d\n",size,data.length));
        res.append("[");
        for (int i=0;i<size;i++){
            res.append(data[i]);
            if (i != size-1){
                res.append(",");
            }
        }
        res.append("]");
        return res.toString();
    }

    /**
     * 开辟新的空间,实现动态数组
     * @param newCapacity
     */
    private void resize(int newCapacity){
        E[] newData = (E[])new Object[newCapacity];
        for (int i=0;i<size;i++){
            newData[i]=data[i];
        }
        data = newData;
    }
}

这是实现动态数组的核心思想
在这里插入图片描述
数组扩容
在这里插入图片描述
数组缩小空间
在这里插入图片描述
在这里是不是有小盆友发现,为什么不是size == data.length/2 的时候缩容呢?
其实,这里主要是防止复杂度的震荡

考虑一种情况,如果现在capacity(数组容量)=10,size=10。当执行add添加元素的方法的时候,数组会进行扩容,capacity=20,size=11。然后我有执行remove删除元素方法,capacity =20,size=10。如果我们规定执行缩容的条件是size == data.length/2 ,那他就会执行缩容方法。这个时候又执行添加方法,执行删除方法,那这个resize()方法就会不断执行,不断执行for循环的赋值工作和新增数组对象,这样会很影响效率,因此我们要实行慢减思想,等到size == data.length/4,再缩容。

在这里插入图片描述

其实,以上的代码和List中的ArrayList源码实现的思想很像,大家可以看看源码。
今天的分享到这里,希望大家点个赞

别让一次欲言又止,带来一生遗憾。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值