数据结构(一):数组
1、数组
1.1、数组定义
数组对应的英文是array,是有限个相同类型的变量所组成的有序集合,数组中的每一个变量被称为元素。
以整型数组为例,数组的存储形式如下图所示。
数组中的 每一个元素也有着自己的下标,只不过这个下标 从0开始,一直到数组长度-1。
数组的另一个特点,是在内存中顺序存储, 因此可以很好地实现逻辑上的顺序表。
数组在内存中的顺序存储,具体是什么样子呢?
内存是由一个个连续的内存单元组成的,每一个内存单元都有自己的地址。在这些内存单元中,有些被其他数据占用了,有些是空闲的。
数组中的每一个元素,都存储在小小的内存单元中,并且元素之间紧密排列,既不能打乱元素的存储顺序,也不能跳过某个存储单元进行存储。
在上图中,橙色的格子代表空闲的存储单 元,灰色的格子代表已占用的存储单元,而红色 的连续格子代表数组在内存中的位置。
1.2、数组的基本操作
1.2.1、读取元素
对于数组来说,读取元素是最简单的操作。 由于数组在内存中顺序存储,所以只要给出一个 数组下标,就可以读取到对应的数组元素。
像这种根据下标读取元素的方式叫作随机读取。
int[] array = new int[]{3,5,6,9};
//打印下标为1的元素
System.out.println(array[1]);
1.2.2、更新元素
要把数组中某一个元素的值替换为一个新 值,也是非常简单的操作。直接利用数组下标, 就可以把新值赋给该元素。
int[] array = new int[]{3,5,6,9};
//给下标为1的元素重新赋值
array[1] = 10;
//打印下标为1的元素
System.out.println(array[1]);
数组读取元素和更新元素的时间复杂度都是O(1)。
1.2.3、插入元素
插入数组元素的操作存在3种情况:
- 尾部插入
- 中间插入
- 超范围插入
尾部插入,是最简单的情况,直接把插入的 元素放在数组尾部的空闲位置即可,等同于更新 元素的操作。
中间插入,稍微复杂一些。由于数组的每一 个元素都有其固定下标,所以不得不首先把插入 位置及后面的元素向后移动,腾出地方,再把要 插入的元素放到对应的数组位置上。
代码实现如下:
public class Demo {private int[] array;private int size;public Demo(int capacity){array = new int[capacity];size = 0;}/*** 数组插入元素* @param element* @param index*/public void insert(int element,int index){//判断访问下标是否超出范围if (index < 0 || index > size){throw new IndexOutOfBoundsException("数组下标越界....");}//从右向左循环,将元素逐个向右挪1位for (int i = size - 1; i >= index; i--) {array[i+1] = array[i];}//腾出的位置放入新元素array[index] = element;size ++;}
}
超范围插入,假如现在有一个长度为6的数组,已经装满了 元素,这时还想插入一个新元素。
这就涉及数组的扩容了。可是数组的长度在 创建时就已经确定了。这该如何是好呢?
此时可以创建一个新数组,长度是旧数组的2倍,再把旧数组中的元素统统复制过去,这样就实现了数组的扩容。
代码如下:
public class Demo {private int[] array;private int size;public Demo(int capacity){array = new int[capacity];size = 0;}/*** 数组插入元素* @param element* @param index*/public void insert(int element,int index){//判断访问下标是否超出范围if (index < 0 || index > size){throw new IndexOutOfBoundsException("数组下标越界....");}//从右向左循环,将元素逐个向右挪1位for (int i = size - 1; i >= index; i--) {array[i+1] = array[i];}//腾出的位置放入新元素array[index] = element;size ++;}/*** 数组扩容*/public void resize(){int[] arrayNew = new int[array.length * 2];//从旧数组复制到新数组System.arraycopy(array,0,arrayNew,0,array.length);array = arrayNew;}}
1.2.4、删除元素
数组的删除操作和插入操作的过程相反,如果删除的元素位于数组中间,其后的元素都需要向前挪动1位。
代码实现如下:
public class Demo {private int[] array;private int size;public Demo(int capacity){array = new int[capacity];size = 0;}public int delete(int index){//判断访问下标是否超出范围if (index < 0 || index >= size){throw new IndexOutOfBoundsException("数组下标越界...");}int deleteElement = array[index];//从左向右循环,将元素逐个向左挪1位for (int i = index; i < size - 1; i++) {array[i] = array[i + 1];}size --;return deleteElement;}
}
插入操作,数组扩容的时间复 杂度是O(n),插入并移动元素的时间复杂度也 是O(n),综合起来插入操作的时间复杂度是 O(n)。至于删除操作,只涉及元素的移动,时 间复杂度也是O(n)。
1.3、数组的优势和劣势
数组拥有非常高效的随机访问能力,只要给 出下标,就可以用常量时间找到对应元素。有一 种高效查找元素的算法叫作二分查找,就是利用 了数组的这个优势。
至于数组的劣势,体现在插入和删除元素方 面。由于数组元素连续紧密地存储在内存中,插 入、删除元素都会导致大量元素被迫移动,影响 效率。
总的来说,数组所适合的是读操作多、写操 作少的场景。
数据结构(一):数组相关推荐
- 数据结构之数组定义及基本操作(转)
数据结构之数组定义及基本操作数据结构中最基本的一个结构就是线性结构,而线性结构又分为连续存储结构和离散存储结构.所谓的连续存储结构其实就是数组.数组本质其实也是数据的一种存储方式,既然有了数据的存储, ...
- 009 数据结构逆向—数组(困难版)
文章目录 前言 数组逆向 通过人物血量查找人物属性 调call取对象 call内追局部变量 逆向加密数组下标 分析人物属性 总结 前言 通过之前的分析,我们已经对数组结构有了一个简单的了解,这次就用幻 ...
- 008 数据结构逆向—数组(简单版)
文章目录 前言 逆向背包数组 一维背包数组 二维背包数组 数组结构分析 总结 前言 对于游戏逆向来说,核心需求其实就只有两个 追踪游戏数据 定位游戏功能call 对于追踪游戏数据来说,单纯从一个寄存器 ...
- 基于java的数据结构学习——数组实现的栈以及简单应用C++实现
基于java的数据结构学习--数组实现的栈以及简单应用的 C++ 实现 源码: // // Created by PC-Saw on 2019/1/3. //#ifndef DATA_STRUCTUR ...
- 数据结构 判断数组元素是否互不相同
4.18 数据结构 判断数组元素是否互不相同 -----题目 设二维数组a.b 含有m*n 个整数.写一个算法判断a,b两个数组中所有元素是否互不相同?输出相关信息 a[4][3]={1,2,3,4, ...
- Java版数据结构之数组模拟环形队列demo
Java版数据结构之数组模拟环形队列demo 我的代码仓库:https://github.com/zhuangbinan/datastructure 类 CircleArray package clu ...
- 数据结构之数组及动态数组剖析
数据结构之数组及动态数组剖析 文章目录 数据结构之数组及动态数组剖析 概述 动态数组实现的原理 实践编写动态数组类 时间复杂度分析 数组对数器 参考代码 相关链接 公众号 参考 概述 数组是在程序设计 ...
- 数据结构(数组结构、链表结构)
本来第一篇文章准备写点关于map的,但是考虑到map中可能也牵扯到数据结构,所以先随便写点就当做铺垫吧! 数据结构: 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 1.集合 数据结构中的 ...
- 第七周--数据结构--队列数组
/* *第七周--数据结构--队列数组 *Copyright (c) 2015 烟台大学计算机与控制工程学院 *All right reserved. *文件名称:li ...
- 数据结构(数组)的特点以及优缺点
数据结构(数组)的特点以及优缺点 数组这种数据结构是我们在java开发中非常常见的.所以借用这篇文章来分析数组的特点以及他的优缺点. 特点一 数组的读取和更改数据的效率是所有数据据结构中最高的. 数组 ...
最新文章
- shell 脚本简单入门
- Java学习之键盘输入输出小程序
- nodejs HelloWorld
- NLP免费直播 | 两周讲透图卷积神经网络、BERT、知识图谱、对话生成
- 【C语言】控制台窗口图形界面编程(三)窗口相关设置
- 百度地图根据经纬度计算瓦片行列号
- 重新解读DDD领域驱动设计(一)
- mybatis-plus分页查询_SpringBoot + MyBatisPlus 快速入门
- python 工具箱_Python交易工具箱:通过指标子图增强图表
- 舰船目标检测的学习笔记(legacy)
- CB Insights,201608月174家独角兽榜单出炉,上榜的33家中国公司都是谁?
- pandas入门(3)
- [转]计算机四级网络工程师思维导图--操作系统部分
- makefile suppress echoing the actual command @
- 怎样把PDF格式转换成可编辑的PPT幻灯片?
- IC 后端仿真: process corner 和 PVT
- 稀疏表示中KL1p库的配置及Demo
- 按摩界的“爱马仕”,拯救你的发际线,失眠、职业病通通消失,爽爆了!
- 新年警惕:多数手机银行App存安全隐患
- 如何在VI中使用小键盘上的数字键