Это циклы в алгоритме:
for (int gap = n/2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i += 1) {
for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {
}
}
}
Давайте начнем с l oop over i
. Он начинается с gap
и продолжается до n
с шагом 1. Следующее значение l oop сверх j
начинается с тока i
и понижается на gap
, пока не станет меньше gap
. Таким образом, l oop over j
выполняется один раз для i
между gap
и 2*gap
, дважды для i
между 2*gap
и 3*gap
, три раза для i
между 3*gap
и 4*gap
и тд.
Это означает, что j
l oop будет выполняться один раз для gap
различных значений i
, дважды для gap
различных значений i
, три раза для gap
различных значения i
, et c.
Максимальное значение для i
равно n
, поэтому значение l oop сверх j
может выполняться максимально j_max = (n - gap)/gap
раз. Общее количество выполнений j
l oop равно
1+1+...+1+1 + 2+2+...+2+2 + 3+3+...+3+3 + .... + j_max+j_max+...+j_max+j_max
|_________| |_________| |_________| |_________________________|
gap times gap times gap times gap times
Эта сумма равна
gap*(sum from 1 to j_max) = gap * j_max(j_max + 1) / 2 = O(gap * ((n-gap)/gap)^2) = O((n-gap)^2/gap)
Это будет повторяться для различных значений gap
в внешний l oop, поэтому сложность O-big составляет
sum((n-gap)^2/gap, for gap = n/2, n/4, n/8, ...., 4, 2, 1)
Расширение:
(n^2 - 2*n*gap + gap^2)/gap = n^2*(1/gap) - 2*n + gap
Первый член равен n
в квадрате, умноженном на следующие значения:
1/(n/2), 1/(n/4), 1/(n/8), ..... 1/4, 1/2, 1/1
или
2/n, 4/n, 8/n, ....., n/n
Это сумма степеней двух, деленная на n
, поэтому первый член дает всего
n^2/n * 2^(log2 n) = n^2
. второй член равен -2*n
, суммированному log2 n
раз, поэтому сложность равна
n*log2 n
Последний член равен сумме gaps
, так что это сумма степеней двух и его сложность n
. Объединяя все вместе, мы получаем сложность наихудшего случая как O (n ^ 2).