ArrayList与顺序表

一.线性表
线性表是n个相同特征元素的有限序列。线性表在逻辑上是连续的,但在物理上不一定是连续的。线性表包括数组和链表。
顺序表结构:
在这里插入图片描述

链表结构:
在这里插入图片描述

二.顺序表
自己实现一个简单的顺序表:

public class MyArrayList {
    public int[] elem;
    //当前数组存储的有效数据个数
    public int usedSize;
    public static final int DEFAULT_SIZE=10;
    public MyArrayList(){
        this.elem=new int[DEFAULT_SIZE];
    }

    //获取顺序表的长度
    public int size(){
        return this.usedSize;
    }

    //判断是否包含某个元素
    public boolean contains(int toFind){
        for(int i=0;i<usedSize;i++){
            if(toFind==this.elem[i]){
                return true;
            }
           /* //如果是引用类型使用equals方法判等
            if(toFind.equals(this.elem[i])){
                return true;
            }*/
        }
        return false;
    }

    //查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (toFind == this.elem[i]) {
                return i;
            }
        }
        //数组下标没有负数
        return -1;
    }

    //新增元素,默认放在数组的最后,O(1)
    public void add(int data){
        if(this.isFull()){
            resize();
        }
        this.elem[this.usedSize]=data;
        this.usedSize++;
    }

    //获取pos位置的元素
    public int get(int pos){
        checkGetIndex(pos);
        return this.elem[pos];
    }
    //在pos位置新增元素,O(n)
    public void add(int pos,int data){
        checkAddIndex(pos);
        if(isFull()){
            resize();
        }
        for(int i=usedSize;i>=pos;i--){
            elem[i]=elem[i-1];
        }
        elem[pos]=data;
        this.usedSize++;
    }

    //给pos位置的元素更新位val,O(1)
    public void set(int pos,int value){
        checkGetIndex(pos);
        this.elem[pos]=value;
    }

    //删除第一次出选的关键子key,O(n)
    public boolean remove(int toRemove){
        int index=indexOf(toRemove);
        if(index==-1){
            System.out.println("没有这个元素");
            return false;
        }
        for(int i=index+1;i<=usedSize-1;i++){
            elem[i-1]=elem[i];
        }
        usedSize--;
        //如果时引用类型,要手动置空
        elem[usedSize]=0;
        return true;
    }

    //扩容
    private void resize(){
        this.elem= Arrays.copyOf(this.elem,2*this.elem.length);
    }

    //判断顺序表是否满
    public boolean isFull(){
        return this.elem.length==this.usedSize;
    }

    //插入数据时判断pos是否合法
    private void checkAddIndex(int pos){
        if(pos<0||pos>usedSize){
            throw new AddIndexOutOfException("add时pos位置不合法");
        }
    }

    //判断获取元素时pos位置是否合法
    private void checkGetIndex(int pos){
        if(pos<0||pos>=usedSize){
            throw new AddIndexOutOfException("add时pos位置不合法");
        }
    }

    //打印顺序表
    public void display(){
        for(int i=0;i<usedSize;i++){
            System.out.print(this.elem[i]+"  ");
        }
    }

    //清空顺序表
    public void clear(){
        for(int i=0;i<usedSize;i++){
            elem[i]=0;
        }
        usedSize=0;
    }
}

顺序表插入和删除需要移动元素,时间复杂度位O(n),所以不适合频繁的对数据插入和删除,适合给定下标查找元素,时间复杂度为O(1)。
三.ArrayList使用
小练习:杨辉三角(力扣118)添加链接描述

在这里插入图片描述
解决思路:创建一个ArrayList,ArrayList里面还有一个ArrayList1,ArrayList2,…ArrayListn,ArrayListn,将ArrayListn添加进ArrayList里面,ArrayListn里面第一个和最后一个元素都是1,中间的元素是上一行上面的元素与上一行上面的元素前一个的和,示意图如下:
在这里插入图片描述
具体实现:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret=new ArrayList<>();
        List<Integer> one=new ArrayList<>();
        one.add(1);
        ret.add(one);
        for(int i=1;i<numRows;i++){
            List<Integer> row=new ArrayList<>();
            row.add(1);
            List<Integer> list=ret.get(i-1);
            for(int j=1;j<i;j++){              
                int sum=list.get(j)+list.get(j-1);
                row.add(sum);
            }
            row.add(1);
            ret.add(row);
        }
        return ret;
    }
}

四.ArrayList的扩容机制
在这里插入图片描述

五.扑克牌的实现顺序表
ArrayList优点:当给定下标的时候,查找的速度非常快,适合给定下标查找。O(1)缺点:插入删除时须得挪动元素,每次扩容也浪费资源。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值