JAVA初阶必学-线性表-顺序表

线性表
概念:
线性表是n个具有相同特性的数据元素的有限序列。线性表表示一种广泛应用在实际中的数据结构,线性表中数据元素的关系的一对一的关系,大多数线性表除了第一个和最后一个数据元素之外,其他数据元素都是首尾相接的。
常见的线性表有顺序表,链表,栈,队列,字符串。
线性表在逻辑上是线性结构,也就是说是一条直线,但是在物理上并不以一定是连续的,线性表在物理上存储时,通常以数组和链表结构的形式存储。

顺序表
顺序表的概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的数据结构,一般情况下采用数组存储。在数组上完成数据的增删改查。
顺序表一般可分为
静态顺序表:使用定长数组存储。
动态顺序表:使用动态开辟的数组存储。
静态顺序表适用于知道需要存储多少数据的场景。(开多了浪费,开少了不够用)

实现动态顺序表

MyArrayList


/*
对象具备的一致性问题(前提)
1,size<=array.length
2,真正有用的元素下标[0,size)做删除操作size处不进行操作,因左闭右开,size处无有效值
3,可以插入元素的位置[0,size] size处也可插入,因有容量
4,[size,array.length)设置为无效的元素long.MIN_VALUE,便于观察
 */
/*
时间复杂度
当尾插,尾删时(暂不考虑扩容),时间复杂度为O(1)
根据下标插入删除时(包括头插),时间复杂度是O(n)
get(index)/set(index,e) 时间复杂度是O(1),顺序表支持随机访问
查找:indexOf,contains时间复杂度是O(n)
 */

import java.util.Arrays;

public class MyArrayList {
//两个需要的属性
    private long[] array;//存放数据的空间即空间的容量
    private int size;//有效元素的个数

    public MyArrayList() {
//将属性初始化,此时未插入有效元素,故将数组中全部填充为无效值Long.MIN_VALUE
        array = new long[2];
        size = 0;
        Arrays.fill(array, Long.MIN_VALUE);
    }

    /*
    放入元素
    1,指定位置放入
    2,在最后放入元素,即尾插操作
     */
    public long get(int index) {
//用来得到对应下标的值,便于检查操作的正确性
        //检查下标合法性
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException(index + ":" + size);
        }
        return array[index];
    }

    public int size() {
        return size;
    }
//尾插操作,即在末端插入值
    public void add(long e) {
        ensureCapacity();//调用方法确保容量足够
//  1,将元素放在size下标处
        array[size] = e;
//    2,size++
        size++;
    }

//确保容量足够的方法
    private void ensureCapacity() {
        if (size < array.length) {
            return;
        }
        //放不下了,进行扩容
        //建立新数组
        int newLength = array.length * 2;
        long[] newArray = new long[newLength];
        //复制内容到新数组
        for (int i = 0; i < size; i++) {
            newArray[i] = array[i];
        }
        Arrays.fill(newArray, size, newArray.length, Long.MIN_VALUE);//把[size,length]填充为无效值
        this.array = newArray;
    }

    //检查对象的正确性
    //如果对象不正确,抛异常
    public void check() {
        if (array == null) {
            throw new RuntimeException();
        }
        if (array.length == 0) {
            throw new RuntimeException();
        }
        if (size < 0) {
            throw new RuntimeException();
        }
        if (size > array.length) {
            throw new RuntimeException();
        }
        //[0,size)是有效元素
        for (int i = 0; i < size; i++) {
            if (array[i] == Long.MIN_VALUE) {
                throw new RuntimeException();
            }
        }
        //[size,array.length-1)是无效值
        for (int i = size; i < array.length; i++) {
            if (array[i] != Long.MIN_VALUE) {
                throw new RuntimeException();
            }
        }

    }
//指定下标进行插入
    public void add(int index, long e) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException(index + ":" + size);
        }
        ensureCapacity();
        //TODO
        for (int i = size; i > index; i--) {
            array[i] = array[i - 1];
        }
        array[index] = e;
        size++;
    }
