数据结构-2.顺序表

news2024/12/23 10:09:26

1.线性表

线性是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表有: 顺序表 , 链表 , 栈 , 队列...

线性表在逻辑上是线性结构, 也就是连续的一条直线 . 但是在物理结构上并不是连续的, 线性表在物理上存储时, 通常以数组和链式结构的形式存储.

2.顺序表

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

2.1接口的实现

public class MyArrayList {
    private int[] elem;//用来存放数据元素
    private int usedSize;//代表当前顺序表当中的有效数据个数

    private static final int DEFAULT_SIZE = 10;//顺序表的空间大小
    public MyArrayList() {
        this.elem = new int[DEFAULT_SIZE];
    }

    //自给容量
    public MyArrayList(int initCapacity) {
        this.elem = new int[initCapacity];
    }

    //判断顺序表空间是否装满了
    public boolean isFull() {
        if(this.usedSize == this.elem.length) {
            return true;
        }
        return false;
    }

    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //进入if说明顺序表空间不足,需要扩容
        if(isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //顺序表空间足够,还没满
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    // 在 pos 位置新增data元素
    public void add(int pos, int data) {
        if(pos < 0 || pos > this.usedSize) {
            throw new RuntimeException(pos+" 位置不合法! ");
            //System.out.println("位置不合法! ");
            //return;
        }

        //顺序表空间不足
        if(this.isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //顺序表空间足够
        int tmp = this.usedSize;
        while(tmp > pos) {
            this.elem[tmp] = this.elem[tmp-1];
            tmp--;
        }
        this.elem[pos] = data;
        this.usedSize++;
    }

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            //如果是两个引用类型的数据判断是否相等,则用equals或者compareTo
            //区别就是equals的返回值是true或者false而compareTo的返回值是int
            if(this.elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            //如果是两个引用类型的数据判断是否相等,则用equals或者compareTo
            //区别就是equals的返回值是true或者false而compareTo的返回值是int
            if(this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

    // 获取 pos 位置的元素
    public int get(int pos) {
        //pos不合法
        checkPos(pos);
        //pos合法
        return this.elem[pos];
    }
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        checkPos(pos);
        this.elem[pos] = value;
    }

    private void checkPos(int pos) {
        if(pos < 0 || pos >= this.usedSize) {
            throw new RuntimeException(pos+" 位置不合法! ");
        }
    }

    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        int index = indexOf(toRemove);
        if(index == -1) {
            System.out.println("没有这个数据! ");
            return;
        }
        while(index < usedSize-1) {
            this.elem[index] = this.elem[index+1];
            index++;
        }
        usedSize--;
    }

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

    // 清空顺序表
    public void clear() {
          this.usedSize = 0;
    }

    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(elem[i] + " ");
        }
        System.out.println();
    }

温馨提示: 初学者最好自己能实现顺序表的接口,后面使用ArrayList类才不至于只知其一不知其二.

3.AraayList介绍

在集合框架中,ArrayList是一个普通的类, 实现了List接口,具体框架图如下:

说明:

1.ArrayList是以泛型方式实现的, 使用时必须要先实例化

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

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

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

5.和Vector不同, ArrayList不是线程安全的, 在单线程下可以使用, 在多线程下可以选择Vector或者

CopyOnWriteArrayList

6.ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表.

4.ArrayList的使用

4.1ArrayList的构造

ArrayList()无参构造很容易,就不做解释了, 其实就跟2.1中MyArryList的无参构造一样,名字一换就行了.

2.重点解释第二个构造方法.

List<Integer> list2 = new LinkedList<>();
        list2.add(1);
        list2.add(2);
        list2.add(3);
        List<Integer> list3 = new ArrayList<>(list2);
        list3.add(44);
        System.out.println(list3);

发现list3中包含list2的元素,  构造出来的新的顺序表list3包含list2中所有的元素, 这就是这种构造方法的意义所在.

4.2 ArrayList常见操作

ArrayList 虽然提供的方法比较多, 但是常用方法如下所示:

还有三个常用方法 : 

int   indexOf(Object o)    返回第一个o所在下标
int   lastIndexOf(Object o)     返回最后一个o的下标
List<E>  subList(int fromlndex, int tolndex)      截取部分list

  以下是set方法和 subList方法的代码示例:

ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(666);
        list1.add(321);
        list1.add(43);
        list1.add(123);
        list1.add(32);
        list1.add(55);
        List<Integer> list2 = list1.subList(1,4);//[1,4)
        list2.set(0,555);
        System.out.println(list2);//一般情况下,能够直接通过sout输出引用指向对象当中的内容的时候,
        //此时一定重写了toString方法,要么是父类,要么是自己重写了

其余方法不做代码解释, 自行实现即可

4.3ArrayList的遍历

ArrayList 可以使用三种方式遍历: for循环 + 下标, for-each , 使用迭代器.

for (int i = 0; i < list1.size(); i++) {
            System.out.print(list1.get(i)+ " ");
        }
        System.out.println();
        System.out.println("===========================");
        //3.for-each遍历
        for(Integer x : list1) {
            System.out.print(x + " ");
        }
        System.out.println();
        System.out.println("============================");

