0

What is the complexity for alloc(realloc)/new operations for code below, for huge values of N.

As far as I understood push_back allocates memory:
size = cst*old_size;
cst = 2; // for gcc
So we have O(1) inside k cycle and ~O(N) inside i cycle. In summary I have O(N), am I right?

std::vector<int> data;  
for (int i = 0; i < N; ++i)  
{  
    for (int k = 0; k < 2 * N; ++k)  
        data.push_back(k);  
    for (int k = 0; k < N; ++k)  
        data.pop_back();  
}  
Hmmman
  • 35
  • 5
  • The cost of the whole thing is O(n^2). This is because the inner loop is O(n) and the outer loop runs n times. – Mike Vine Jan 30 '19 at 12:24
  • But the number of calls to operator new/delete (which will _not_ dominate the complexity calculations and so is kinda irrelevant) will be O(lg(n)) in the first run of the outer loop and none for subsequent runs. – Mike Vine Jan 30 '19 at 12:28

2 Answers2

4

vector::push_back is not exactly O(1), but amortized O(1) which is required by C++ standard. See Constant Amortized Time

2

When reallocation happens, it doubles the allocated size of the vector so (for arbitrarily big values of N) in the given example, it will happen constant*log_2(N) times.

Yes, the complexity of the push_back call is amortized O(1) because reallocating does not take more time if the vector is big (better: the time does not depend on the size), but reallocation will still happen constant*log_2(N) times inside the loop (where constant != 0).

Finally, the complexity of reallocation in the k-loop example is O(log2(N)) and (edited) for the main loop, it's O(log2(N^2)) = O(2*log2(N)) = O(log2(N)).

L.C.
  • 1,008
  • 9
  • 18
  • (...) and not O(N*log2(N)) because it's the same vector! – L.C. Jan 30 '19 at 13:25
  • 1
    Re: "it doubles the allocated size" -- the key is that it **multiplies** by some factor. Many implementations these days use 1.5 rather than 2. But that's a minor detail. +1. – Pete Becker Jan 30 '19 at 14:46