算法与数据结构 | 数组 / 为什么数组下标从0开始编号?

数组是一种线性表数据结构,使用连续内存空间存储相同类型数据。其随机访问速度快速,但插入和删除操作效率较低。数组下标从0开始,便于计算内存地址,减少CPU指令。虽然容器如ArrayList能简化操作,但无法完全替代数组,尤其在性能敏感的场景中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是数组?

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

如何实现随机访问

  • 线性表
    • 数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向
    • 除了数组,链表、队列、栈等也是线性表结构。
    • 在这里插入图片描述
    • 非线性表
      • 如二叉树、堆、图等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系。
      • 在这里插入图片描述
  • 连续的内存空间和相同类型的数据
    • 在这里插入图片描述
    • 寻址公式:a[i]_address = base_address + i * data_type_size
    • 链表适合插入、删除,时间复杂度 O(1);数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)。

低效的“插入”和“删除”

  • 插入操作
    • 耗时的操作:如果想要在数组中的K位置插入一个新数据X,则K后面的数据都需要往后挪一位置,时间复杂度会大大提高;
    • 简单的操作:将K位置的数值放在末尾,把k位置的放置新的值;
    • 在这里插入图片描述
  • 删除操作
    • 每次删除并非真正的删除,只是记录数据被删除,也就是说后面的数据不会向前移动,而当储存空间不够时,才会触发一次真正的删除操作,进而减少执行时间
    • JVM垃圾回收的核心思想也是如此

警惕数组的访问越界问题

  • 当出现某一个下标在当前数组不存在时,会出现数组越界的现象

容器能否完全替代数组

  • JAVA中的ArrayList 最大的优势就是可以将很多数组操作的细节封装起来,数组的插入、删除、搬移等操作
  • 动态扩容
    • 不需要提前声明指定的大小

为什么数组的下标都是从0开始呢?

  • “下标”最确切的定义应该是“偏移(offset)”。前面也讲到,如果用 a 来表示数组的首地址,a[0] 就是偏移为 0 的位置,也就是首地址,a[k] 就表示偏移 k 个 type_size 的位置,所以计算 a[k] 的内存地址只需要用这个公式:a[k]_address = base_address + k * type_size
  • 如果数组从 1 开始计数:a[k]_address = base_address + (k-1)*type_size;从 1 开始编号,每次随机访问数组元素都多了一次减法运算,对于 CPU 来说,就是多了一次减法指令。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值