数据结构-数组

数组的定义

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

线性表数据结构

线性表结构是一种数据结构,用于存储一组有序的数据元素。线性表中的数据元素按照线性的顺序排列,每个元素只有一个直接前驱和一个直接后继。

随机访问特性

随机访问是指可以通过元素的位置或下标(索引)直接访问元素的一种访问方式。对于线性表结构来说,随机访问是指可以根据元素在线性表中的位置,以O(1)的时间复杂度访问到元素。这意味着,无论线性表中有多少元素,访问任何一个元素的时间都是相同的,而不受元素数量的影响。

a[i]_address = base_address + i * data_type_size
arr[i] 首地址 = 数组内存块首地址 + 数据类型大小 * i ,其中i为偏移量。
baseaddress:内存块的首地址。datatype_size:数组中每个元素的大小,比如每个元素大小是4个字节。

数组使用二分法查找元素,时间复杂度是O(logn)

根据下标随机访问的时间复杂度是O(1)

数组低效的插入和删除

数组在插入和删除元素时,可能需要进行大量的元素移动,因此在这些操作上可能不是非常高效。具体来说:

  1. 插入元素:如果要在数组的中间插入一个元素,那么需要将插入位置之后的所有元素都向后移动一位,为新元素腾出空间。这样的操作需要进行大量的数据移动,其时间复杂度为O(n)。

  1. 删除元素:如果要删除数组中的一个元素,那么需要将该元素之后的所有元素都向前移动一位,填补被删除元素留下的空缺。这也需要进行大量的数据移动,其时间复杂度同样为O(n)。

为什么数组要从 0 开始编号,而不是1

在计算机科学中,数组通常从 0 开始编号,而不是从 1 开始编号。这是由于历史原因造成的,并在早期的计算机科学中广泛使用。下面是几个原因:

  1. 方便计算:从 0 开始编号可以更方便地计算元素的地址。例如,对于数组中的元素 a[i],它的地址可以计算为数组的起始地址加上 i * sizeof(a[i])。

  1. 与指针算术的兼容性:在 C 语言中,指针算术的规则是将指针加上一个整数值,该整数值表示要访问的元素在数组中的偏移量。如果从 1 开始编号,则会使指针算术的规则变得复杂,因为需要将指针减去 1,然后加上要访问的元素的编号。

  1. 历史原因:早期的计算机科学家和编程语言设计者普遍采用从 0 开始编号的习惯,这在后来的编程语言中得到了继承和保留。

需要注意的是,并不是所有的编程语言都采用从 0 开始编号的方式。例如,Fortran 编程语言从 1 开始编号,而 MATLAB 编程语言允许用户根据需要选择从 0 或 1 开始编号。

原生数组与容器类

原生数组的优点:

  • 直接存储数据,访问速度快,因为数据在物理内存中是连续存储的。

  • 数组大小固定,不会因为数据量变化而引起额外的内存分配和释放,因此在大量数据读写的场景中更加高效。

原生数组的缺点:

  • 插入和删除元素的效率低,因为需要移动其他元素来填补空缺。

  • 只能存储相同类型的元素,不支持泛型,因此使用起来不够灵活。

  • 数组大小固定,无法动态调整,需要手动重新分配内存空间。

容器类的优点:

  • 可以动态增加和删除元素,不需要手动分配内存空间,使用起来更加灵活。

  • 支持泛型,可以存储不同类型的元素。

  • 提供了丰富的API和算法,如排序、查找、删除等,使用起来更加方便。

容器类的缺点:

  • 在大量数据读写的场景中,效率比原生数组低。

  • 由于底层实现是链表或者动态数组,因此占用的内存空间比原生数组更大。

  • 由于支持泛型,因此在存储元素时需要进行类型检查,会带来额外的性能开销。

java中的数组

Java数组是一个存储固定大小元素的容器,所有元素必须是相同类型的。Java数组实际上是对象,由JVM(Java虚拟机)在运行时创建和管理。

Java数组有以下几个重要的特性:

  1. 声明数组时需要指定数组的长度,一旦数组创建,其长度就不能再改变。

  1. 数组中的元素可以通过索引进行访问,索引从0开始。

  1. Java数组可以存储基本数据类型,也可以存储对象类型。

  1. Java数组是连续的内存块,可以通过内存地址进行访问。

  1. Java数组可以被初始化为指定的值,或者使用默认值初始化。

在Java中,数组使用方括号 [] 来声明,例如:

int[] arr = new int[10];

这将声明一个名为 arr 的整数数组,其长度为10。可以使用 arr[0]、arr[1] 等来访问数组的元素。

Java还提供了一些方便的方法来处理数组,例如:Arrays.sort() 可以对数组进行排序,Arrays.toString() 可以将数组转换为字符串,Arrays.copyOf() 可以复制数组等等。

Java 数组本身是无法实现真正的删除操作的,因为数组的长度是固定的,一旦创建,就不能再改变长度,只能改变数组中的元素值。因此,Java 中实现删除操作的一种常用方法是通过标记待删除元素的方式,然后在后续操作中跳过这些被标记的元素。

具体来说,当需要删除某个元素时,可以将该元素位置的值置为 null,表示该位置的元素已经被删除。然后,在后续操作中遍历数组时,可以通过判断元素是否为 null 来跳过这些已经被删除的元素。当数组中已经被标记删除的元素数量达到一定程度时,可以通过一些特殊的方式来重新组织数组,以减小已删除元素对数组性能的影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值