创建线性表增删扩容并测试

线性表的定义:零个或多个元素的有限序列

a1-a2-....-a(i-1)-a(i)-a(i+1)-....a(n-1)-an

线性表的特点:

  1. a(i-1)是a(i)的直接前驱;
  2. a(i+1)是a(i)的直接后继;
  3. 除了第一个元素外,其余元素均有直接前驱;
  4. 除了最后一个元素外,其余元素都有直接后继;

n表示线性表的长度,当n=0时,称为空表。

底层既可以用数组实现,也可以用链表实现,都是增删改查,具体的实现方法不同。

List接口的定义

        既然线性结构可以由顺序存储结构和链式存储结构实现,那么将两者对线性结构共同的操作进行抽取,定义出线性结构的接口

public interface List<E> extends Iterable<E> {
        public void add(E el ement);
        public void add(int index, E element) throws IllegalAccessException;
        public void remove(E element);
        public E remove(int index);
        public E get(int index);
        public E set(int index, E element);
        public int size();
        public int indexOf(E element);
        public boolean contains(E element);
        public boolean isEmpty();
        public void clear();
        public void sort(Comparator<E> c);
        public void swap(int i, int j);
        public List<E> sublist(int fromIndex, int toIndex);

}

线性表的实现ArrayList

ArrayList就是线性结构顺序存储结构方式的具体实现,称为线性表

385d6e8249a3452492f2533d445979c2.png

 创建ArrayList类实现List接口

定义相关成员属性和构造函数

ArrayList(E[] arr)的问题

data不能直接引用外部传入的数组arr,否则外部对arr的修改会引起ArrayList内部的一些问题

d0d79f3529d04e4cad870c8ed35f1ae8.png

 add(int index,E element)

1.直接从表尾添加元素

2.从下标为2添加元素,过程:

且只能插入0到size之间,否则抛出异常

如果size的长度等于表的长度,就要进行扩容

从size-1开始,将下标为i的值赋给下标为i+1,以此类推

160b9f9ba3414ac8ae96119f7cd7e504.png

 

public void add(int index, E element) {

        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add index out of range");
        }
        if (size == data.length) {
            resize(data.length * 2);
        }
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = element;
        size++;
    }
 //扩容O(n)
    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        data = newData;
    }

a93d16902f4f446598f7046424e9f9a1.png

remove(int index),根据角标删除元素

让i从index+1开始,将i的值赋给i-1,i要小于size,size--

public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("remove index out of range");
        }
        E ret = data[index];
        for (int i = index + 1; i < size; i++) {
            data[i - 1] = data[i];
        }
        size--;
        if (size == data.length / 4 && data.length > 10) {
            resize(data.length / 2);
        }
        return ret;
    }

ae0ba288ab4045a4bf72b0c5f5257f90.png

a24a19a9c4054db8b915bbace0f09ad3.png

 缩容:当有效元素达到数组的1/4,且数组的长度大于10,才可以缩容,且缩到原来的1/4

不能缩容到原来的1/2原因是如果添加的元素超过原来的1/2,就要扩容

ab338b209ab84bb285bb9281ac150a68.png

 remove(E elememt),删除指定元素

要删除指定元素,首先要知道指定元素的角标,即遍历数组找角标

不能使用==,原因是要比较两个对象的内容是相等,且不能让传入的参数和已存在的比较,如果传入的参数是空的,就会发生空指针异常。

public int indexOf(E element) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(element)) {//比较两个对象的内容是否相等
                return i;
            }
        }
        return -1;
    }
public void remove(E element) {
        //删除全部
//        while(true){
//        int index = indexOf(element);
//        if (index != -1) {
//            remove(index);
//        }
//            }else{
//                break;
//            }
//        }
        //删除指定
        int index = indexOf(element);
        if (index != -1) {
            remove(index);
        }
    }
size(),获取有效元素的个数
public int size() {
        return size;
    }

contains(E element),判断元素是否存在,这里可以做一个循环遍历数组,但是也可以通过找角标的函数,如果不存在,令它返回-1

public boolean contains(E element) {
        return indexOf(element) != -1;
    }

isEmpty(),判空,返回值是如果size==0,即空

public boolean isEmpty(){

    return size == 0;
}

clear(),清空,新建一个数组,令size=0

public void clear(){

    data = (E[]) new Object[DEFAULT_CAPACITY];
    size = 0;
}

toString(),打印出数组,使用stringBuilder

public String toString() {
        //打印出数组
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()) {
            sb.append(']');
        } else {
            for (int i = 0; i < size; i++) {
                sb.append(data[i]);
                if (i == size - 1) {
                    sb.append(']');
                } else {
                    sb.append(',');
                    sb.append(' ');
                }
            }
        }
        return sb.toString();
    }

get(int index),获取指定角标处元素

public E get(int index){
    if(index < 0 || index > size){
        throw new IllegalArgument1Exception("get index out of range");
       }
        return data[index];
}

88b9fb6d78004134b84bdf9244292401.png

compare()返回值,负数表示第一个小于第二个,0表示相同,正数表示第一个大于第二个

测试

package com.openlab.dataStruce.p1动态数组;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;

public class TestArrayList {
    public static void main(String[] args) {
        Random random = new Random();
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println(list);
        for (int i = 0; i < 12; i++) {
            list.add(random.nextInt(20));
        }
        System.out.println(list);
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println(list);
        for (Integer num: list
             ) {
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

simpleHan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值