//指定下标进行删除
    public void delete(int index) {
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException(index + ":" + size);
        }
        for (int i = index + 1; i < size; i++) {
            array[i - 1] = array[i];
        }
        size--;
        array[size] = Long.MIN_VALUE;
    }
//指定元素进行删除,从前往后遍历,只删一个
    public void removeFromHead(long e) {
        int index;
        for (index = 0; index < size; index++) {
            if (array[index] == e) {
               break;
                }
            }
        if (index == size) {
            return;
        }
        for (int i = index + 1; i < size; i++) {
            array[i - 1] = array[i];
        }
        size--;
        array[size] = Long.MIN_VALUE;

    }
//指定元素进行删除,从后往前遍历,只删一个
    public void removeFromLast(long e) {
        int index;
        for ( index = size-1; index >=0; index--) {
            if (array[index] == e) {
                break;
            }
        }
        if (index <0) {
            return;
        }
        for (int i = index + 1; i < size; i++) {
            array[i - 1] = array[i];
        }
        size--;
        array[size] = Long.MIN_VALUE;


    }
//下边三种均为删除顺序表中值为e的方法,性能略有不同
//初级解法,性能较差
    public void removeAll(long e) {
       int index=0;
        while(true){
            if(array[index]==e){
                for (int i = index + 1; i < size; i++) {
                    array[i - 1] = array[i];
                }
                size--;
                array[size] = Long.MIN_VALUE;
            }
            else{
                index++;
            }
            if(index==size){
                break;
            }
        }
    }
//开辟新数组,稍有优化
    public void removeAllNEW(long e) {
        //把不是e的元素搬到新的数组中,时间复杂度为O(n)
        int newLength=array.length;
        long[]newArray=new long[newLength];
        int j=0;
        for (int i = 0; i <size ; i++) {
            if (array[i]!=e){
                newArray[j]=array[i];
                j++;
            }
            else{

            }
        }
        size=j;
        Arrays.fill(newArray,j,newLength,Long.MIN_VALUE);
        this.array=newArray;
    }
//优化版,在原有的数组中完成任务
    public void removeAllNEWNEW(long e) {
        int from=0;
        int to=0;
        for (int i = 0; i <size ; i++) {
            if (array[i]!=e){
                array[to]=array[from];
                from++;
                to++;
            }
            else{
                from++;
            }
        }
        size=to;
        Arrays.fill(array,to,array.length,Long.MIN_VALUE);
    }
}

用例

UseMyArrayList

/*主要做以下几块内容
1,尾插
2,指定下标插入
3,指定下标删除
4,指定元素删除
1)从前往后删
2)从后往前删
3)全部删除
 */
