2016-04-14 21 views
7

Przeczytałem previous question o złożoności czasowej dla TreeSet i odpowiedziano, że zajmuje to O (n) czas. Jednak nie rozumiem, dlaczego jest O (n) do iteracji zamiast O (n * nlogn).Dlaczego TreeSet Iteracja O (n) zamiast O (n * logn)?

Każde następne wywołanie odbywa O(logn) time

Więc jeśli iterację TreeSet tak:

while (iterator.hasNext()){ //Runs N times 
    System.out.println(iterator.next() + " "); //each next is O(logn) 
} 

by się spodziewać, że będzie O (n * logn), a nie O (n), ponieważ pętla while ma N iteracji, a każda iterator.next() wywołuje czas O (logn).

+0

Dlaczego 'iterator.next()' jest O (log n). Musi tylko przejść do następnego węzła, to jest O (1), czyż nie? –

+2

@JoseLuis nie dokładne, na podstawie patrząc na kod źródłowy. –

+0

@ louis-wasserman Masz rację, bardzo mi przykro. Myślałem, że iterator() może zwrócić listę z posortowanymi węzłami, a następnie przejście do następnego węzła jest łatwe. –

Odpowiedz

12

Najgorszy czas dla jednej operacji next to O(log n), ponieważ jest to wysokość drzewa. Średnio jednak następny element można znaleźć w czasie O(1). Dzieje się tak dlatego, że cała operacja polega na dwukrotnym użyciu każdej krawędzi drzewa.

+1

Kod dla Iterator.next wydaje się kończyć w 'TreeMap.Entry.successor()', tutaj: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6- b14/java/util/TreeMap.java # TreeMap.successor% 28java.util.TreeMap.Entry% 29 Tak, wydaje się, że przez większość czasu następnym wpisem będzie po prostu 'p.left! = null'. Czy jednak Big-O nie jest najgorszy, a nie przeciętny? – markspace

+1

@markspace Big-O opisuje dowolne zachowanie, ponieważ nie chodzi tu o samą złożoność, chodzi o wzrost funkcji. Możesz opisać średni, najgorszy, zamortyzowany, przewidywany koszt, z dużym prawdopodobieństwem, ... W tym przypadku jest to nawet Theta (n) (najgorszy i najlepszy przypadek) dla wszystkich operacji razem. Znalezienie jednego następcy może kosztować log n czas, ale iterowanie wszystkich n elementów kosztuje najwyżej 2n. –

+1

@markspace Duże-O związane bez opracowania odnosi się do najgorszego przypadku czasu pracy, ale notacja big-O jest po prostu matematycznym stwierdzeniem o funkcji. –

0

można zaimplementować iteracji dla drzewa tak:

void print(Node n) { 
    if (n.left != null) print(n.left); 
    System.out.println(n.value); 
    if (n.right != null) print(n.right); 
} 

Druk funkcja ma być wywołana dokładnie jeden raz dla każdego węzła, więc całkowity czas iteracji wynosi O (N). Możesz wdrożyć dokładnie ten sam algorytm iteracyjnie (bez rekursji). A jeśli jesteś wystarczająco ostrożny, możesz mieć klasę, która zachowa stan iteracyjny i przejdzie do przodu, gdy zostanie wywołana .next(). To prawda, że ​​liczba wywołań funkcji między println s jest nierównomierna, ale gdy spojrzysz na nią ogólnie, odkryjesz, że jest ich dokładnie N.

Powiązane problemy