Zheng found an interesting loop online
here (apparently blocked
on campus), like this:
int m = 0,i,j;
for(i = 1; i <= n ; i *= 2)
for(j = 1; j <= i; j++)
m++;
He tells me that the Chinese text says the complexity is
O(n).
I think so, too.
- Let's start by assuming n is a power of 2.
The outer loop runs through the powers of two which are less than
or equal to n. So,
i= 1, 2, 4, 8, 16, 32, … , n.
Stated differently:
i=20,21,22,23,24,…,2log2n.
- For each outer loop iteration, the number of inner loop iterations is
just the index of the outer iteration.
So, the total number of inner loop iterations is the sum of those outer loop
index values.
So, lets add them up:
20+21+22+23+24+…+2log2n=log2n
Σ
k=0
2k
- The formula cribbed from
here is
Applying that,
log2n
Σ
k=0
2k==2⋅2log2n−1=2n−1=O(n)
- Perhaps a more satifying way to look at it is to the think of doing
the sum in binary. The number
20+21+22+23+24+…+2log2n
is a sum of binary place values. Hence, it is a binary number
made of log2n+1 ones.
The value of any binary number made of
k ones is 2k−1
(Add one to that binary number, and you'll carry through to get a 1 followed
by k zeros, so the 1 is the the 2k place.)
So,
2log2n+1−1=2⋅2log2n−1=2n−1=O(n)
- If n is not a power of two, the actual number of
outer-loop iterations will
be the same as the largest power of two less than n. Call that
number nb. But nb
cannot be less than n/2, so log2nb cannot be smaller
than log2n−1. No threat to O(n).
Very clever. I like it.