Widziałem ludzi, którzy mówili, że set
obiekty w Pythonie mają sprawdzanie członkostwa O (1). Jak są wdrażane wewnętrznie, aby to umożliwić? Jakiego rodzaju struktury danych używa? Jakie inne konsekwencje ma to wdrożenie?
Każda odpowiedź była naprawdę pouczająca, ale mogę zaakceptować tylko jedną, więc podam najbliższą odpowiedź na moje pierwotne pytanie. Dzięki wszystkim za informację!
źródło
set
implementacja faktycznie miaładict
wartości fikcyjne i została później zoptymalizowana.Kiedy ludzie mówią, że zestawy mają sprawdzanie członkostwa O (1), mówią o przeciętnym przypadku. W najgorszym przypadku (kiedy wszystkie zaszyfrowane wartości kolidują) sprawdzanie członkostwa to O (n). Zobacz wiki Pythona na temat złożoności czasowej .
Artykuł w Wikipedii mówi, że najlepsza złożoność czasowa przypadku dla tabeli skrótów, która nie zmienia rozmiaru, to
O(1 + k/n)
. Ten wynik nie ma bezpośredniego zastosowania do zestawów Pythona, ponieważ zestawy Pythona używają tablicy skrótów, która zmienia rozmiar.Nieco dalej w artykule na Wikipedii napisano, że dla przeciętnego przypadku, przy założeniu prostej, jednolitej funkcji mieszającej, złożoność czasowa jest taka
O(1/(1-k/n))
, w którejk/n
można ją ograniczyć przez stałąc<1
.Big-O odnosi się tylko do asymptotycznego zachowania jako n → ∞. Ponieważ k / n może być ograniczone stałą, c <1, niezależną od n ,
O(1/(1-k/n))
jest nie większa niżO(1/(1-c))
która jest równoważnaO(constant)
=O(1)
.Zatem zakładając jednolite proste haszowanie, sprawdzanie członkostwa w zestawach Pythona wynosi średnio
O(1)
.źródło
Myślę, że to częsty błąd,
set
wyszukiwanie (lub haszowanie w tym przypadku) nie jest O (1).z Wikipedii
Powiązane: Czy hashmap Java to naprawdę O (1)?
źródło
Wszyscy mamy łatwy dostęp do źródła , w którym powyższy komentarz
set_lookkey()
mówi:źródło
Aby nieco bardziej podkreślić różnicę między
set's
idict's
, oto fragmentsetobject.c
sekcji komentarzy, który wyjaśnia główną różnicę między zestawami a dyktami.źródło na github
źródło