Hmm, upon further inspection your algorithm is the following:
sub divide {
my $mid = @_/2;
$ITER++;
return if @_ == 1;
divide(@_[0 .. $mid - 1]);
divide(@_[$mid .. $#_]);
}
for (10 .. 30) {
$ITER = 0;
divide(1 .. $_);
printf "%2d %2d\n", $_, $ITER;
}
The order of this is N, really. Specifically, it's
2*N-1. T(N) is the time it takes to call
divide() for a list of N values:
T(1) = 1
T(2) = 1 + 2*T(1)
T(4) = 1 + 2*T(2)
...
T(N) = 1 + 2*T(N/2)
We can then expand backwards from the generality:
T(N) = 1 + 2*T(N/2)
= 1 + 2*(1 + 2*T(N/4))
= 1 + 2 + 4*T(N/4)
--> = 3 + 4*T(N/4)
= 3 + 4*(1 + 2*T(N/8))
= 3 + 4 + 8*T(N/8)
--> = 7 + 8*T(N/8)
= 7 + 8*(1 + 2*T(N/16))
= 7 + 8 + 16*T(N/16)
--> = 15 + 16*T(N/16)
The general equation here is
T(N) = 2^k - 1 + 2^k * T(N / 2^k). We will make
the following substitution: k = log(N) (base 2).
We now have:
T(N) = 2^k - 1 + 2^k * T(N / 2^k)
= 2^(log N) - 1 + 2^(log N) * T(N / 2^log(N))
= N - 1 + N * T(N/N)
= N - 1 + N * 1
= 2*N - 1
$_="goto+F.print+chop;\n=yhpaj";F1:eval |