顺序表-java-笔记

一、前置知识:线性表的定义:https://blog.csdn.net/jdie00/article/details/81045814

二、类定义

顺序表,就是利用顺序结构存储的线性表,在数据结构的操作上和线性表别无二致。而在存储方式上对线性表进行了限制。

顺序存储结构即在内存中用连续的存储空间来将数据存储下来,用物理上的线性关系来表示逻辑上的线性关系。

元素关系、行为定义和存储方式有了,我们要实现我们的顺序表类了。但是还有两个问题需要解决:

1.确定类中的成员变量和静态方法:两个都是要看实际需要,之后讨论

2.确定构造器:接口只能定义行为,不能定义初始化(构造器),我们还需要自行定义构造器

我认为的解决:

1.成员变量中一定要有的是Object数组,用于存储数据;书上还提到了一个用于记录大小的int变量,我们来讨论一下是否具有合理性:有些意见可能是,方便得到整个表的大小,而不是每一次都要统计;这个原因有,而且非常大。但是我认为,如果你在ArrayList中尾插null,此时的数组和没有插入是一样的,这个int变量可以处理尾插入null的情况。(让我们知道真正有多少个元素,而不是最后一个非空元素之前有多少元素!)

2.构造器...,空构造、指定容量的、指定初始化数组的、容量和数组都指定的、用其他表初始化

三、实现

不一定正确,算是笔记性质

package DataStructure.LinerList;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 第一版的ArrayList,看了一遍书写的
 * @param <T>
 */
//里面的所有复制算法都可以用System.arrayCopy()方法代替
public class ArrayList1<T> implements List1<T>{

    /*大小*/
    private int size;
    /*存储数据*/
    private Object[] elementData;

    public ArrayList1() {//默认构造,长度10
        this.elementData = new Object[10];
    }

    public ArrayList1(int size) {//看起来好看,然而空间的话,还不如写开了if-else
        this();
        if (size > 0) {
            this.elementData = new Object[size];
        }
    }

    public ArrayList1(int size, T[] elementData) {
        if (elementData != null) {//二参非法
            if (size > elementData.length) {//一参大于二参长度
                this.elementData = new Object[size];//创建
                copy(elementData, this.elementData);//复制
            } else {
                this.elementData = elementData;//赋值
            }
            this.size = elementData.length;//不要忘了,只要更改elementData,一定对size进行核查
        } else {
            this.elementData = new Object[size > 0 ? size : 10];//实际上就是this(size),然而放在第一句的话,浪费空间时间
        }
    }

    public ArrayList1(T[] elementData) {//你懂得~
        this(0, elementData);
    }

    public ArrayList1(List1 list) {
        if (list == null || list.size() == 0) {//list为空,....,或者为空/xk
            elementData = new Object[10];
        } else {
            elementData = new Object[list.size() + (list.size() >> 1)];//运算优先级...小心一点
            for (int i = 0 ; i < list.size() ; i ++) {
                insert((T) list.get(i));//方便,快捷~
            }
        }
    }

    @Override
    public boolean isEmpty() {//不解释
        return size == 0;
    }

    @Override
    public int size() {//不解释
        return size;
    }

    @Override
    public T get(int i) {
        if (i < 0) {//非法参数
            throw new IllegalArgumentException("Exception for input i:" + i);
        } else if (i > size - 1) {//非法参数
            throw new IllegalArgumentException("Exception for input i:" + i + " bigger than elementData.length");
        }
        return (T) elementData[i];
    }

    @Override
    public void set(int i, T x) {
        if (i < 0) {//非法
            throw new IllegalArgumentException("Exception for input i:" + i);
        } else if (i > size - 1) {//非法
            throw new IllegalArgumentException("Exception for input i:" + i + " bigger than elementData.length");
        }
        elementData[i] = x;
    }

    @Override
    public int insert(int i, T x) {
        if (i < 0) {//头插
            moveToNext(0);//将从0开始的元素向后移一位
            elementData[0] = x;//赋值
            size ++;//size变化
            return 0;//返回插入位置
        } else if (i > size - 1){//尾插
            return insert(x);//尾插
        }
        //正常插入
        moveToNext(i);//从i之后每一个向后移一位
        elementData[i] = x;//赋值
        size++;//size变动
        return i;//返回插入位置
    }

    /**
     * 将从index开始的数组元素向后移动一个位数
     * @param index 开始位置
     */
    private void moveToNext(int index) {
        if (size == elementData.length) {//满容
            dilatation();//扩容
        }
        for (int i = size - 1 /*从后向后移*/; i >= index ; i --) {
            //如果从前向后移,将会使后面的每一个值都变成elementData[index]
            //首次循环:elementData[size] = elementData[size - 1]
            //末次循环:elementData[index + 1] = elementData[index]
            elementData[i + 1] = elementData[i];//后移
        }
    }

    //扩容
    private void dilatation() {
        Object[] oldElementData = elementData;//旧的
        elementData = new Object[size + (size >> 1)];//新的
        copy(oldElementData, elementData);//复制,将旧的复制到新的中,旧的一定是满容的
    }

