《数据结构》顺序表ArrayList

news2024/11/25 15:52:52

《数据结构》顺序表ArrayList

文章目录

  • 《数据结构》顺序表ArrayList
    • 什么是顺序表:
    • 模拟实现顺序表(以int类型为例)
    • 详解ArrayList:
        • ArrayList实现的接口:
        • ArrayList的构造方法:
          • 对源码的解析:
      • ArrayList的方法
      • ArrayList的扩容机制
    • ArrayList的缺陷

什么是顺序表:

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。

顺序表通过控制数组中的有效数据个数,进而包装成一个连续存储数据元素的线性结构.

模拟实现顺序表(以int类型为例)

import java.util.*;
class MyArraylist{
    public int size;
    public int[] elem;
    MyArraylist(){
        elem = new int[0];
    }
    MyArraylist(int n){
        elem = new int[n];
    }
    private boolean isfull(){
        return size==elem.length;
    }
    private boolean checkpos(int pos){
        if(pos<0||pos>=size){
            return false;
        }
        return true;
    }
    public boolean isempty(){
        return size==0;
    }
    public void display(){
        for(int i = 0;i < size;i++){
            System.out.print(elem[i]+" ");
        }
    }

    public void add(int x){
        if(isempty()){
            elem = new int[10];
        }
        if(isfull()){
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        elem[size] = x;
        size++;
    }
    public void add(int x,int pos){
        if(isempty()){
            elem = new int[10];
        }
        if(isfull()){
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        if(checkpos(pos)){
            for(int i = size;i>pos;i--){
                elem[i] = elem[i-1];
            }
            elem[pos] = x;
            size++;
        }else{
            System.out.println("pos下标不合法");
        }
    }
    public boolean contains(int tofind){
        if(isempty()){
            System.out.println("顺序表为空,查找失败");
        }
        for(int i = 0;i < size;i++){
            if(elem[i]==tofind){
                return true;
            }
        }
        return false;
    }
    //返回数值k的下标
    public int indexOf(int k){
        if(isempty()){
            System.out.println("顺序表为空,查找失败");
        }
        for(int i = 0;i < size;i++){
            if(elem[i]==k){
                return i;
            }
        }
        return -1;
    }
    //得到pos下标的值
    public int get(int pos){
        if(!checkpos(pos)){
            System.out.println("pos下标不合法");
        }
        return elem[pos];
    }
    public void set(int x,int pos){
        if(!checkpos(pos)){
            System.out.println("pos下标不合法");
        }else{
            elem[pos] = x;
        }
    }
    public void remove(int k){
        if(!checkpos(k)){
           System.out.println("pos下标不合法");
        }else{
            for(int i = k;i<size;i++){
               elem[i] = elem[i+1];
            }
            size--;
        }
    }
    public int size(){
        return size;
    }
    public void clean(){
        size = 0;
    }
}
public class Main{
    public static void main(String[] args){
        MyArraylist arraylist = new MyArraylist();
        arraylist.add(1);
        arraylist.add(2);
        arraylist.add(1);
        arraylist.add(2);
        arraylist.add(1);
        arraylist.add(2);
        //arraylist.display();
        arraylist.add(3,2);
        arraylist.display();
        arraylist.remove(2);
        arraylist.display();
    }
}

值得注意的是:

在我们的remove和clean方法中,如果删除的元素是引用类型时,需要把这个要被删除的元素置为null,防止出现内存泄露的问题.一般而言,对于pos指针不合法,或者顺序表为空无法查询的情况,我们也可以通过抛出异常来终止本次操作并提醒程序员.

详解ArrayList:

ArrayList实现的接口:

在这里插入图片描述

  1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

  2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的

  3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的

  4. ArrayList不是线程安全的,可以在单线程使用.

ArrayList的构造方法:

  • ArrayList()

  • ArrayList(Collection<? extends E> c) 利用其他 Collection 构建 ArrayList

  • ArrayList(int initialCapacity) 指定顺序表初始容量

对源码的解析:

对于ArrayList():

在这里插入图片描述

在这里插入图片描述

我们可以很明显的得出,使用ArrayList构造出来的顺序表,底层是一个空数组,没有容量.

对于ArrayList(Collection<? extends E> c):

在这里插入图片描述

首先.这个构造方法会将接受的c转化为数组存入elem中,并且如果该数组的大小为空,则直接生成一个空数组来作为底层数组,如果不为空 这会判断这个数组是不是一个Object数组,如果是一个Object数组,则不需要进行拷贝了,已经赋值成功了,如果不是一个Object数组,则需要进行拷贝.

对于ArrayList(int initialCapacity)
在这里插入图片描述

作用比较单一 ,传入的int是多大,那么底层数组的容量就是多大.

ArrayList的方法

方法解释
boolean add(E e)尾插 e
void add(int index, E element)将 e 插入到 index 位置
boolean addAll(Collection<? extends E> c)尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置元素
E set(int index, E element)将下标 index 位置元素设置为 element
void clear()清空
boolean contains(Object o)判断 o 是否在线性表中
int indexOf(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List subList(int fromIndex, int toIndex)截取部分 list

ArrayList的扩容机制

为了ArrayList的动态存储,对于数组的长度采用的动态扩容的机制.

源码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重点关注grow()

private void grow(int minCapacity) {
// 获取旧空间大小
    int oldCapacity = elementData.length;
// 预计按照1.5倍方式扩容
    int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小
     if (newCapacity - MAX_ARRAY_SIZE > 0)
         newCapacity = hugeCapacity(minCapacity);
// 调用copyOf扩容
     elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
// 如果minCapacity小于0,抛出OutOfMemoryError异常
     if (minCapacity < 0)
          throw new OutOfMemoryError();
     return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

在确保数组已经无法存下元素之后,并且用户需要扩容的数值没有问题的情况下,grow保证了ArrayList的动态扩容机制

  • 初步预估按照1.5倍大小扩容

  • 如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容

  • 真正扩容之前检测是否能扩容成功,防止太大导致扩容失败

实现了ArrayList 的1.5倍扩容

ArrayList的缺陷

  • 顺序表中间/头部的插入删除,时间复杂度为O(N)

  • 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/13813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Hack The Box】windows练习-- acute

HTB 学习笔记 【Hack The Box】windows练习-- acute &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月17日&#x1f334; &#x1f…

并发入门组件AQS源码解析(未完善)

必要掌握技术 阻塞&#xff0c;唤醒与中断 阻塞与唤醒 LockSupport的park使用的是Parker->park() synchronized的wait&#xff0c;synchronized的monitorenter使用的是ParkEvent->park()&#xff0c; 而LockSupport的unpark&#xff0c;Parker->unpark() synchroni…

员工离职后,账号权限怎么自动化回收?

最近一则离职员工报复前东家的新闻引人注目。起因是该员工被公司辞退后怀恨在心&#xff0c;于是用自己的笔记本电脑入侵了前公司的服务器&#xff0c;进入了该公司的法国站、英国站、德国站三个亚马逊店铺&#xff0c;进行了大幅调低商品价格、主动向客户发起退款、调高广告预…

1525_AURIX TC275 BootROM上

全部学习汇总&#xff1a; GitHub - GreyZhang/g_TC275: happy hacking for TC275! 这一次看一个全新的章节&#xff0c;BootROM&#xff0c;这是我之前只听过但是没有接触过的一个功能。 1. BootROM包含的三个主要的功能&#xff1a;启动软件、引导加载程序、测试固件。 2. 启…

UI设计都有哪些设计原则,分享三个给你

是什么使一个好UI设计容易阅读&#xff1f;是什么让用户轻松浏览&#xff1f;设计师如何创造一个闪亮的UI&#xff1f;任何软件产品的关键部分都是用户界面。 ​好的UI设计&#xff0c;用户甚至会忽略它。如果做得不好&#xff0c;就会成为用户使用产品的绊脚石。为了更有效地设…

数字化车间认定条件

一、申报数字化车间的奖励&#xff1a; 聊城市为了支持企业开展智能制造。对新获认定的国家级智能制造示范工厂、智能制造优秀场景&#xff0c;分别给予最高100万元、50万元一次性奖励&#xff1b;对新获认定的省级智能制造系统解决方案供应商、智能制造标杆企业、智能工厂、数…

因误删文件导致CentOS7开机卡死无法进入图形登录界面

目录 1、背景 2、解决步骤 1、背景 这几天在清理电脑&#xff0c;需要删除虚拟机&#xff0c;为此写下了Linux系统下卸载VMware Workstation软件_nanke_yh的博客-CSDN博客&#xff0c;但是同时怕有残留&#xff0c;自己全局搜索了vm&#xff0c;删除了部分带有vm的文件。删除…

【GridMask】《GridMask Data Augmentation》

arXiv-2020 文章目录1 Background and Motivation2 Related Work3 Advantages / Contributions4 GridMask5 Experiments5.1 Image Classification5.2 Object Detection on COCO Dataset5.3 Semantic Segmentation on Cityscapes5.4 Expand Grid as Regularization6 Conclusion&…

MongoDB之完整入门知识(集合操作、文档基本CRUD操作、文档分页查询、索引等相关命令)

MongoDB完整入门知识一、相关概念1、简介2、体系结构3、安装网址二、MongoDB基本常用命令1、Shell连接&#xff08;mongo命令&#xff09;2、选择和创建数据库2.1 选择和创建数据库的语法格式&#xff08;如果数据库不存在&#xff0c;则自动创建&#xff09;2.2 查看有权限查看…

SpringBoot与Loki的那些事

因为网上好多都没有通过Loki的API自己实现对日志监控系统&#xff0c;所以我就下定决心自己出一版关于loki与springboot的博文供大家参考&#xff0c;这个可以说是比较实用&#xff0c;很适合中小型企业。因此我酝酿了挺久了&#xff0c;对于loki的研究也比较久&#xff0c;希望…

论文精读《OFT: Orthographic Feature Transform for Monocular 3D Object Detection》

OFT: Orthographic Feature Transform for Monocular 3D Object Detection 文章目录OFT: Orthographic Feature Transform for Monocular 3D Object Detection论文精读摘要&#xff08;Abstract&#xff09;1. 介绍&#xff08;Introduction&#xff09;2. 相关工作&#xff08…

给开源项目做一个漂亮简洁的版本迭代更新图,生成固定链接复制到介绍中、公众号菜单链接中、博客中等

背景 开源项目的版本迭代与更新经常需要更新迭代文档&#xff0c;但是readme.md没有比较美观一点的效果&#xff0c;所以文本分享一种第三方的方式&#xff1a;用TexSpire的免费在线文档分享功能&#xff0c;手机、PC、Pad都可以适配。 效果预览 使用 第一步&#xff1a;创…

浅谈 async/await 和生成器

浅谈 async/await async/await 是ES8规范新增的&#xff0c;使得以同步方式写的代码异步运行不再是白日梦&#xff0c;进一步让代码逻辑更加清晰。 为什么新增 async/await 下面有这样一个需求&#xff1a;有两个请求&#xff0c;请求 1 的结果是请求 2 的参数&#xff0c;所…

机器学习6——EM算法与高斯混合模型GMM

前置内容 Jensen不等式 高斯混合模型 多元高斯模型 拉格朗日乘子法 主要内容 EM算法&#xff08;Expectation-Maximization&#xff09;&#xff0c;期望-最大化。 用于保证收敛到MLE&#xff08;最大似然估计&#xff09;。主要用于求解包含隐变量的混合模型&#xff0c;主要…

R生成三线表

R生成三线表table1包测试数据生成制作三线表Tableone包加载包 探索数据类型数据整理分类构建Table函数Tableone函数细节主要基于table1 或tableone 包table1包 测试数据生成 datadata.frame(性别sample(c("男","女"), 1000,replaceT),年龄round(rnorm(10…

2021年认证杯SPSSPRO杯数学建模A题(第一阶段)医学图像的配准全过程文档及程序

2021年认证杯SPSSPRO杯数学建模 A题 医学图像的配准 原题再现&#xff1a; 图像的配准是图像处理领域中的一个典型问题和技术难点&#xff0c;其目的在于比较或融合同一对象在不同条件下获取的图像。例如为了更好地综合多种信息来辨识不同组织或病变&#xff0c;医生可能使用…

5年自动化测试,终于进字节跳动了,年薪30w其实也并非触不可及

一些碎碎念 什么都做了&#xff0c;和什么都没做其实是一样的&#xff0c;走出“瞎忙活”的安乐窝&#xff0c;才是避开弯路的最佳路径。希望我的经历能帮助到有需要的朋友。 在测试行业已经混了5个年头了&#xff0c;以前经常听到开发对我说&#xff0c;天天的点点点有意思没…

java计算机毕业设计springboot+vue+elementUI永加乡精准扶贫信息管理系统

项目介绍 系统设计的主要意义在于&#xff0c;一方面&#xff0c;对于网站来讲&#xff0c;系统上线后可以带来很大的便利性&#xff0c;精准扶贫网站管理属于非常细致的管理模式&#xff0c;要求数据量大&#xff0c;计算机管理可以提高精确性&#xff0c;更为便利的就是信息…

NF-κB 信号通路调节细胞因子转录

NF-κB 大家族哺乳动物 NF-κB 家族由五种成员组成&#xff1a;RelA/p65、c-Rel、RelB、p50 (NF-κB1) 和 p52 (NF-κB2)&#xff0c;它们可以形成各种异源二聚体或者同源二聚体 (如常见 p50/RelA 异源二聚体)&#xff0c;并通过与启动子的 κB 位点结合来激活大量基因。所有 N…

Mysql常用函数

Mysql常用函数 字段拼接(concat) CONCAT() 函数用于将多个字符串连接成一个字符串 格式&#xff1a; select CONCAT(str1,str2,…) from table_name; #查询商品表&#xff0c;返回一列&#xff1a;商品名称&#xff08;价格&#xff09;。 SELECT concat(prod_name,(,prod…