A dynamic array is an array that doubles its size, when an element is added to an already full array, copying the existing elements to a new place more details here. It is clear that there will be ceil(log(n))
of bulk copy operations.
In a textbook I have seen the number of movements M
as being computed this way:
M=sum for {i=1} to {ceil(log(n))} of i*n/{2^i}
with the argument that "half the elements move once, a quarter of the elements twice"...
But I thought that for each bulk copy operation the number of copied/moved elements is actually n/2^i
, as every bulk operation is triggered by reaching and exceeding the 2^i th
element, so that the number of movements is
M=sum for {i=1} to {ceil(log(n))} of n/{2^i}
(for n=8 it seems to be the correct formula).
Who is right and what is wrong in the another argument?
Both versions are O(n), so there is no big difference.
The textbook version counts the initial write of each element as a move operation but doesn't consider the very first element, which will move ceil(log(n))
times. Other than that they are equivalent, i.e.
(sum for {i=1} to {ceil(log(n))} of i*n/{2^i}) - (n - 1) + ceil(log(n))
== sum for {i=1} to {ceil(log(n))} of n/{2^i}
when n
is a power of 2. Both are off by different amounts when n
is not a power of 2.