@Junior007

Как работает std::list?

Как реализуется контейнер std::list в C++?

Конкретно, не могу понять эти строки:
1) "Список представляет собой контейнер, который поддерживает быструю вставку и удаление элементов из любой позиции в контейнере.
Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions."

2) "Быстрый произвольный доступ не поддерживается.
The main drawback of lists and forward_lists compared to these other sequence containers is that they lack direct access to the elements by their position


Любая позиция и произвольный доступ не одно и тоже?

Исходя из первого утверждения, если напишу:
myList.emplace(it, 5, "Value"); // То это должно быть очень быстро


А судя по второму, такая запись должна работать за O(n)
  • Вопрос задан
  • 1551 просмотр
Решения вопроса 2
@Free_ze
Пишу комментарии в комментарии, а не в ответы
Произвольный доступ - это доступ по индексу, с константной сложностью (O(1)), когда вычисляется смещение и мы можем сразу перейти к нужному элементу, как в std::vector через [] или метод at(index).

В std::list, чтобы попасть (вставить, удалить и т.п.) куда-то в середину, мы должны в это место попасть, попутно обойдя все ниже(выше) лежащие элементы, один за другим. Это достаточно медленно (O(n)). Но сама вставка будет дешевой в любом месте (O(1)).
Ответ написан
@Xano
Лист - не упорядоченный в памяти массив, связь между элементами осуществляется путем сохранения указателя на следующий и/или предыдущий элемент. При удалении или добавлении элемента всего лишь меняются эти самые указатели - это объясняет "поддерживает быструю вставку и удаление элементов из любой позиции в контейнере".

"myList.emplace(it, 5, "Value"); " отработает следующим образом ( условно )
auto item = new ItemType( 5, "Value" );
item->next = it->next;
it->next = item;

Быстрый произвольный доступ - подразумевает доступ к N элементу за константное время. Лист же предоставляет доступ лишь за линейное время, т.к. для доступа к N элементу необходимо перебрать все предыдущие элементы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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