当前位置: 首页 > news >正文

一文读懂:认识与探索数组——基础数据结构的基石

数组

数据结构分类

数据结构中数据按逻辑结构分为:线性结构、非线性结构

  • 常用的线性结构有:线性表(顺序存储、链式存储)、栈、队列、双端队列、串(一维数组);
  • 常见的非线性结构有:二维数组、多维数组、矩阵、散列表、树、堆、图。

线性结构的特征

    • 集合中必存在唯一的一个"第一个元素";
    • 集合中必存在唯一的一个"最后的元素";
    • 除最后元素之外,其它数据元素均有唯一的"后继";
    • 除第一元素之外,其它数据元素均有唯一的"前驱"。

线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。

如(a0,a1,a2,…,an),a0为第一个元素,an为最后一个元素,此集合为一个线性结构的集合。

非线性结构,其逻辑特征是一个节点元素可能有多个直接前驱和多个直接后继。

线性数据结构存储方式

    • 顺序存储结构:顺序表
    • 链式存储结构:链表

常用线性数据结构

常用的线性结构有:线性表(顺序存储、链式存储)、栈、队列、双端队列、串(一维数组)。

线性表(Linear List)就是数据排成像一条线一样的结构,数据只有前后两个方向。

线性表分为顺序存储和链式存储。

按照人们的生活习惯,存放东西时,一般是找一块空间,然后将需要存放的东西依次摆放,这就是顺序存储。

计算机中的顺序存储是指在内存中用一块连续的地址空间依次存放数据元素,用这种方式存储的线性表叫顺序表。其特点是表中相邻的数据元素在内存中存储位置也相邻,如下图:

在这里插入图片描述

在这里插入图片描述

概念

  • 一维数组是最简单、最常用的线性数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
  • 数组(Array)是有限个相同类型的变量所组成的有序集合,数组中的每一个变量被称为元素。
  • 每个元素都有下标,下标从0开始
  • 一维数组是顺序存储的线性表。二维数组和多维数组的逻辑结构属于非线性结构。
  • 连续的内存空间和相同类型的数据是随机访问的前提。

数组的优缺点

  • 优点:具有随机访问的特性。
  • 缺点:删除、插入数据效率低。

操作数组 - 增删改查

需求:自定义数组工具类,实现增删改查等功能

public class MyArray<E> {// 数组最大容量private static final int MAX_CAPACITY = Integer.MAX_VALUE-8;// 数组默认容量private static final int DEFAULT_CAPACITY = 10;// 数组private Object[] elementData;// 数组中当前的数据量private int size;// 构造方法public MyArray() {elementData = new Object[DEFAULT_CAPACITY];}// 构造方法public MyArray(int initialCapacity){if(initialCapacity > MAX_CAPACITY)throw new RuntimeException("initialCapacity过大");if(initialCapacity <= 0)throw new RuntimeException("initialCapacity必须大于0");elementData = new Object[initialCapacity];}// 在数组尾部添加元素public void add(E e){if(size >= elementData.length){grow();}elementData[size] = e;size++;}// 数组的扩容public void grow(){int oldCapacity = elementData.length;int newCapacity = oldCapacity*2;elementData = Arrays.copyOf(elementData, newCapacity);}// 在数组的下标位置添加元素public void add(int index,E e){if(size >= elementData.length){grow();}if(isElementIndex(index)){// 数组index之后的元素全部往后移位for (int i = index; i < size-1; i++) {elementData[i] = elementData[i+1];}// 给数组第index个元素赋值elementData[index] = e;size++;}else{throw new RuntimeException("下标越界");}}// 判断下标是否越界public boolean isElementIndex(int index){if(index >= 0 && index < elementData.length){return true;}return false;}// 根据下标位置删除元素public Object remove(int index){if(isElementIndex(index)){Object oldValue = elementData[index];int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null;return oldValue;}else{throw new RuntimeException("下标越界");}}//根据下标设置元素public Object set(int index, E e){if(isElementIndex(index)){Object oldValue = elementData[index];elementData[index] = e;return oldValue;}else{throw new RuntimeException("下标越界");}}//根据下标查找元素public Object get(int index){if(isElementIndex(index)){return elementData[index];}else{throw new RuntimeException("下标越界");}}//获取元素个数public int size(){return size;}// 数组的字符串表示public String toString(){StringBuilder sb = new StringBuilder("[");for (int i = 0; i < size; i++) {if(sb.length() != 1){sb.append(",");}sb.append(elementData[i]);}sb.append("]");return sb.toString();}
}
public class Test {public static void main(String[] args) {MyArray<String> myArray = new MyArray<>();System.out.println("数组添加元素:");myArray.add("张三");myArray.add("李四");myArray.add("王五");myArray.add("赵六");myArray.add("吴七");System.out.println("获取数组中元素的个数为:" + myArray.size());System.out.println("数组中数据为:" + myArray);System.out.println("--------------------------------");//数组修改System.out.println("修改指定下标上的元素:");myArray.set(1,"abc");System.out.println("获取数组中元素的个数为:" + myArray.size());System.out.println("数组中数据为:" + myArray);System.out.println("--------------------------------");//数组删除元素System.out.println("删除指定下标上的元素:" + myArray.remove(0));System.out.println("获取数组中元素的个数为:" + myArray.size());System.out.println("数组中数据为:" + myArray);System.out.println("--------------------------------");//数组查询元素System.out.println("查询指定下标上的元素:" + myArray.get(0));System.out.println("获取数组中元素的个数为:" + myArray.size());System.out.println("数组中数据为:" + myArray);System.out.println("--------------------------------");}
}

相关文章:

  • MyBatisPlus学习一:快速入门
  • MySQL中的连接池
  • vue3 指令详解
  • RabbitMQ消息可靠性保证机制3--消费端ACK机制
  • 四元数分析(Quaternion Analysis)在故障诊断中的应用
  • 手机录屏没有声音?让你的录屏有声有色
  • 鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台
  • 【2023年中国高校大数据挑战赛 】赛题 B DNA 存储中的序列聚类与比对 Python实现
  • 详解ajax、fetch、axios的区别
  • 2023 CSIG青年科学家会议丨多模态大模型时代下的文档图像处理
  • C# windows服务程序开机自启动exe程序
  • CV之DL之Yolo:计算机视觉领域算法总结—Yolo系列(YoloV1~YoloV8各种对比)的简介、安装、案例应用之详细攻略
  • Linux之Shell编程
  • ubuntu apt 更换阿里云源
  • Linux常用命令大全<二>
  • 「面试题」如何实现一个圣杯布局?
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • CODING 缺陷管理功能正式开始公测
  • Druid 在有赞的实践
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • es的写入过程
  • Python - 闭包Closure
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • vuex 学习笔记 01
  • windows下如何用phpstorm同步测试服务器
  • windows下使用nginx调试简介
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 服务器从安装到部署全过程(二)
  • 聊聊flink的TableFactory
  • 前端攻城师
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 微信小程序开发问题汇总
  • 进程与线程(三)——进程/线程间通信
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​ArcGIS Pro 如何批量删除字段
  • # Java NIO(一)FileChannel
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (八)c52学习之旅-中断实验
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三分钟)速览传统边缘检测算子
  • (十三)Flask之特殊装饰器详解
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)http协议
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)大型网站架构演变和知识体系
  • (转)关于多人操作数据的处理策略
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...