- 数组
① 数组的定义上有个必要条件是:“存储在连续的内存空间里”的有序元素序列
② “JS 数组未必是真正的数组”
③ 区分JS数组 和 常规数组
常规数组: 数组元素内容是一种类型的元素,如const arr = [1,2,3,4],在存储空间是连续内存的
JS数组: 数组元素内容不是同一种类型的元素,如const arr = ['haha', 1, {a:1}],则在存储上是一段非连续空间。此时,JS 数组不再具有数组的特征,其底层其实是由链表来实现的
链表
① 在存储上是无序的,依靠next指针指向下一个node结点
② JS 中的链表,是以嵌套的对象的形式来实现的链表 与 数组
① 我们假设数组的长度是 n,那么因增加/删除操作导致需要移动的元素数量,就会随着数组长度 n 的增大而增大,呈一个线性关系。所以说数组增加/删除操作对应的复杂度就是 O(n);
在链表中,添加和删除操作的复杂度是固定的——不管链表里面的结点个数 n 有多大,只要我们明确了要插入/删除的目标位置,那么我们需要做的都仅仅是改变目标结点及其前驱/后继结点的指针指向。
因此我们说链表增删操作的复杂度是常数级别的复杂度,用大 O 表示法表示为 O(1)
② 在数组中,我们直接访问索引、可以做到一步到位,这个操作的复杂度会被降级为常数级别(O(1));
随着链表长度的增加,我们搜索的范围也会变大、遍历其中任意元素的时间成本自然随之提高。这个变化的趋势呈线性规律,用大 O 表示法表示为 O(n)
总结
链表的插入/删除效率较高,而访问效率较低;
数组的访问效率较高,而插入效率较低