        //4.迭代器遍历
        //第一种写法:(父类)
        /**/Iterator<Integer> it = list1.iterator();
        while(it.hasNext()) {
            System.out.print(it.next() + " ");
        }
        System.out.println();

        //第二种写法:(子类)
        ListIterator<Integer> listIterator = list1.listIterator();
        while(listIterator.hasNext()) {
            System.out.print(listIterator.next() + " ");
        }
        System.out.println();

        System.out.println("===================================");

        //从后往前遍历:
        ListIterator<Integer> listIterator2 = list1.listIterator(list1.size());

        while(listIterator.hasPrevious()) {
            System.out.print(listIterator2.previous() + " ");
        }
        System.out.println();

注意: 

1. ArrayList最长使用的遍历方式是: for循环+下标 以及 foreach

2. 迭代器是设计模式的一种, 后面的文章再细说

4.4ArrayList的扩容机制

从上图可以看出,即使list的长度为1,空间已满,还是可以往里添加元素. 其中的玄机一定在add方法中.

鼠标放在add上,按住ctrl(键盘最左下),鼠标左键点过去可以看到 ↓

刚开始没add时,size = 0;

所以,  minCapacity = size + 1 = 1;

补充:  Java中 在写AarryList时, 就定义了一个常量 DEFAULT_CAPACITY = 10; 同样的,在这里也可以发现  elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA  不相信可以自查.

 

继续解释扩容机制:

总结: 

1. 检测是否真正需要扩容, 如果是调用grow准备扩容

2. 预估需要的空间大小

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

 如果需要的大小超过预估的1.5倍大小,则按照所需大小扩容

3. 使用copyOf进行扩容

5.ArrayList的具体使用

5.1杨辉三角

public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();


        List<Integer> row = new ArrayList<>();
        row.add(1);
        ret.add(row);
        //上面已经处理完第一行了
        //下面开始处理第二行
        for (int i = 1; i < numRows; i++) {
            List<Integer> curRow = new ArrayList<>();
            curRow.add(1);//新的一行的第一个值
            //这里处理中间列
            //拿到上一行
            List<Integer> prevRow = ret.get(i-1);
            for (int j = 0; j < i; j++) {

                int x = prevRow.get(j) + prevRow.get(j-1);
                curRow.add(x);
            }

            curRow.add(1);//新的一行的最后一个值
            ret.add(curRow);
        }
        return ret;
    }

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

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

相关文章

5-----RYZ维修工具 操作界面预览与功能操作解析 刷机 解锁 修复参数等等

以上是工具选项功能的界面预览 。通过预览可以看到很多功能选项。此类工具涵盖了很多操作区域。需要根据自己机型的实际需求来操作。根据开发者的描述。此工具有一下功能。包含mtk刷机 分区修复。9008刷机 备份基带efs等等。 高通操作区域 高通修复串码 高通修改写入基带qc…

石化盈科PMO总经理任志婷受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 石化盈科信息技术有限责任公司运营管理部总经理兼PMO总经理任志婷女士受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾&#xff0c;演讲议题为“激活关键的少数派——项目经理培养体系的设计实践”。大会…

无人机视角下落水救援检测数据集

无人机视角下落水救援检测数据集&#xff0c;利用无人机快速搜索落水者对增加受害者的生存机会至关重要&#xff0c;该数据集共收集12万帧视频图像&#xff0c;涵盖无人机高度从10m-60m高度&#xff0c;检测包括落水者&#xff08;11万标注量&#xff09;、流木&#xff08;900…

TCP/IP - ICMP