//delete(int index)   下标有效值0<=index<size(),删除时取不到size
import com.shuai.Main.p20211130.MyArrayList;
public class UseMyArrayList {
//    插入位置是否正确的校验
    //通过assertTure方法,如果不报错即证明程序书写正确
    public static void assertTure(boolean condition){
        if(!condition){
            throw new RuntimeException();
        }
    }

public static void main(String[] args) {
    MyArrayList arrayList = new MyArrayList();
    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add(4);
    arrayList.add(5);
    arrayList.add(5);
    arrayList.add(4);
    arrayList.add(3);
    arrayList.add(2);
    arrayList.add(1);
    arrayList.check();
    assertTure(arrayList.size()==10);
    assertTure(arrayList.get(0)==1);

    arrayList.removeAllNEWNEW(2);
    arrayList.check();
    assertTure(arrayList.size()==8);
    assertTure(arrayList.get(1)==3);
    assertTure(arrayList.get(2)==4);
    assertTure(arrayList.get(3)==5);
    assertTure(arrayList.get(6)==3);
    assertTure(arrayList.get(7)==1);

}
public static void main5(String[] args) {
    MyArrayList arrayList = new MyArrayList();
    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add(4);
    arrayList.add(5);
    arrayList.add(5);
    arrayList.add(4);
    arrayList.add(3);
    arrayList.add(2);
    arrayList.add(1);
    arrayList.check();
    assertTure(arrayList.size()==10);
    assertTure(arrayList.get(0)==1);

    arrayList.removeFromLast(2);
    arrayList.check();
    assertTure(arrayList.size()==9);
    assertTure(arrayList.get(8)==1);
}
public static void main4(String[] args) {
    MyArrayList arrayList = new MyArrayList();
    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add(4);
    arrayList.add(5);
    arrayList.add(5);
    arrayList.add(4);
    arrayList.add(3);
    arrayList.add(2);
    arrayList.add(1);
    arrayList.check();
    assertTure(arrayList.size()==10);
    assertTure(arrayList.get(0)==1);

    arrayList.removeFromHead(2);
    arrayList.check();
    assertTure(arrayList.size()==9);
    assertTure(arrayList.get(0)==1);
    assertTure(arrayList.get(1)==3);
    assertTure(arrayList.get(2)==4);
    assertTure(arrayList.get(3)==5);
    assertTure(arrayList.get(4)==5);

}
    public static void main3(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        for (int i = 0; i <10 ; i++) {
            arrayList.add(i+1);
        }
        arrayList.check();
        assertTure(arrayList.size()==10);
        assertTure(arrayList.get(0)==1);

        arrayList.delete(9);
        arrayList.check();
        assertTure(arrayList.size()==9);
        assertTure(arrayList.get(8)==9);
        assertTure(arrayList.get(0)==1);

        arrayList.delete(0);
        arrayList.check();
        assertTure(arrayList.size()==8);
        assertTure(arrayList.get(0)==2);
        assertTure(arrayList.get(1)==3);

        arrayList.delete(4);
        arrayList.check();
        assertTure(arrayList.size()==7);
        assertTure(arrayList.get(0)==2);
        assertTure(arrayList.get(1)==3);
        assertTure(arrayList.get(4)==7);
        assertTure(arrayList.get(6)==9);


    }
    public static void main2(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.check();
        assertTure(arrayList.size()==0);

        arrayList.add(0,100);
        arrayList.check();
        assertTure(arrayList.size()==1);
        assertTure(arrayList.get(0)==100);

        arrayList.add(0,200);
        arrayList.check();
        assertTure(arrayList.size()==2);
        assertTure(arrayList.get(0)==200);
        assertTure(arrayList.get(1)==100);

        arrayList.add(1,300);
        arrayList.check();
        assertTure(arrayList.size()==3);
        assertTure(arrayList.get(0)==200);
        assertTure(arrayList.get(1)==300);
        assertTure(arrayList.get(2)==100);

        arrayList.add(3,400);
        arrayList.check();
        assertTure(arrayList.size()==4);
        assertTure(arrayList.get(0)==200);
        assertTure(arrayList.get(1)==300);
        assertTure(arrayList.get(2)==100);
        assertTure(arrayList.get(3)==400);



    }
    public static void main1(String[] args) {
        MyArrayList arrayList = new MyArrayList();
        arrayList.check();//检查对象的正确性
        assertTure(arrayList.size()==0);//检查插入位置是否正确,确保一致性


        arrayList.add(3, 1);//满足一致性
        arrayList.check();
        assertTure(arrayList.size()==1);
        assertTure(arrayList.get(0)==1);

        arrayList.add(3, 2);//满足一致性
        arrayList.check();
        assertTure(arrayList.size()==2);
        assertTure(arrayList.get(0)==1);
        assertTure(arrayList.get(1)==2);


        arrayList.add(3, 3);//满足一致性
        arrayList.check();
        assertTure(arrayList.size()==3);
        assertTure(arrayList.get(0)==1);
        assertTure(arrayList.get(1)==2);
        assertTure(arrayList.get(2)==3);

        arrayList.add(3, 4);//满足一致性
        arrayList.check();
        assertTure(arrayList.size()==4);
        assertTure(arrayList.get(0)==1);
        assertTure(arrayList.get(1)==2);
        assertTure(arrayList.get(2)==3);
        assertTure(arrayList.get(3)==4);


        arrayList.add(3, 5);//满足一致性
        arrayList.check();
        assertTure(arrayList.size()==5);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

.小柱.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值