1.定义

1.1概念

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

线性表:线性表就是数据排成像一条线一样的结构,每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表,队列,栈等也是线性结构。
04数组

而与他对立的概念是非线性表,比如二叉树,堆,图。之所以叫非线性,是因为,在非线性表中,数据之前并不是简单的前后关系。

04数组

连续的内存空间和相同的数据类型:有此特性,才可实现随机访问。但是在插入和删除时,为保持内存连续性,需要做大量的数据搬移工作。

1.2如何通过下标随访访问?

拿一个长度为10的int类型数组 int[] a = new int[10]举例。下图中,计算机给数据a[10], 分配了一块连续内存空间1000~1039,其中,内存块的首地址为base_address=1000.
04数组
技术机会给每个内存单元分配一个地址,计算机通过地址来访问内存中的数据。当计算机需要随机访问数组的某个数组中的元素时,它会首先通过下面的寻址公司,计算该元素存储的内存地址:

a[i]_address = base_address + i * data_type_size

其中 data_type_size 表示数组中每个元素的大小。在这里,array中类型为 int, 所以 data_type_size为4个字节。

2.数组插入

假设数组长度为n, 插入的位置为k,则 k 的取值范围为 [0, n-1]。

最好: k最后一个位置,不需要移动数据,复杂度为 O(1).

最坏: k为第一个位置,需要移动n个数据,复杂度为O(n).

平均: 插入arr每个位置的概率是一样的,则 (1+2+3+…n)/n = (n+1)/2 -> O(n)

3.数组删除

假设数组长度为n, 插入的位置为k,则 k 的取值范围为 [0, n-1]。

最好: k最后一个位置,不需要移动数据,复杂度为 O(1).

最坏: k为第一个位置,需要移动n个数据,复杂度为O(n).

平均: 插入arr每个位置的概率是一样的,则 (1+2+3+…n)/n = (n+1)/2 -> O(n)

4.容器与数组比较

容器(比如ArrayList等)是否能够完全替代数组?ArrayList的优势

  • 动态扩容
  • 封装对数组的操作细节,操作便利

5.数组编号为啥从0开始

5.1 原因1

从数组存储的内存模型上看,“下标”最确切的定义是“偏移(offset)”。下标从0开始的寻址公式:

a[k]_address = base_address + k * type_size

但是,如果数组从1开始计数,计算数组元素a[k]的内存地址会变为:

a[k]_address = base_address + (k-1) * type_size

两者的区别是,从1开始,cpu多了一次 (k-1)的减法指令。数组作为非常基础的数据结构,通过下标随机访问数组元素又是其非常基础的编程操作,效率的优化就要尽可能做到极致。所以为了减少一次减法操作,数组选择了从 0 开始编号,而不是从 1 开始。

5.2 原因2

历史原因,C语言从0开始。

相关文章:

  • 2021-07-13
  • 2021-12-26
  • 2021-10-17
  • 2021-07-25
  • 2021-08-07
  • 2021-09-03
  • 2022-02-08
  • 2022-12-23
猜你喜欢
  • 2021-12-25
  • 2022-12-23
  • 2021-11-10
  • 2021-06-06
  • 2022-12-23
  • 2021-06-28
  • 2022-12-23
相关资源
相似解决方案