数组很少有人做插入和删除操作, 数组和链表的复杂度分析

这个表格描述的是两种常见数据结构------数组和链表------在插入/删除和查询操作上的时间复杂度。

数组

  1. 插入/删除:

    对于数组,插入或删除操作的时间复杂度是 O(n)O(n)O(n),原因是数组是连续存储的,当你在数组的某个位置插入或删除元素时,后面的元素必须向前或向后移动,最坏情况下,这一操作需要移动整个数组中的元素。

    例子:

    假设我们有一个数组 [1, 2, 3, 4],现在我们要在数组的开头插入一个元素 0。为了腾出位置,所有的元素需要向后移动一位。最终数组变成了 [0, 1, 2, 3, 4]。如果数组有 nnn 个元素,最坏情况下需要移动 nnn 个元素,时间复杂度就是 O(n)O(n)O(n)。

  2. 查询:

    数组查询是 O(1)O(1)O(1) 的,因为数组支持通过索引直接访问元素。无论数组有多大,通过索引访问某个元素的时间是常数时间。

    例子:

    对于数组 [1, 2, 3, 4],要查询第 2 个元素,只需要通过索引 arr[1],这一步操作的时间是常数 O(1)O(1)O(1)。

链表

  1. 插入/删除:

    链表的插入和删除操作通常是 O(1)O(1)O(1),特别是当你知道要插入或删除的位置时,因为链表的节点是通过指针连接的,插入和删除操作只需要调整指针即可,不需要像数组那样移动大量元素。

    例子:

    假设我们有一个链表 1 -> 2 -> 3 -> 4,如果要在链表的头部插入一个元素 0,只需要创建一个新的节点,并将这个节点的指针指向原来的头节点 1,然后更新头指针即可。操作是 O(1)O(1)O(1) 的。

  2. 查询:

    链表的查询操作是 O(n)O(n)O(n),因为链表不支持直接通过索引访问元素,必须从头节点开始逐个遍历,直到找到目标节点。

    例子:

    对于链表 1 -> 2 -> 3 -> 4,如果要查询第 3 个元素,需要从头节点 1 开始,依次遍历 23,最终到达 3。所以查询需要遍历 nnn 个节点,时间复杂度是 O(n)O(n)O(n)。

总结

  • 数组 :插入/删除是 O(n)O(n)O(n),查询是 O(1)O(1)O(1)。
  • 链表 :插入/删除是 O(1)O(1)O(1),查询是 O(n)O(n)O(n)。

这样的时间复杂度差异使得数组和链表各有优缺点:如果需要频繁查询,数组更高效;如果需要频繁插入和删除,链表则更加高效。