zoukankan      html  css  js  c++  java
  • 【数据结构】手动实现基础数据结构_ArrayList

    学习数据结构,必不可少的就是手动实现它们,亲自动手做了,才可以真正理解。

     

    ArrayList,顾名思义,是用数组实现的链表,一个链表的基本功能可以说是增删查改,对于数组来说,查询、修改是非常容易的,直接通过数组的下标就可以完成,时间复杂度是常数级别的。而添加、删除就比较麻烦,为了保证数据的连续性,数组之间不可以有"空位"(即没有存放有效数据的空间),那么在添加删除时需要将数组移位,最好的情况是添加删除都在链表的末尾,时间复杂度为O(c),但最坏的情况是在链表的头部添加删除数据,时间复杂度为O(n),综合来算,时间复杂度为O(n)

     

    如下图,如果要删除a[3]的数据,那么删除之后,a[3]以后的数据都要向前移动一位,以保证数据的有效性,添加同理

     

    除了增删查改,还应该能获取到链表的大小、清空链表、判断链表是否为空等操作。此外,链表还应该具有自动扩容的功能,使用链表的人不需要操心链表的大小是否够用,若添加的数据超出了数组的容量,应自动扩容。

     

     

    添加数据:有两种方法,一是在链表末尾添加数据,二是在链表中插入数据,这两种实际上可以概括为在链表的某一个位置插入数据。在添加数据之前,首先要判断现有数据的大小是否超出了数组的容量,若超出,则需要扩容,否则插入数据。

     

    /**
     * 在链表末尾添加元素
     * 
     * @param e
     * @return
     */
    public boolean add(Object e) {
        // 判断是否需要扩容
        if(size == list.length){
            ensureCapacity();
        }
        list[size++] = e;
        return true;
    }
    
    /**
     * 在指定下标位置添加元素
     * 
     * @param e     要添加的元素
     * @param index 下标
     * @return
     */
    publicboolean add(Object e, int index) {
        // 下标越界,抛出异常
        if (index > size || index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        // 判断是否需要扩容
        if(size == list.length){
            ensureCapacity();
        }
        // 在末尾添加数据
        if (index == size) {
            return add(e);
        }
        for (int i = size - 1; i >= index; i--) {
            list[i + 1] = list[i];
        }
        list[index] = e;
        size++;
        return true;
    }    
    
    /**
     * 扩容
     */
    private void ensureCapacity() {
        Object[] newList = new Object[(int) (size + 0.5 * size)];
        // native方法,提高效率
        System.arraycopy(list, 0, newList, 0, list.length);
        list = newList;
        }
    }

    删除数据:与添加数据一样,也有两种方法,不带参数的方法默认删除链表最后一个数据,带参数的则删除参数指定的数据

    /**
     * 删除元素,参数为空则删除最后一个
     */
    public Object remove() {
        if(size <= 0) {
            return null;
        }
        Object o = get(size-1);
        size --;
        return o;
    }
    
    /**
     * 删除下标为index的元素
     * @param index
     * @return
     */
    public Object remove(int index) {
        if(index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        Object o = get(index);
        for(int i = index;i<size;i++) {
            list[i] = list[i+1];
        }
        size--;
        return o;
    }

    查询数据与修改数据都比较简单,直接利用相应的下标进行替换或返回相应的值,判断链表为空直接判断size的值就可以了,而清空链表就将size的值修改为0

    /**
     * 获取下标处的元素
     * 
     * @param index 下标
     * @return
     */
    public Object get(int index) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        return list[index];
    }
    
    /**
     * 判断列表是否为空
     * 
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }
    
    /**
     * 清空列表
     */
    public void clear() {
        size = 0;
    }
    
    /**
     * 列表大小
     * 
     * @return
     */
    public int size() {
        return size;
    }

     都是比较粗糙的实现,暂时还未考虑优化

  • 相关阅读:
    layer ----- 弹层
    php start
    node.js使用iconv-lite和zlib解决gzip压缩和gbk乱码
    AngularJS中promise的使用
    AngularJS中的$routeProvider
    AngularJS入门教程记录
    AngularJS中的$resource
    Javascript原型易错点记录
    触屏相关事件问题记录
    图片预加载
  • 原文地址:https://www.cnblogs.com/qxxblogs/p/9943584.html
Copyright © 2011-2022 走看看