Przeszukiwanie tablicy elementów przy użyciu wyszukiwania binarnego zajmuje w najgorszym przypadku iteracje ponieważ na każdym kroku zmniejszamy połowę naszej przestrzeni wyszukiwania. Gdybyśmy zamiast tego użyli „wyszukiwania trójskładnikowego”, dwie trzecie naszej przestrzeni wyszukiwania przy każdej iteracji, więc najgorszy przypadek powinien zająć iteracji ...
Wygląda na to, że wyszukiwanie trójskładnikowe jest szybsze, więc dlaczego używamy wyszukiwania binarnego?
algorithms
algorithm-analysis
runtime-analysis
search-algorithms
binary-search
Średni kwadrat
źródło
źródło
Odpowiedzi:
Jeśli zastosujesz wyszukiwanie binarne, będziesz mieć wiele porównań. Jeśli zastosujesz wyszukiwanie trójskładnikowe, masz wiele porównań, ponieważ na każdym kroku musisz wykonać 2 porównania, aby przeciąć przestrzeń wyszukiwania na trzy części. Teraz, jeśli wykonasz matematykę, możesz zauważyć, że: Ponieważ wiemy, że , faktycznie uzyskujemy więcej porównań z wyszukiwaniem trójstronnym.
Nawiasem mówiąc: -ary wyszukiwanie może mieć sens w przypadku, gdy porównania są dość kosztowne i można je zrównoleglać, ponieważ wówczas można zastosować komputery równoległe.n
Zauważ, że argument można dość łatwo uogólnić na wyszukiwanie -ary. Musisz tylko pokazać, że funkcja rośnie ściśle monotonicznie dla wartości całkowitych .n f(k)=(k−1)⋅log(2)log(k) k
źródło
DCTLib ma rację, ale na chwilę zapomnij o matematyce.
Według twojej logiki, n -ary powinno być najszybsze. Ale jeśli się nad tym zastanowić, n -ary jest dokładnie równe regularnemu wyszukiwaniu iteracyjnemu (tylko iteracja po liście 1 na 1, ale w odwrotnej kolejności). Najpierw wybierz ostatni (lub obok ostatniego) element z listy i porównaj tę wartość z wartością porównania. Następnie usuwasz ten element z listy, a następnie wybierasz ostatni element z nowej listy, który jest tuż przed ostatnią wartością w tablicy. Za każdym razem eliminujesz tylko 1 wartość na raz, dopóki nie znajdziesz swojej wartości.
Zamiast tego powinieneś pomyśleć o tym w ten sposób - jak mogę wyeliminować najwięcej wartości z listy przy każdej iteracji? W wyszukiwaniu binarnym zawsze eliminujesz połowę listy. W trójstronnym wyszukiwaniu istnieje możliwość (faktycznie 33,33% szansy), że możesz wyeliminować 2/3 listy, ale istnieje jeszcze większa szansa (66,66%), że wyeliminujesz tylko 1/3 listy. aby obliczyć O (n), musisz spojrzeć na najgorszy scenariusz, który wynosi 1/3, mniej niż 1/2. W miarę zbliżania się do n staje się jeszcze gorzej.
Wyszukiwanie binarne poprawi nie tylko najgorszy scenariusz, ale także poprawi się średni czas. Patrząc na oczekiwaną wartość (jaką część listy możemy usunąć średnio), używamy tej formuły:
(P_lower) x (część, którą możemy usunąć, jeśli jest niższa) + (P_higher) x (część, którą możemy usunąć, jeśli jest wyższa) = E
W przypadku wyszukiwania binarnego jest to .5x.5 + .5x.5 = .5 (zawsze usuwamy połowę listy). W przypadku wyszukiwań trójskładnikowych wartość ta wynosi .666x.333 + .333x.666 = 0,44, lub na każdym etapie prawdopodobnie usuniemy tylko 44% listy, co czyni ją mniej wydajną niż wyszukiwanie binarne. Wartość ta osiąga wartość szczytową na 1/2 (połowa listy) i zmniejsza się, im bardziej zbliżasz się do n (iteracja wsteczna) i 0 (iteracja zwykła).
Ok, więc skłamałem ... w grę wchodzi trochę matematyki, ale mam nadzieję, że to pomoże!
źródło
Uwaga: argument porównania log (N) vs 2 log (N) opiera się na naiwnej interpretacji algorytmu. Gdybym rzeczywiście usiadł i napisał to w zestawie x86, wyniki zostałyby odwrócone. Problemem jest użycie liczb całkowitych w przypadkach testowych w połączeniu z niewystarczająco inteligentnym kompilatorem, który nie może usunąć zbędnych porównań. Ponów próbę z ciągami znaków i odpowiednią funkcją porównania ciągów, a następnie zakoduj ją, aby wywoływała funkcję porównania raz na pętlę, a przekonasz się, że wyszukiwanie potrójne jest szybsze.
źródło