2011-01-02 17 views
19

Ponieważ pracuję nad złożonością czasową, przeszukałem bibliotekę klasy Oracle w języku Java, aby uzyskać złożoność czasową niektórych standardowych metod używanych na listach, mapach i klasach. (Dokładniej, ArrayList, HashMap i HashSet)Złożoność czasowa metod HashMap

Teraz, kiedy patrząc na HashMap javadoc page, tylko naprawdę mówić o metodach get() i put().

Metody nadal muszę wiedzieć to:

remove(Object o) 
size() 
values() 

myślę że remove() będzie taka sama złożoność jako get(), O(1), zakładając, że nie mają olbrzymi HashMap z równych hashCodes, itp itd ..

Dla size() ja też założyć O(1), ponieważ HashSet, który również nie ma porządku, ma size() metodę ze złożoności O(1).

Jeden mam pojęcia, jest values() - Nie jestem pewien, czy ta metoda będzie po prostu jakoś „kopia” HashMap, dając złożoność czasową O(1), lub jeśli będzie musiał iteracyjne nad HashMap, czyniąc złożoność równa ilości elementów przechowywanych w HashMap.

Dzięki.

+1

Btw jaki sposób 'values ​​()' może dać 'O (1)', nawet jeśli to w jakiś sposób " skopiuj "HashMap? – Pacerier

+0

przy okazji, twój link jest zepsuty – Hengameh

+0

Czy możesz podać dokładną złożoność (średnią lub najgorszą), której szukasz w swoim pytaniu? Złożoność metody remove() będzie się odpowiednio różnić, jak słusznie zauważyłem: @JavaGuy – Dinesh

Odpowiedz

21

źródło jest często jako: http://kickjava.com/src/java/util/HashMap.java.htm

  • remove: O (1)
  • size: O (1)
  • values: O (n) (na przechodzenie przez iteracyjnej)
+7

remove ma zamortyzowaną złożoność O (1 + a), gdzie a zależy od tego, ile elementów znajduje się w gnieździe na klucz mieszający usuniętego obiektu. – Tim

+0

@Tim, co to jest? – Hengameh

+2

@Hengameh a - jest współczynnikiem obciążenia. Współczynnik obciążenia to stosunek liczby elementów do liczby slotów na mapie skrótów. Więcej szczegółowych objaśnień znajduje się w Wstępie do algorytmów 11.2 Tabele skrótów. – Tim

1

Zawsze możesz rzucić okiem na kod źródłowy i sprawdzić go samodzielnie.
W każdym razie ... Raz sprawdziłem kod źródłowy i pamiętam, że istnieje zmienna o nazwie size, która zawsze zawiera liczbę elementów w HashMap, więc size() jest O(1).

+0

Jestem nowicjuszem w Javie, więc nie mam pojęcia o kodach źródłowych, ale spróbuję. Dzięki! – Koeneuze

+0

gdzie mogę znaleźć kod źródłowy? – Hengameh

5

Kod do usunięcia (jak w rt.jar dla HashMap) to:

/** 
* Removes and returns the entry associated with the specified key 
* in the HashMap. Returns null if the HashMap contains no mapping 
* for this key. 
*/ 
final Entry<K,V> removeEntryForKey(Object key) { 
    int hash = (key == null) ? 0 : hash(key.hashCode()); 
    int i = indexFor(hash, table.length); 
    Entry<K,V> prev = table[i]; 
    Entry<K,V> e = prev; 

    while (e != null) { 
     Entry<K,V> next = e.next; 
     Object k; 
     if (e.hash == hash && 
      ((k = e.key) == key || (key != null && key.equals(k)))) { 
      modCount++; 
      size--; 
      if (prev == e) 
       table[i] = next; 
      else 
       prev.next = next; 
      e.recordRemoval(this); 
      return e; 
     } 
     prev = e; 
     e = next; 
    } 

    return e; 
} 

Najwyraźniej najgorszym przypadkiem jest O (n).

+1

Chociaż pod względem technicznym ta odpowiedź może być myląca dla niektórych. Ten kod jest tylko O ​​(n), jeśli wszystkie klucze w HashMap mają ten sam kod hash, co jest mało prawdopodobne i/lub błąd. Myślę, że [komentarz Tima] (http://stackoverflow.com/questions/4577998/time-complexity-of-hashmap-methods#comment20518366_4578039) jest lepszą prawdą. –

+1

Zgadzam się z @HawkeyeParker, ale punkt jest nadal poprawny: runtime = worst case = linear. Ponownie, jest to mało prawdopodobne i czysto teoretyczne, ale w sposobie definiowania wydajności algorytmów odpowiedź musi być liniowa, ponieważ istnieje jedna możliwość, w której O (n) jest prawdziwa. –

1

wyszukiwania: O (1 + k/n)
Płytka: O (1)
Usuń: O (1 + k/n) gdzie k jest nie. elementów kolizji dodanych do tej samej listy wyników (elementy k miały taki sam kod haszowania)

Wstawienie to O (1), ponieważ element ten jest wstawiany bezpośrednio na początku listy odnośników.

Amortyzowane złożoności czasowe są bliskie wartości O (1) podanej w dobrym haśle. Jeśli jesteś zbyt zaniepokojony czasem szukania, spróbuj rozwiązać kolizje za pomocą BinarySearchTree zamiast domyślnej implementacji java tj. LinkedList

+0

"Wstawienie to O (1), ponieważ element jest wstawiany bezpośrednio na początku listy parametrów." Musi jeszcze przejść przez listę, aby sprawdzić, czy ten element już istnieje, porównując klucz wraz z hashiem (Ref - source code). – Swapnil

+0

lepiej używać wyszukiwania, umieszczania i usuwania :) – Hengameh

Powiązane problemy