Sobes.tech
Middle

Mit érdemes inkább használni: ArrayList vagy LinkedList, ha a lista közepéből szeretnék elemet törölni?

sobes.tech MI

Válasz az MI-től

ArrayList.

Elem törlése középről:

  • ArrayList: Szükségessé teszi az összes későbbi elem eltolását, ami a legrosszabb esetben (amikor az első elemet töröljük) időt vesz igénybe $O(n)$-ben, ahol $n$ az elemek száma. Átlagosan azonban az művelet $O(n)$ marad, mivel csak a felét kell eltolni az elemeknek. A tényleges teljesítmény gyakran jobb a jobb adatlokalizáció miatt.
  • LinkedList: Szükségessé teszi az elemek közötti iterációt a kívánt csomópont megtalálásához ($O(n)$ a legrosszabb esetben, ha az iteráció a kezdet vagy a vég felől történik). A csomópont megtalálása után a törlés $O(1)$.

Bár a LinkedList esetén maga a csomópont törlése gyorsabb, a csomópont keresése a törlés előtt átlagosan lassabbá teszi az összes műveletet, mint az ArrayList esetén.

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListRemovalComparison {

    public static void main(String[] args) {
        int size = 100000; // Lista mérete
        int removeIndex = size / 2; // Törlési index (közép)

        // ArrayList
        List<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            arrayList.add(i);
        }

        long startTimeArrayList = System.nanoTime();
        arrayList.remove(removeIndex); // Középről törlés
        long endTimeArrayList = System.nanoTime();
        long durationArrayList = (endTimeArrayList - startTimeArrayList);

        System.out.println("Törlési idő ArrayList-ből: " + durationArrayList + " ns");

        // LinkedList
        List<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < size; i++) {
            linkedList.add(i);
        }

        long startTimeLinkedList = System.nanoTime();
        linkedList.remove(removeIndex); // Középről törlés
        long endTimeLinkedList = System.nanoTime();
        long durationLinkedList = (endTimeLinkedList - startTimeLinkedList);

        System.out.println("Törlési idő LinkedList-ből: " + durationLinkedList + " ns");
    }
}

Az eredmények szerint a középről történő törléshez az ArrayList általában gyorsabb, annak ellenére, hogy a szövetés elméleti komplexitása magasabb. Ez azért van, mert a index szerinti keresés a LinkedList-ben ($O(n)$) lassabb, mint az eltolás az ArrayList-ben.

// ArrayList - indexelés O(1), törlés O(n) (elmozdulás)
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
arrayList.remove(1); // "B" törlése - eltolja a "C"-t

// LinkedList - indexelés O(n), törlés O(1) (a csomópont megtalálása után)
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.remove(1); // "B" törlése - először meg kell találni a "B" csomópontot (O(n)), majd törölni (O(1))

Végül, középről történő törlés esetén, ha ismeri az indexet, az ArrayList gyakran előnyösebb választás az gyorsabb indexelési művelet miatt, ami kompenzálja az eltolási költségeket.