java实现自己的动态数组

1 前言

利用java语言,仿照ArrayList实现自己的动态数组,以加深对动态数组的理解

2 动态数组 Array实现

/**
 * @author Created by qiyei2015 on 2018/4/27.
 * @version: 1.0
 * @email: 1273482124@qq.com
 * @description: 动态数组
 */
public class Array<E> {

    /**
     * 默认容量大小
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     * 保存元素的数组
     */
    private E[] element;
    /**
     * 元素个数大小
     */
    private int size;

    /**
     * 容量大小
     */
    private int capacity;

    /**
     * 默认构造函数
     */
    public Array() {
        this(DEFAULT_CAPACITY);
    }

    /**
     * 构造方法
     * @param capacity
     */
    public Array(int capacity){
        this.capacity = capacity;
        size = 0;
        element = (E[])new Object[capacity];
    }

    /**
     * 添加元素
     * @param t
     */
    public void addFirst(E t){
        add(0,t);
    }

    /**
     * 添加元素
     * @param t
     */
    public void addLast(E t){
        add(size,t);
    }

    /**
     *
     * @param index
     * @param t
     */
    public void add(int index,E t){
        if (index < 0 || index > size){
            throw new IllegalArgumentException("index illegal");
        }
        if (size == capacity){
            resize(2 * capacity);
        }
        //右移一位
        for (int i = size - 1; i >= index ;i--){
            element[i+1] = element[i];
        }
        element[index] = t;
        size++;
    }

    /**
     * 删除第0个
     * @return
     */
    public E removeFirst(){
        return remove(0);
    }

    /**
     * 删除末尾元素
     */
    public E removeLast(){
        return remove(size - 1);
    }

    /**
     * 删除元素
     * @param index
     */
    public E remove(int index){
        if (index < 0 || index >= size){
            throw new IllegalArgumentException("index illegal");
        }
        E e = element[index];
        //左移一位
        for (int i = index;i < size;i++){
            element[i] = element[i + 1];
        }
        size--;
        element[size] = null;
        //缩容到一半,防止震荡
        if ((size == capacity / 4) && ((capacity / 2) != 0)){
            resize(capacity / 2);
        }
        return e;
    }


    public E getFirst(){
        return get(0);
    }

    public E getLast(){
        return get(size - 1);
    }

    /**
     * 获取该元素
     * @param index
     * @return
     */
    public E get(int index){
        if (index < 0 || index >= size){
            throw new IllegalArgumentException("index illegal");
        }
        return element[index];
    }

    /**
     * 修改
     * @param index
     * @param e
     */
    public void set(int index,E e){
        if (index < 0 || index >= size){
            throw new IllegalArgumentException("index illegal");
        }
        element[index] = e;
    }

    /**
     * 判断是否为null
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 返回大小
     * @return
     */
    public int size(){
        return size;
    }

    /**
     * 容量大小
     * @return
     */
    public int getCapacity(){
        return capacity;
    }

    /**
     * 调整数组大小
     * @param n
     */
    private void resize(int n) {
        E[] newData = (E[]) new Object[n];

        //拷贝元素
        System.arraycopy(element,0,newData,0,size);
        element = newData;
        capacity = element.length;
    }

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

3 时间复杂度分析

1 添加
add(index,e) O(n)
addLast(e) O(1)
addFirst(e) O(n)

2 删除
remove(index) O(n)
removeLast() O(1)
removeFirst() O(n)

3 修改
set(index,e) O(1)

4 查询
get(index) O(1)
contains(e) O(n)
find(e) O(n)

4 均摊分析和复杂度震荡

1 resize均摊分析
n+1 次addlast操作,触发resize,总共进行了2n+1 次基本操作,因此每次addlast平均进行了2次基本操作
时间复杂度是o(1)
2 复杂度震荡
但是同时看addlast和removelast可能出现复杂度震荡,在临界点add了又remove,
出现原因 removelast时resize过于着急,
解决方案 lazy懒惰策略
缩容时判断当前占用是四分之一时才缩容,并且只缩容为1/2

另外可以参考ArrayList的缩容策略,每次删除后,移动数组后,将elementData[–size] = null; 这样数组长度也就减1了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值