数组列表vs链表:为什么删除链表中的第一个元素比删除数组列表中的最后一个元素要快?

yzuktlbb  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(710)

这个问题在这里已经有答案了

如何用java编写正确的微基准测试(11个答案)
上个月关门了。
从数组列表的末尾删除项的时间复杂度为o(1),就像从链表的开头删除项一样。但是当我用java测试链表时,它还是快了一点,我不明白为什么。有人能解释为什么链表在时间复杂度为o(1)的情况下仍然更快吗?
换句话说,为什么从链表中删除第一个元素比从数组列表中删除最后一个元素要快?
我不认为我的代码能帮你回答我的问题,因为它更多的是关于数据结构的。但这里只是以防万一(不要介意法语,它是用来做作业的):

LinkedList<Integer> LinkL = new LinkedList<Integer>();
        ArrayList<Integer> ArrL = new ArrayList<Integer>();
        int N;
        N = 1000;
        //2.creer le Linked List
        for(int i=0; i<N; i++) {    
        LinkL.add(i);
        }
        //System.out.println(LinkL);  
        //3. et 4.Supprimer les elements de Linked List et afficher le temps
        long debut = System.nanoTime(); 
        for(int i=0; i<N; i++) {
        LinkL.removeFirst();
        }
        long fin = System.nanoTime();
        long tempsExecution = fin - debut;
        System.out.println("1.Suppression des éléments de LinkL avec la méthode \nremoveFirst( ) de LinkedList, avec une durée \nduréeLinkedList = "+tempsExecution+ " nanosecondes");  //-

        //5.Creer Array List
        for(int i=0; i<N; i++) {    
            ArrL.add(i);
            }
        //System.out.println(ArrL);
        //6.Supprimer les elements de Array List et afficher le temps
        debut = System.nanoTime(); 
        for(int i=0; i<N; i++) {
        ArrL.remove(0);
        }
        fin = System.nanoTime();
        tempsExecution = fin - debut;       
        System.out.println("\n2.Suppression des éléments de ArrL avec remove(0) d’un \nArrayList, durée duréeArrayDirect = "+tempsExecution+ " nanosecondes");

        //7. Recreer ArrL
        for(int i=0; i<N; i++) {    
            ArrL.add(i);
            }
        //System.out.println(ArrL);
        //Supprimer les elements de ArrL
        debut = System.nanoTime(); 
        for(int i=N-1; i>=0; i--) {
            ArrL.remove(i);
            }
        fin = System.nanoTime();
        tempsExecution = fin - debut;   
        System.out.println("\n3.Suppression des éléments de ArrL avec remove(i) ciblant \nles derniers éléments d’un ArrayList, avec une durée \nde duréeArrayInverse = "+tempsExecution+ " nanosecondes");

    }
}

提前谢谢。

vof42yt1

vof42yt11#

要了解原因,您必须查看代码源代码,看看在那里做了什么
数组表

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

双链表

public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));
}

Node<E> node(int index) {
    // assert isElementIndex(index);

    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

public boolean remove(Object o) {
    if (o == null) {
        for (Node<E> x = first; x != null; x = x.next) {
            if (x.item == null) {
                unlink(x);
                return true;
            }
        }
    } else {
        for (Node<E> x = first; x != null; x = x.next) {
            if (o.equals(x.item)) {
                unlink(x);
                return true;
            }
        }
    }
    return false;
}

如果从arraylist中删除一个元素,则该元素之后的元素应该向左移动,这一操作需要时间。另一方面,如果从linkedlist中删除元素,首先我们应该找到元素(此操作的速度,取决于列表大小),然后通过从列表中取消限制来删除元素。
现在在你的例子中,我看到你从列表中删除了第一个元素,这个操作对于arraylist和linkedlist都是非常昂贵的,但是如果你尝试删除最后一个元素,那么arraylist肯定会比linkedlist快。

相关问题