2016-07-26 4 views
1

Ich überarbeite eine ArrayList mit einer while-Schleife und entferne Werte, wenn sie bestimmte Kriterien erfüllen. Mein Code ist im Geist des folgenden Ausschnitts:Ist die Methode remove von Java's ArrayList Iterator O (n^2) oder O (n)? wenn ich über die Liste iteriere?

List<Integer> list = new ArrayList<>(); 
    int N = 1000 
    // setup list to show as an example 
    for (int i = 0; i < N; i++) { 
     list.add(i); 
    } 

    Date start = new Date(); 
    // iterate over entire list, removing half the values 
    Iterator<Integer> iter = list.iterator(); 
    while (iter.hasNext()) { 
     Integer in = iter.next(); 
     if (in % 2 == 0) { 
      // is it even? 
      iter.remove(); 
     } 
    } 

    Date end = new Date(); 
    System.out.println(end.getTime() - start.getTime()); 
    System.out.println(list.size()); 

Was will ich weiß, ist, wenn die Zeit Komplexität dieser Iterator Schleife ist O (N) oder O (N^2). Ich glaube, dass es O (N^2) ist, weil Java ArrayLists in einem regulären Array gesichert werden, und für jede Entfernung müssen Sie unbedingt O (N) der nachfolgenden Werte nach links verschieben, um das Array in einem vernünftigen Zustand zu halten.

+1

Ihr Titel stimmt nicht mit Ihrer Frage überein. Die zeitliche Komplexität der remove-Methode wird dokumentiert. Die Komplexität Ihrer Schleife kann durch die Konstruktion aus den bekannten Zeitkomplexitäten des Iterators und der Remove-Methode berechnet werden. – EJP

+0

Es ist größer als N, aber es kann nicht N^2 sein, wenn Speicherblöcke effizient kopiert werden können. – chrylis

+1

Sind Sie verantwortlich für [Amoritisierung] (https://en.wikipedia.org/wiki/Amortized_analysis)? –

Antwort

-1

Keine der Antworten auf meine Frage liefern Beweise, wie Iterator.remove funktioniert, also habe ich meine eigenen Tests gemacht. Meine persönlichen Tests lassen mich glauben, dass die Zeitkomplexität O (N^2) ist. Hier ist es, Daten aus 3 verschiedenen Tests, wobei jeder "Time" Wert ist ein Durchschnittswert über 10 Iterationen:

N = 10.000 Time = 8ms

N = 100.000 Zeit = 487ms

N = 200.000 Zeit = 2026ms

eine Verdoppelung der Listengröße ergibt eine ungefähr 4 mal längere Laufzeit.

+0

Es gab noch keine Antworten auf Ihre Frage, und der Beweis ist genau dort im Javadoc, wo Sie nicht hinschauten. – EJP

+0

@EJP Der Javadoc-Link, den Sie angegeben haben, ist für die 'remove'-Methode von ArrayList, während ich nach der' remove'-Methode von ListIterator frage. Bitte geben Sie eine Antwort auf meine Frage und lassen Sie die Community entscheiden, was besser ist. – almel

Verwandte Themen