Sobes.tech
Middle

Ի՞նչ է ավելի լավ օգտագործել՝ ArrayList թե LinkedList, եթե ուզում եմ հեռացնել տարր ցանկի միջից։

sobes.tech AI

Պատասխան AI-ից

ArrayList.

Երբ հեռացնում եք տարր ցանկի կենտրոնից.

  • ArrayList: Պահանջում է բոլոր հաջորդող տարրերի տեղաշարժը, ինչը վատագույն դեպքում (երբ հեռացվում է առաջին տարրը) ժամանակ է $O(n)$, որտեղ $n$ տարրերի քանակն է: Սակայն, միջինում, գործողությունը մնում է $O(n)$, քանի որ պետք է տեղաշարժել միայն կես տարրերը: Իրական կատարողականությունը հաճախ ավելի լավ է տվյալների ավելի լավ տեղակայման պատճառով:
  • LinkedList: Պահանջում է անցնել տարրերի միջով մինչև անհրաժեշտ հանգույցը գտնելը ($O(n)$ վատագույն դեպքում, եթե սկսվում է սկզբից կամ վերջից): Հետո հանգույցի հեռացումը $O(1)$:

Չնայած, որ ինքնըստինքյան հանգույցի հեռացումը LinkedList-ում արագ է, հանգույցի որոնումը նախքան հեռացումը ընդհանուր գործողությունը դարձնում է միջինում ավելի դանդաղ, քան ArrayList-ում:

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

public class ListRemovalComparison {

    public static void main(String[] args) {
        int size = 100000; // Ցանկի չափը
        int removeIndex = size / 2; // Հեռացման ինդեքսը (կենտրոն)

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

        long startTimeArrayList = System.nanoTime();
        arrayList.remove(removeIndex); // Կենտրոնից հեռացում
        long endTimeArrayList = System.nanoTime();
        long durationArrayList = (endTimeArrayList - startTimeArrayList);

        System.out.println("ArrayList-ից հեռացման ժամանակը: " + 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); // Կենտրոնից հեռացում
        long endTimeLinkedList = System.nanoTime();
        long durationLinkedList = (endTimeLinkedList - startTimeLinkedList);

        System.out.println("LinkedList-ից հեռացման ժամանակը: " + durationLinkedList + " ns");
    }
}

Արդյունքները ցույց են տալիս, որ եթե դուք գիտեք ինդեքսը, ArrayList-ը հաճախ ավելի լավ ընտրություն է, քանի որ ավելի արագ է ինդեքսով մուտքը, ինչը փոխհատուցում է տեղաշարժի ծախսերը:

// ArrayList - մուտք ըստ ինդեքսի O(1), հեռացում O(n) (տեղաշարժում)
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
arrayList.remove(1); // Հեռացնում "B" - տեղափոխում "C"

// LinkedList - մուտք ըստ ինդեքսի O(n), հեռացում O(1) (հետո հանգույցի գտնվելուց)
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.remove(1); // Հեռացնում "B" - նախ պետք է գտնել "B" հանգույցը (O(n)), ապա հեռացնել (O(1))

Ընդհանուր առմամբ, եթե դուք գիտեք ինդեքսը, ArrayList-ը հաճախ ավելի լավ ընտրություն է, քանի որ ավելի արագ է մուտք գործելու համար, ինչը փոխհատուցում է տեղաշարժի ծախսերը: