Какова временная сложность получения максимального ключа std :: map в C ++? - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь найти наибольшее значение в std::map, которое будет последним узлом в дереве (поскольку ключи std::map отсортированы).

Cppref говорит, что std::map.end() - это постоянное время. Но чтобы получить самый большой ключ, я должен получить предыдущее значение этого итератора, то есть *std::prev(std::map.end()).

Какова временная сложность этой операции?

Я понимаю, что это должно быть эквивалентно --std::map.end(), но я также не знаю стоимость этой операции.

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

Прогресс в любом направлении является линейным по количеству авансов (в вашем случае это один , поэтому мы можем назвать его постоянным временем), но вам не нужно сделай это. Просто используйте rbegin(), который является итератором последнего элемента.

std::prev равно , а не эквивалентно --std::map.end(), хотя последний не гарантирует ничего полезного. См. std::prev документы.

0 голосов
/ 02 ноября 2018

Но чтобы получить самый большой ключ, я должен получить предыдущее значение этого итератора, т.е. *std::prev(std::map.end()).

Какова временная сложность этой операции?

Все std::map.end, std::prev(a_std_map_iterator) и std::map::iterator::operator* являются постоянными операциями. Следовательно, это выражение является константой в целом.

Обратите внимание, что сложность std::prev гарантированно будет максимально линейной с точки зрения второго аргумента n, который по умолчанию равен 1. Когда n является постоянным, std::prev в целом является постоянным.

0 голосов
/ 02 ноября 2018

Используйте взамен std::map::rbegin(), что:

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

и

Сложность

Constant.

где последнее слово должно звучать как музыка в ваших ушах.


std::prev(std::map.end()) - константа в сложности.


Более того, ваше понимание эквивалентности неверно.

С std::prev примечания:

Хотя выражение --c.end() часто компилируется, оно не гарантированно сделает это: c.end() является выражением rvalue, и есть нет требования к итератору, которое указывает, что уменьшение значения гарантированно работать. В частности, когда итераторы реализованы как указатели, --c.end() не не компилируются, а std::prev(c.end()) делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...