Сложность для нового /alloc для метода vector :: push_back

Вопрос: Какова сложность для операций alloc (realloc)/new для кода ниже, для огромных значений N. Насколько я понял push_back выделяет память: size = cst * old_size; cst = 2; // для gcc Таким образом, у нас есть O (1) внутри цикла k и ~ O (N) внутри цикла i. В итоге я имею O (N), я

Вопрос:

Какова сложность для операций alloc (realloc)/new для кода ниже, для огромных значений N.

Насколько я понял push_back выделяет память:
size = cst * old_size;
cst = 2; // для gcc
Таким образом, у нас есть O (1) внутри цикла k и ~ O (N) внутри цикла i. В итоге я имею O (N), я прав?

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(); } Лучший ответ:

Когда происходит перераспределение, он удваивает выделенный размер вектора, поэтому (для произвольно больших значений N) в данном примере это будет происходить постоянными * log_2 (N) раз.

Да, сложность вызова push_back амортизируется O (1), потому что перераспределение не займет больше времени, если вектор большой (лучше: время не зависит от размера), но перераспределение все равно будет происходить постоянным * log_2 (N) раз внутри цикла (где константа! = 0).

Наконец, сложность перераспределения в примере k-цикла составляет O (log2 (N)) и (отредактировано) для основного цикла, это O (log2 (N ^ 2)) = O (2 * log2 (N)) = O (log2 (N)).

Ответ №1

vector :: push_back – это не O (1), а амортизированный O (1), что требуется стандартом C++. См постоянное амортизированное время

Ответ №2

Как правило, если оставить в стороне код, который вызывает перераспределения, долгосрочное поведение push_back и последующие перераспределения больше похожи на O (log (N)), хотя стандарт C++ этого не требует.

Оцените статью
Добавить комментарий