将元素移动到第一位时,ArrayList 与 LinkedList 的复杂性

ArrayList vs LinkedList complexity when moving element to the first place

我想分析使用 LinkedList 或 ArrayList 将 1 2 3 4 移动到 3 1 2 4(整数列表)。

我做了什么:

aux = arraylist.get(2); // O(1)
arraylist.remove(2); // O(n)
arraylist.add(0, aux); // O(n), shifting elements up.

aux = linkedlist.get(2); // O(n)
linkedlist.remove(2); // O(n)
linkedlist.addFirst(aux); // O(1)

所以,在这种情况下,我们可以说它们是相同的还是我遗漏了什么?

这是一个快速而粗略的基准测试。我为这两个操作计时并重复了一百万次:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

public class Main {

    public static void main(String[] args) {
        int arrayListTime = 0;
        int linkedListTime = 0;
        int n = 10000000;
        for (int i=0; i<n; i++) {
            ArrayList<Integer> A = new ArrayList<>(Arrays.asList(1,2,3,4));
            long startTime = System.currentTimeMillis();
            int x = A.remove(2);
            A.add(0, x);
            long endTime = System.currentTimeMillis();
            arrayListTime += (endTime - startTime);

            LinkedList<Integer> L = new LinkedList<>(Arrays.asList(1,2,3,4));
            long startTime2 = System.currentTimeMillis();
            int x2 = L.remove(2);
            L.addFirst(x2);
            long endTime2 = System.currentTimeMillis();
            linkedListTime += (endTime2 - startTime2);
        }

        System.out.println(arrayListTime);
        System.out.println(linkedListTime);
    }
}

差别很小。我的输出是:

424
363

因此,在 1,000,000 次操作过程中,使用 LinkedList 仅快 61 毫秒。

当输入非常小时,大 O 复杂性毫无意义,就像您的情况一样。回想一下,大 O 的定义只适用于 "large enough n",我怀疑你是否已经达到 n==4 的阈值。

如果这在一个小数据量的紧密循环中运行(并且每次都有不同的数据),唯一真正重要的是缓存性能,并且数组列表解决方案比缓存更友好链表解决方案,因为链表中的每个 Node 都可能需要缓存查找。
在这种情况下,我什至更喜欢使用原始数组 (int[]),以避免冗余包装对象,这会触发更多缓存未命中。

你确实可以说这个特定操作对 LinkedList 和 ArrayList 都需要 O(n) 时间。

但是你不能说他们因此而占用了相同的实时时间。

Big-O 符号仅告诉您 运行 时间将如何随着输入变大而缩放,因为它忽略了常数因子。因此,一个 O(n) 算法最多可以进行 1*n 次操作或 100000*n 次操作或更多操作,并且这些操作中的每一个所花费的时间可能相差很大。这也意味着它通常是一个非常不准确的小输入性能度量,因为常数因子对 运行 时间的影响比小输入的大小更大(但性能差异对于小输入往往不太重要).

另请参阅:What is a plain English explanation of "Big O" notation?