为什么数组下标从0开始? 从1开始不是更符合人类的习惯吗?
带着这个问题,我们来讨论一下数组的线性表数据结构。
什么是数组? 数组是一种线性数据结构,它使用连续的内存空间来存储一组相同数据类型的数据。
什么是线性表? 数据结构是线性排列的,一条数据只有前后两个方向。 例如:还有队列、栈、链表。
什么是非线性表? 数据结构是非线性排列的,数据之间的关系并不简单。 例如:二叉树、多树、图。
连续的存储空间,正是因为这个特性,数组才可以被随机访问。 通过下标查询的时间复杂度为O(1)。 然而,插入和删除操作通常会整体执行翻译操作,以保证内存的连续性。
对于正常操作(移动),插入的时间复杂度是多少? 有一个大小为n的数组(大小可以自动扩展)。 如果我们想在下标y的位置插入一个元素,我们需要将下标y~n的元素向后移动一位。 如果在数组尾部插入元素,则无需移动,时间复杂度为O(1)。 平均而言,数组插入的时间复杂度为 O(n)。
我们来看一下删除操作。 如果我们要删除下标为y的元素,以保证内存空间的连续性。 我们还需要移动 y 之后的元素。 同样,删除操作与插入操作相同。 最坏情况时间复杂度为 O(n),最好情况时间复杂度为 O(1),平均时间复杂度为 O(n)。
现在我们来思考一下开头的问题:为什么大多数编程语言中的数组都是从0而不是1开始编号的?
例如:array int a[6],a是数组的首地址,a[0]实际上表示地址空间向后偏移0位,或者a,以此类推,a[y]表示偏移k 4言语向后。 该节的位置(int类型占用4个字节)。
给出推入公式:a[y] = + y * 。
如果下标从1开始,此时的推入公式为:a[y] = + (y-1) *。
对于CPU来说,y-1意味着多了一条指令计算。 因此,选择以索引 0 开始数组的索引。