一、什么是数组

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

这个定义里有几个关键词。

1.1 线性表

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

概念是非线性表,比如二叉树、堆、图等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系。
image.png

1.2 连续的内存空间和相同类型的数据

image.png

很多时候我们并不是要去死记硬背某个数据结构或者算法,而是要学习它背后的思想和处理技巧,这些东西才是有价值的。

二、警惕数组的访问越界问题

访问数组的本质就是访问一段连续内存,只要数组通过偏移计算得到的内存地址是可用的,那么程序可能不会报任何错误。

三、容器能否完全替代数组?

使用数组更适合的场景:

  • Java ArrayList 无法存储基本类型,如果特别关注性能,或者希望使用基本类型,就可以选用数组。
  • 如果数据大小事先已知,并且对数据的操作非常简单,用不到 ArrayList 提供的大部分方法,也可以直接使用数组。
  • 当要表示多维数组时,用数组往往会更加直观。

对于业务开发,直接使用容器就足够了,省时省力。毕竟损耗一丢丢性能,完全不会影响到系统整体的性能。但如果是做一些非常底层的开发,比如开发网络框架,性能的优化需要做到极致,这个时候数组就会优于容器,成为首选。

四、为什么大多数编程语言中,数组要从 0 开始编号,而不是从 1 开始?

主要是历史原因。C 语言设计者用 0 开始计数数组下标,之后的 Java、JavaScript 等高级语言都效仿了 C 语言,或者说,为了在一定程度上减少了 C 语言程序员学习 Java 的成本,因此继续沿用了从 0 开始计数的习惯。

五、小结

数组用一块连续的内存空间,来存储相同类型的一组数据,最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为 O(n)。
在平时的业务开发中,我们可以直接使用编程语言提供的容器类,但是,如果是特别底层的开发,直接使用数组可能会更合适。