Wiem, że z O (n) zwykle masz pojedynczą pętlę; O (n ^ 2) jest podwójną pętlą; O (n ^ 3) jest potrójną pętlą itp. Co powiesz na O (log n)?
Naprawdę źle sobie z tym radzisz. Próbujesz zapamiętać, które wyrażenie big-O pasuje do danej struktury algorytmu, ale naprawdę powinieneś po prostu policzyć liczbę operacji wymaganych przez algorytm i porównać to z rozmiarem danych wejściowych. Algorytm, który zapętla się na całym wejściu, ma wydajność O (n), ponieważ uruchamia pętlę n razy, a nie dlatego, że ma pojedynczą pętlę. Oto pojedyncza pętla z wydajnością O (log n):
for (i = 0; i < log2(input.count); i++) {
doSomething(...);
}
Tak więc dowolnym algorytmem, w którym liczba wymaganych operacji jest rzędu logarytmu wielkości danych wejściowych, jest O (log n). Ważną rzeczą, którą mówi analiza Big-O, jest to, jak zmienia się czas wykonania algorytmu w stosunku do wielkości danych wejściowych: jeśli podwoisz wielkość danych wejściowych, czy algorytm wykona jeszcze 1 krok (O (log n)) , dwa razy więcej kroków (O (n)), cztery razy więcej kroków (O (n ^ 2)) itp.
Czy pomaga z doświadczenia wiedzieć, że algorytmy, które wielokrotnie dzielą dane wejściowe, zwykle mają „log n” jako składnik ich wydajności? Pewnie. Ale nie szukaj partycjonowania i przejdź do wniosku, że wydajność algorytmu to O (log n) - może to być coś w rodzaju O (n log n), co jest zupełnie inne.