繁体   English   中英

为什么ArrayList比Java中的LinkedList花费更多的时间在开头插入元素

[英]Why does ArrayList takes more time to insert element in the beginning than LinkedList in java

我认为ArrayList具有O(n)复杂度以在开始时插入元素,因为它会将其余元素右移一位。 LinkedList具有O(n)可以在最后插入元素,因为它必须遍历每个元素。 所以上述两个操作所花费的时间应该是可比较的,但是当我实际执行时,arraylist在开头插入需要34057毫秒,而LinkedList在结尾插入只需要41毫秒,而两者都具有O(n)时间复杂度。 为什么会这样呢?

就空间复杂度而言,哪个更好?

这是我的代码

public void timeTakenEnd(String name, List<Integer> list) {


    for (int i = 0; i < 1E5; i++) {
        list.add(i);

    }


    long start = System.currentTimeMillis();
    for (int i = 0; i < 1E5; i++) {
        list.add(i);

    }

    long end = System.currentTimeMillis();

    System.out.println("time taken for: " + name + " to insert elements in the end is  " + (end - start));

}

public void timeTakenBeg(String name, List<Integer> list) {


    for (int i = 0; i < 1E5; i++) {
        list.add(i);

    }


    long start = System.currentTimeMillis();
    for (int i = 0; i < 1E5; i++) {
        list.add(0, i);

    }

    long end = System.currentTimeMillis();

    System.out.println("time taken for: " + name + "to insert elements in the beginning is  " + (end - start));

}

public static void main(String[] args) {

    ArrayList<Integer> alist = new ArrayList<Integer>();
    LinkedList<Integer> llist = new LinkedList<Integer>();

    TimeComplexity demo = new TimeComplexity();

    demo.timeTakenEnd("arrarylist", alist); //25 miliseconds on my machine
    demo.timeTakenEnd("linkedlist", llist);//41 miliseconds on my machine

    demo.timeTakenBeg("arraylist", alist);// 34057 miliseconds on my machine
    demo.timeTakenBeg("linkedlist", llist); //60 miliseconds on my machine

}

}

LinkedList是一个双向链接列表。 它记住它的第一个最后一个元素,并允许在两个方向上遍历列表。

因此,在末尾添加元素只是创建节点并分配lastnextprevious指针的一种方法。 是O(1)。

请注意,Java是开放源代码,并且源代码是JDK随附的。 您可以轻松找到实现:

public boolean add(E e) {
    linkLast(e);
    return true;
}

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}

顾名思义(和Javadoc), ArrayList由数组内部实现。

因此,插入项目涉及将其后面的所有项目向前移动一个位置。

另一方面, LinkedList只需重定向项目的引用即可插入新节点,因此其时间更加恒定。

数组列表使用连续存储,因此在开始时插入需要将所有现有元素上移一个,或重新分配整个列表。 只要正确设置链接,链接列表就可以将新元素放置在任何地方。 无需移动列表的其他元素,只需调整一些链接即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM