定义
数组是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
线性表
线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。数组、链表、栈、队列等也是线性表结构。
非线性表
非线性表中,数据之间并不是简单的前后关系,比如二叉树、堆、图等。
低效的“插入”和“删除”
-
插入操作
- 假设数组的长度为 n,现在,如果我们需要将一个数据插入到数组中的第 k 个位置。为了把第 k 个位置腾出来,给新来的数据,我们需要将第 k~n 这部分的元素都顺序地往后挪一位。 删除操作
- 跟插入数据类似,如果要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,不然中间就会出现空洞,内存就不连续了。
数组和链表的区别
数组是支持随机访问,根据下标随机访问的时间复杂度为O(1)。
数组用一块连续的内存空间,来存储相同类型的一组数据,最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为 O(n)。在平时的业务开发中,可以直接使用编程语言提供的容器类,但是,如果是特别底层的开发,直接使用数组可能会更合适。
为什么很多编程语言中数组都从0开始编号
- 从数组存储的内存模型上来看,“下标”最确切的定义应该是“偏移(offset)”,如果用 a 来表示数组的首地址,a[0] 就是偏移为 0 的位置,也就是首地址,a[k] 就表示偏移 k 个 type_size 的位置,所以计算 a[k] 的内存地址只只需要用这个公式:
a[k]_address = base_address + k * type_size
- C 语言设计者用 0 开始计数数组下标,之后的高级语言都效仿了 C 语言,或者说,为了在一定程度上减少 C 语言程序员学习 Java 的学习成本,因此继续沿用了从 0 开始计数的习惯。