@Quark_Hell
C++ программист

Почему доступ к элементам vector-а O(1)?

Насколько я понял, при создании массива в памяти выделяется фиксированное количество ячеек, которые располагаются последовательно, благодаря чему по времени доступ к каждой ячейке постоянный.

А с вектором дела обстоят иначе. Каждый элемент хранит указатель на следующий после него.

Почему тогда поулчение любого элемента вектора всё-равно остаётся O(1)? Ведь для получения элемента нам нужно сначала пройти все предыдущие, а это уже O(n)
  • Вопрос задан
  • 275 просмотров
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
А с вектором дела обстоят иначе. Каждый элемент хранит указатель на следующий после него.

Такое поведение имеет список, односвязный или двусвязный.

Вектор же реализован как непрерывный блок памяти, внутри которого последовательно размещены его элементы. Благодаря этому элементы вектора доступны не только через итераторы, но и через адресную арифметику.

Именно поэтому доступ к любому элементу вектора имеет сложность O(1). Это просто смещение на индекс элемента относительно начала блока памяти с помощью адресной арифметики.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Irval
Дело в том, что std::vector - достаточно хитрая структура, использующая непрерывные блоки памяти для реализации "динамического" массива. Сам объект хранит в себе 2 различных размера - capacity (вместимость) и непосредственно size. Последний численно равен количеству добавленных Вами элементов, а вот с capacity дела обстоят чуточку сложнее.
Как Вы, думаю знаете, амортизационная асимптотика вставки элемента в вектор равна O(1). Это достигается благодаря "разрастанию" capacity вдвое каждый раз, когда размер массива переваливает за его вместимость. Структура ищет в памяти блок, размер которого равен 2 * capacity и объявляет его занятым, после чего перемещает всю информацию туда. Поскольку массив хранится на непрерывном участке памяти, то к нему вполне применима адресная арифметика, то есть расстояние от первого элемента вектора до i-ого равно sizeof(datatype) * i. Именно благодаря этому доступ к произвольному элементу осуществляется за константное время.

Условия, который были описаны Вами, относятся к указательным структурам данных, где каждый элемент указывает на следующий/предыдущий.
Ответ написан
Комментировать
@dima20155
you don't choose c++. It chooses you
То, что вы называете вектором - это связанный список, по своей сути. Вот статья навики. Слово вектор, насколько, я знаю, не используется в контексте классических структур банных. Если же под вектором имеется в виду std::vector, то данный вектор создан на основе динамического массива.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы