数据结构java(三)线性表 ①顺序结构实现(ArrayList)手写

1.特点

  • 相同数据类型
  • 序列(顺序性)
  • 有限

2.逻辑结构

3.存储结构

  • 链式表 (节点=值+地址)
    • 优点 插入和删除方便,空间利用率高
    • 缺点 存储密度小( <1 ),查找和修改需要遍历整个链表
  • 顺序表(数组)
    • 优点 存储密度大( =1 ),易于查找和修改
    • 缺点 插入和删除不方便,存储空间利用率低

4.实现

  • 顺序结构实现

1. 自定义线性表接口(List)和存储结构无关

/**
 * 自定义线性表接口
 * 和存储结构无关
 * @author Administrator
 */
public interface List {
    /**
     * 定义size方法,应返回size大小,最大值为Integer.MAX_VALUE
     * @return
     */
    int size();

    /**
     * List要求,定义get方法,获取指定index的值
     * @param index
     * @return
     */
    Object get(int index);

    /**
     * 定义isEmpty方法,用于返回是否为空
     * 如果不包含元素,则返回true
     * @return
     */
    boolean isEmpty();

    /**
     * 定义contains方法,判断一个e是否属于此集合
     * 如不是集合,则返回true
     * @param e
     * @return
     */
    boolean contains(Object e);

    /**
     *
     * 获取查询元素的index,若备查元素为null,则寻找空元素,返回index
     * 若备查元素不为null,则使用equal判断该元素是否存在,并返回index
     * 不存在则返回-1
     * 被contains调用
     * @param e
     * @return
     */
    int indexOf(Object e);

    /**
     * 定义add方法,添加一个元素e,并返回添加成功标志
     * @param e
     * @return
     */
    boolean add(Object e);

    /**
     * 在指定位置插入指定元素在这个列表(可选操作)。变化的元素目前位置(如果有的话)和任何后续元素向右(添加一个索引)。
     * @param index 指数要插入指定的元素
     * @param e 元素被插入
     */
    void add(int index, Object e);

    /**
     * 将元素e插入到元素object之前
     * @param object 目标元素
     * @param e 元素被插入
     * @return
     */
    boolean addBefore(Object object,Object e);

    /**
     * 将元素e插入到元素object之后
     * @param object 目标元素
     * @param e 元素被插入
     * @return
     */
    boolean addAfter(Object object,Object e);

    /**
     * 这个列表中删除指定位置的元素(可选操作)。任何后续元素转移到左(减去一个来自他们的指标)。返回的元素从列表中删除。
     * @param index 删除元素的索引
     * @return
     */
    Object remove(int index);

    /**
     * 定义remove方法,移除一个元素e,并返回移除元素成功标志
     * @param e
     * @return
     */
    boolean remove(Object e);

    /**
     * 替换序号为index的元素为e 返回原元素
     * @param index 序号
     * @param e 替换元素
     * @return 原元素
     */
    Object replace(int index,Object e);

}

2.顺序结构的实现类(ArrayList) 

import java.util.Arrays;

/**
 * 顺序结构的实现
 * @author Administrator
 */
public class ArrayList implements List {

    /**
     * 底层是一个数组
     */
    private Object[] elementData;
    /**
     * 不是数组分配的空间,而是元素的个数
     */
    private int size;

    /**
     * @param initialCapacity 数组初始长度
     */
    public ArrayList(int initialCapacity){
        //给数组分配指定的空间
        elementData = new Object[initialCapacity];
        //指定顺序表元素个数
//        size = 0; int初始值是0
    }

    public ArrayList(){
        //没有指定长度,默认长度是5
        this(10);
        //没有指定长度,长度是0
//        elementData = new Object[]{};
    }



    /**
     * 定义size方法,应返回size大小,最大值为Integer.MAX_VALUE
     *
     * @return
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * List要求,定义get方法,获取指定index的值
     *
     * @param index
     * @return
     */
    @Override
    public Object get(int index) {
        if (index < 0 || index >= size){
            throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }
        return elementData[index];
    }

    /**
     * 定义isEmpty方法,用于返回是否为空
     * 如果不包含元素,则返回true
     *
     * @return
     */
    @Override
    public boolean isEmpty() {
        return size==0;
    }

    /**
     * 定义contains方法,判断一个e是否属于此集合
     * 如不是集合,则返回true
     *
     * @param e
     * @return
     */
    @Override
    public boolean contains(Object e) {
        return indexOf(e)>=0;
    }

    /**
     * 获取查询元素的index,若备查元素为null,则寻找空元素,返回index
     * 若备查元素不为null,则使用equal判断该元素是否存在,并返回index
     * 不存在则返回-1
     * 被contains调用
     *
     * @param e
     * @return
     */
    @Override
    public int indexOf(Object e) {
        if (e == null) {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null)
                {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (e.equals(elementData[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 定义add方法,添加一个元素e,并返回添加成功标志
     *
     * @param e
     * @return
     */
    @Override
    public boolean add(Object e) {
        this.add(size,e);

//        //数组扩容
//        if (size == elementData.length){
//            grow();
//        }
//
//        //添加
//        elementData[size] = e;
//        //元素个数+1
//        size++;
        elementData[size++] = e;
        System.out.println("length="+elementData.length);
        return true;
    }
    /**
     * 在指定位置插入指定元素在这个列表(可选操作)。变化的元素目前位置(如果有的话)和任何后续元素向右(添加一个索引)。
     *
     * @param index 指数要插入指定的元素
     * @param e     元素被插入
     */
    @Override
    public void add(int index, Object e) {
        //判断index的位置要正确
        if (index<0 || index>size){
            throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }

        //数组扩容
        if (size == elementData.length){
            grow();
        }
        //后移index及其后面元素,从最后一个元素开始
        for (int j = size; j>index ;j--){
            elementData[j] = elementData[j-1];
        }
        //添加
        elementData[index] = e;
        //元素个数+1
        size++;
    }


    /**
     * 数组扩容
     */
    private void grow(){
//            //新创建一个新的数组,长度是旧的数组2倍
//            Object[] newArr = new Object[elementData.length*2];
//            //将旧数组的数据拷贝到新的数组中
//            for (int i = 0;i<size;i++){
//                newArr[i] = elementData[i];
//            }
//            //让elementData指向新数组
//            elementData = newArr;
        elementData = Arrays.copyOf(elementData,elementData.length*2);

    }



    /**
     * 将元素e插入到元素object之前
     *
     * @param object 目标元素
     * @param e      元素被插入
     * @return
     */
    @Override
    public boolean addBefore(Object object, Object e) {
        //目标元素的索引序号 -1说明无此元素
        int i = indexOf(object);
        if (i==-1){
            return false;
        }
        //添加操作
        add(i,e);
        return true;
    }

    /**
     * 将元素e插入到元素object之后
     *
     * @param object 目标元素
     * @param e      元素被插入
     * @return
     */
    @Override
    public boolean addAfter(Object object, Object e) {
        //目标元素的索引序号 -1说明无此元素
        int i = indexOf(object);
        if (i==-1){
            return false;
        }
        //添加操作
        add(i+1,e);
        return true;
    }

    /**
     * 这个列表中删除指定位置的元素(可选操作)。任何后续元素转移到左(减去一个来自他们的指标)。返回的元素从列表中删除。
     *
     * @param index 删除元素的索引
     * @return
     */
    @Override
    public Object remove(int index) {
        //判断index的位置要正确
        if (index<0 || index>size-1){
            throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }
        //要删除的元素
        Object elementDatum = elementData[index];
        //要移动的长度
        fastRemove(index);
        return elementDatum;
    }

    /**
     * 定义remove方法,移除一个元素e,并返回移除元素成功标志
     *
     * @param e
     * @return
     */
    @Override
    public boolean remove(Object e) {
        //当前元素的索引序号 -1说明无此元素
        int i = indexOf(e);
        if (i==-1){
            return false;
        }
        fastRemove(i);
        return true;

//        if (e == null) {
//            for (int index = 0; index < size; index++){
//                if (elementData[index] == null) {
//                    fastRemove(index);
//                    return true;
//                }
//            }
//
//        } else {
//            for (int index = 0; index < size; index++){
//                if (e.equals(elementData[index])) {
//                    fastRemove(index);
//                    return true;
//                }
//            }
//
//        }
//        return false;


    }

    /**
     * 要移动的长度
     * @param index
     */
    private void fastRemove(int index) {
        for (; index<size;index++){
            elementData[index] = elementData[index+1];
        }
        elementData[size]=null;
        size--;
    }

    /**
     * 替换序号为index的元素为e 返回原元素
     *
     * @param index 序号
     * @param e     替换元素
     * @return 原元素
     */
    @Override
    public Object replace(int index, Object e) {
        if (index < 0 || index >= size){
            throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }
        Object object = elementData[index];
        elementData[index] = e;
        return object;
    }


    //[0,1,2,3,4,5]
    @Override
    public String toString() {
        if (size == 0){
            return "[]";
        }

        StringBuilder builder = new StringBuilder("[");
        for (int i = 0;i<size;i++){
            if (i!=size-1){
                builder.append(elementData[i]+",");
            }else {
                builder.append(elementData[i]);
            }

        }
        builder.append("]");

        return builder.toString() ;
    }
}

3.自定义异常(MyArrayIndexOutOfBoundsException)

/**
 * 自定义异常类
 * @author Administrator
 */

public class MyArrayIndexOutOfBoundsException extends RuntimeException{
    public MyArrayIndexOutOfBoundsException(){
        super();
    }
    public MyArrayIndexOutOfBoundsException(String message){
        super(message);
    }
}

4.测试类(ArrayListTest) 

/**
 * 测试
 * @author Administrator
 */
public class ArrayListTest {

    private List list;
    @Before
    public void setUp() throws Exception {
        list = new ArrayList();
        list.add(0);
        list.add(null);
        list.add(2);
        list.add(3);
    }
    @Test
    public void add() {
        list.add(1,151515151);
        int size = list.size();
        System.out.println("元素个数="+size);
        System.out.println(list);
    }
    @Test
    public void get(){
        Object o = list.get(1);
        System.out.println(o);
        System.out.println(list);
    }
    @Test
    public void indexOf(){
        add();
        int i = list.indexOf(3);
        System.out.println(i);
    }
    @Test
    public void remove(){
        Object remove = list.remove(4);
        System.out.println(remove);
        System.out.println(list.toString());
    }
    @Test
    public void remove1(){
        System.out.println("操作前线性表:"+list);
        boolean remove = list.remove(Integer.valueOf(1));
        System.out.println(remove);
        System.out.println("操作后线性表:"+list);
    }
    @Test
    public void replace(){
        Object o = list.replace(3, 1);
        System.out.println(o);
        System.out.println(list.toString());
    }

    @Test
    public void addAfter() {
        System.out.println("操作前线性表:"+list);
        boolean b = list.addAfter(4, 99999);
        System.out.println(b);
        int size = list.size();
        System.out.println("元素个数="+size);
        System.out.println("操作后线性表:"+list);
    }

    @Test
    public void addBefore() {
        System.out.println("操作前线性表:"+list);
        boolean b = list.addBefore(null, 99999);
        System.out.println(b);
        int size = list.size();
        System.out.println("元素个数="+size);
        System.out.println("操作后线性表:"+list);
    }


    @Test
    public void contains() {
        boolean contains = list.contains(0);
        System.out.println(contains);
    }

}

下一篇: 数据结构java(四)线性表 ②链式结构实现(单链表SingleLinkedList)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值