目录 1. 帧格式2. ICMPv4消息类型(Type = 0,Code = 0)回送应答 /(Type = 8,Code = 0)回送请求(Type = 3)目标不可达(Type = 5)重定向(Type = 11)ICMP超时(Type = 12)参数3. ICMPv6消息类型回见TCP/IP 对ICMP协议作介绍 ICMP(Internet Control Message Protocol…

什么是快充协议,最常见的快充协议有哪些

什么是快充协议 随着手机快充的出现大家都知道快充技术但很多人确不知道快充协议&#xff0c;在快充技术里快充协议是必不可少的&#xff0c;那么今天我们就来探讨一下什么是快充协议&#xff1f; 快充协议是一种通过提高充电效率来缩短设备充电时间的电池充电技术。它通过在充…

商淘云九周年 分账系统助力企业合规发展

从2015到2024年&#xff0c;商淘云电商服务品牌已走过整整九个春秋。这九年&#xff0c;是商淘云不断发展壮大&#xff0c;深化品牌建设服务&#xff0c;并取得显著成效的九年&#xff0c;也是见证中国电商迅速崛起的九年。我们回顾九年的风雨历程&#xff0c;感受到企业的成长…

Python计算机视觉 第9章-图像分割

Python计算机视觉 第9章-图像分割 图像分割是将一幅图像分割成有意义区域的过程。区域可以是图像的前景与背景或图像中一些单独的对象。这些区域可以利用一些诸如颜色、边界或近邻相似性等特征进行构建。 9.1 图割&#xff08;Graph Cut&#xff09; 图割&#xff08;Graph…

SOMEIP_ETS_111: SD_Empty_Entries_Array

测试目的&#xff1a; 验证DUT能够忽略声明了条目数组长度为零的SubscribeEventgroup消息。 描述 本测试用例旨在确保DUT在接收到一个Entries数组长度为零的SubscribeEventgroup消息时&#xff0c;能够正确地忽略该消息&#xff0c;不对其进行解释或响应。 测试拓扑&#x…

【机器学习-监督学习】朴素贝叶斯

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

数据中台建设(七)——数据体系建设

数据体系建设 数据中台是企业数据汇集地&#xff0c;但并不是简单的数据堆积&#xff0c;而是进行分层建模&#xff0c;数据体系建设最终呈现一套完整、规范、准确的数据。数据体系建设就是大数据中数据仓库建设。如下图&#xff1a; 贴源数据层ODS(Operational Data Store)…

python的数据类型详解

python基础 认识python基本类型python的注释风格有三种&#xff08;也可以说是两种&#xff09;python的对齐方式python的多行语句折断字符串类型的“计算”列表的常见用法元组的常见用法集合set的常见用法字典的常见用法bytes类型python的输入输出python中的引用 认识python基…

基于环境音频和振动数据的人类活动识别

这篇论文的标题是《Recognition of human activities based on ambient audio and vibration data》&#xff0c;作者是 Marcel Koch 等人&#xff0c;发表在 IEEE Access 期刊上。论文提出了一种基于环境音频和振动数据的分布式多传感器系统&#xff0c;用于识别人类活动。以下…

窗口框架frame(HTML前端)

一.窗口框架 作用&#xff1a;将网页分割为多个HTML页面&#xff0c;即将窗口分为多个小窗口&#xff0c;每个小窗口可以显示不同的页面&#xff0c;但是在浏览器中是一个完整的页面 基本语法 <frameset cols"" row""></frameset><frame…

好的知识竞赛策划公司哪里去找

活动不管多大&#xff0c;都败在策划公司手中&#xff01;要找到好的策划公司&#xff0c;可以考虑以下几个途径&#xff1a; 1.搜索引擎&#xff1a; 通过搜索引擎&#xff0c;可以找到行业内有实力的优秀策划公司。尽管有些公司是打广告&#xff0c;那总比没钱打广告的公司…

Codes 开源研发项目管理平台——敏捷测试管理创新解决方案

前言 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台&#xff0c;支持云端认证、本地部署、全部功能开放&#xff0c;并且对30人以下团队免费。它通过整合迭代、看板、度量和自动化等功能&#xff0c;简化测试协同工作&#xff0c;使敏捷测试更易于实施。并提供低成本的…

C#与Python脚本使用共享内存通信

实现的功能&#xff1a; C#中读取一张图像&#xff0c;通过共享内存传给python脚本进行处理后将图像进行存储&#xff0c;C#读取处理过后的图像。 C#与python通信有好几种&#xff0c;为什么选择共享内存&#xff1f; 处理图像的速度需求是1秒钟处理5张以上&#xff0c;通过…

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】 《中文Python穿云箭量化平台》是纯Python开发的量化平台&#xff0c;因此其中很多Python模块&#xff0c;我们可以自己设计新的量化工具&#xff0c;例如自己新的行…

1----安卓机型修复串码 开启端口 檫除基带 支持高通与MTK机型工具预览与操作解析

在玩机过程中。很多玩家会碰到各种各样的故障 。其中最多的就在于基带 串码类。由于目前的安卓机型必须修改或者写入串码等参数必须开启端口。而一些初级玩友不太了解开启参数端口的步骤。这个工具很简单的为安卓机型开启端口。并且操作相对简单。 此工具基本功能 1-----可以…

linux入门到实操-4 linux系统网络配置、连接测试、网络连接模式、修改静态IP、配置主机名

教程来源&#xff1a;B站视频BV1WY4y1H7d3 3天搞定Linux&#xff0c;1天搞定Shell&#xff0c;清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料&#xff08;包含课程同版本linux系统文件等内容&#xff09;&#xff0c;供大家学习交流下载&#xff1a;…

第15-03章:类的加载与ClassLoader的理解

3、类的加载与ClassLoader的理解 5.1.类加载(ClassLoad)的理解: a.类加载器的作用: 1.将class文件字节码内容加载到内存中&#xff0c;并将这些静态数据转换成方法区的运行时数据结构&#xff0c;然后在堆中生成一个代表这个类的java.lang.Class对象&#xff0c;作为方法区中…