笔记:数组

前言

数组,大家看到这两个字,一定非常熟悉,它不仅是编程语言中的一种数据结构,还是一种最基础的数据结构,这次再一次理解一下数组。

什么是数组

数组(Array)是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据

  • 线性表:数据排成像一条线一样的结构。线性表结构包括数组、链表、队列、栈等
  • 非线性表:数据之间不是简单的前后关系。非线性表包括二叉树、堆、图。

一维数组的寻址公式

a[i]_address = base_address + i * data_type_size;
复制代码

base_address 表示开始数组的地址位置,data_type_size表示每个元素的大小,比如 int类型就是4个字节。

二维数组 m * n的寻址公式

a[i][j]== base_address + (i*n+j)* data_type_size
复制代码
数组的特点

面试的时候,面试官可能会问你这样的问题:数组和链表之间的区别。 大多都是从增删改查方面说起。 链表相对于数组来说,更容易插入和删除,时间复杂度为O(1),数诅更适合随机访问,根据下标访问的时间复杂度为O(1)。

数组是线性表数据结构,存储空间是连续的,这就导致插入和删除时,要多做一些搬移工作。

比如插入操作,举个例子 数组araay中有a、b、c、d、e、f这六个元素,现在需要在下标为2的位置插入新的元素h。

这就需要将下标为2之后的所有元素顺序向后挪一位,然后再进行赋值。 插入的平均时间复杂度为O(n) 删除操作类似,删除位置之后的元素需要往前挪一位。

删除操作可以每次删除的时候记一个标志,等内存不足的时候再做真正的从删除,提高效率,这也是JVM标记清除垃圾回收算法的核心思想

容器能否代替数组

容器类比如说ArrayList,学过Java知识的同学会非常熟悉。

ArrayList相比数组来说,可以说是将数组操作的细节封装起来,比如插入、删除等操作。另一个特点就是它支持动态扩容,比如当一个容器类无法满足插入操作时,它会申请一个更大的存储空,并把之前容器中的数据复制过来。

因此,如果知道数据的大小,最好事前设置好数据大小,避免多余的数据挪动。

既然容器类比数组有这两方面的优势,是不是就可以代替数组了呢,其实有些时候,用数组更合适一些

  1. ArrayList无法存储基本数据类型,像int、long,需要封装成Integer、Long类。
  2. 如果数据大小已知,并且操作非常简单,也可以直接使用数组。
  3. 当表示多维的时候,数组往往会更直观。
为什么数组的下标是从零开始

这里说下“下标”,所谓下标最确切的定义是“偏移”,如果用a表示数组的收地址,a[0]就是偏移为0的位置,还记得上述我们的寻址公式么:

a[i]_address = base_address + i * data_type_size;
复制代码

如果下标是1的话,寻址公式就变成这样:

a[i]_address = base_address + ()i-1) * data_type_size;
复制代码

可以看出这会比上面的公式多一步:i -1,多了一次CPU运算。 这就是为什么下标从零开始的原因,还有一个原因就是历史原因了,这种更能让大众接受,久而久之就这样传下来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值