2013-01-08 18 views
12

Próbuję zrozumieć, w jaki sposób jest iterowanie poprzez zaimplementowane hashtable. Po prostu nie mogę tego sobie wyobrazić. Jestem szczególnie zainteresowany szybkością takiej iteracji. Na przykład:W jaki sposób jest iterowane za pośrednictwem hashtable?

QHash<int, std::string> hashTable; 
... 
for (auto it = hashTable.begin(); it != hashTable.end(); ++it) 
    std::cout << it.value() << std::endl; 

Czy jest to operacja O(hashTable.size())?

Próbowałem zagłębić się w kodzie źródłowym, ale nie mogłem znaleźć właściwej definicji.

Odpowiedz

12

Niektóre implementacje tabel mieszania również utrzymują połączoną listę wszystkich wpisów, aby umożliwić szybką iterację (tak zwaną "połączoną mapę skrótów").

Jedynym sposobem jest powtórzenie wszystkich segmentów stołu mieszającego, a także powtórzenie kolejnych elementów w każdym wiadrze.

Szybkość tej operacji zależy od stanu napełnienia tabeli. Gdy jest bardzo niska, wiele pustych wiader musi zostać poddanych iteracji, co marnuje czas. Gdy tabela jest dobrze wypełniona, a jeden lub więcej elementów znajduje się w każdym wiadrze, to prawie tak, jak iterowanie połączonej listy. Na idealnej mapie mieszania, w której każdy zasobnik zawiera dokładnie jeden element, jest to jak iterowanie tablicy.

+0

Dziękujemy! Więc operacja jest zawsze w czasie liniowym, prawda? –

+1

Tak, liniowo do liczby wiader + liniowo do liczby wpisów. – Philipp

+1

Twoja pętla 'for' jest odpowiednikiem algorytmu STL' std :: for_each'. Algorytm ten jest liniowy pod względem liczby odwiedzanych elementów. Co więcej, kontener 'std :: unordered_map' ma przynajmniej iterator forward, a wszystkie operacje na takich iteratorach są co najwyżej amortyzowane. Oznacza to, że pętla na całej tablicy mieszającej ma także złożoność czasu liniowego (a nie tylko złożoność wielkości liniowej). – TemplateRex

Powiązane problemy