    //复制,可以用System.arrayCopy方法替代
    private void copy(Object[] old, Object[] target) {
        for (int i = 0 ; i < old.length ; i ++)
            target[i] = old[i];
    }

    @Override
    public int insert(T x) {//尾插
        if (size == elementData.length)//满容
            dilatation();//扩容
        elementData[size] = x;
        size ++;
        return size - 1;//因为size自增,之前的位置是size - 1
    }

    @Override
    public T remove(int i) {
        if (i < 0)
            throw new IllegalArgumentException("for input i:" + i);
        if (i >= size)
            throw new IllegalArgumentException("for input i:" + i + " exceed the size-1");
        //正常
        T result = (T)elementData[i];//暂存,否则将覆盖
        moveToPre(i);//i之后的元素向前移,将i覆盖
        size --;//size变动
        return result;
    }

    private void moveToPre(int index) {
        for (int i = index + 1 ; i < size ; i ++)
            //从前向前移,若从后向前,则index之后元素值都为elementData[size - 1]
            //首次循环:elementData[index] = elementData[index + 1]
            //末次循环:element[size - 2] = elementData[size - 1]
            elementData[i - 1] = elementData[i];
    }

    @Override
    public void clear() {//不解释,size是一个逻辑变量
        size = 0;
    }

    @Override
    public int search(T key) {//这个就基本上和java源码实现差不多了
        if (key == null) {
            for (int i = 0 ; i < size ; i ++) {
                if (elementData[i] == null)
                    return i;
            }
        } else {
            for (int i = 0 ; i < size ; i ++) {
                if (key.equals(elementData[i]))
                    return i;
            }
        }
        return -1;
    }

    @Override
    public int lastSearch(T key) {//不解释
        if (key == null) {
            for (int i = size - 1 ; i >= 0 ; i --) {
                if (elementData[i] == null)
                    return i;
            }
        } else {
            for (int i = size - 1 ; i >= 0 ; i --) {
                if (key.equals(elementData[i]))
                    return i;
            }
        }
        return -1;
    }

    @Override
    public int search(T key, int count) {//不解释
        int num = 0;
        if (key == null) {
            for (int i = 0 ; i < size ; i ++) {
                if (elementData[i] == null){
                    num++;
                    if (num == count)
                        return i;
                }
            }
        } else {
            for (int i = 0 ; i < size ; i ++) {
                if (key.equals(elementData[i])) {
                    num++;
                    if (num == count)
                        return i;
                }
            }
        }
        return -1;
    }

    @Override
    public boolean contains(T key) {//不解释
        return search(key) != -1;
    }

    @Override
    public int insertDifferent(T x) {
        if (!contains(x)) {//若不含
            return insert(x);
        }
        return -1;
    }

    @Override
    public int insertDifferent(int i, T x) {
        if (!contains(x)) {
            return insert(i, x);
        }
        return -1;
    }

    @Override
    public T remove(T key) {//外层if判断不解释。内层直接调用remove(i)
        if (key == null) {
            for (int i = 0 ; i < size ; i ++) {
                if (elementData[i] == null) {
                    return remove(i);
                }
            }
        } else {
            for (int i = 0 ; i < size ; i ++) {
                if (key.equals(elementData[i])) {
                    return remove(i);
                }
            }
        }
        throw new RuntimeException("no such key:" + key);
    }

    @Override
    public T remove(int count, T key) {//同上
        int num = 0;
        if (key == null) {
            for (int i = 0 ; i < size ; i ++) {
                if (elementData[i] == null) {
                    num ++;
                    if (num == count) {
                        return remove(i);
                    }
                }
            }
        } else {
            for (int i = 0 ; i < size ; i ++) {
                if (key.equals(elementData[i])) {
                    num ++;
                    if (num == count) {
                        return remove(i);
                    }
                }
            }
        }
        throw new RuntimeException("no such key:" + key);
    }

    @Override
    public void addAll(List1 list) {//不解释
        for (int i = 0 ; i < list.size() ; i ++)
            insert((T)list.get(i));
    }

    @Override
    public List1 removeAll(List1 list) {
        List1 result = new ArrayList1();
        int temp = -1;
        for (int i = 0 ; i < list.size() ; i ++) {
//            for (int j = 0 ; j < size ; j ++) {
//                if (elementData[j] == null && list.get(i) == null) {
//                    result.insert(remove(j));
//                } else if (elementData[j] != null && elementData[j].equals(list.get(i))) {
//                    result.insert(remove(j));
//                }
//            }
            temp = search((T) list.get(i));//查询,第一次出现的值
            if (temp != -1)
                result.insert(remove(i));//将出现的值移除,并添加在结果中
        }
        return result;
    }

    @Override
    public String toString() {//线程不安全,不使用StringBuffer
        StringBuilder stringBuilder = new StringBuilder(this.getClass().getName());
        stringBuilder.append(":[");
        if (size != 0) {
            for (int i = 0 ; i < size - 1 ; i ++)
                stringBuilder.append(get(i) + ", ");
            stringBuilder.append(get(size - 1));
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值