2015-02-21 3 views

ответ

5

Внутренний цикл в первый раз выполняет итерацию 1, на вторые 2 итераций. Последовательность выглядит как 1, 2, 4, 8, 16, 32, ... до тех пор, пока она меньше или равна n. Последовательность может содержать Θ(log(n)) элементов, но ее сумма равна Θ(n). Это происходит потому, что

1 + 2 + 4 + ... + 2^к = 2 * 2^к - 1

и мы знаем n/2 < 2^k <= n. Таким образом, внутренний цикл выполняется Θ(n) раз , и для выполнения каждого внутреннего цикла требуется постоянное количество инструкций.

Остальная часть кода просто log(n) присвоений j = 1 и log(n) двойники k.

Таким образом, временная сложность алгоритма Θ(n).

+3

@JonathanLeffler Верхняя граница O (NlogN), конечно же, также верна этим аргументом, но факты о сумме геометрической прогрессии (N + N/2 + N/4 + N/8 + ... <2N в этом случай) позволяют установить более точную оценку. – Gassa

+1

Проведя немного времени (слишком много времени), измеряя его, я должен согласиться с тем, что он линейный. В диапазоне 15 удвоений в размере проблемы соотношение двух последовательных периодов было между 1,90 и 2,15, без очевидной картины для коэффициентов «больше 2» и «менее 2», особенно не для нескольких тиражей. Машина, на которой я тестировалась, не была полностью бездействующей, что объясняет некоторую изменчивость. –

0
// code     | max times executed 
k=1;     | 1 
while (k<=n) do   | log n 
    j=1;    | log n 
    while (j<=k) do  | log n * n 
     sum=sum+1;  | log n * n 
     j=j+1;   | log n * n 
    k=k*2;    | log n 

Таким образом, сложность O представляется n log n.

+1

Это неверно. –

+0

@OliverCharlesworth. Обоснование правильное, просто субоптимальное (мы можем сделать лучше). O (n log n) технически истинно по определению (верхняя граница сложности), даже если O (n) также верно. – Gassa

Смежные вопросы