Це може бути O (1), якщо в списку буде зберігатися прапор, який дозволяє міняти значення покажчиків " prev
" та " next
", які має кожен вузол. Якщо повернення списку буде частою операцією, таке доповнення може бути насправді корисним, і я не знаю жодної причини, чому його застосування було б заборонено чинним стандартом. Однак наявність такого прапора зробить звичайне прокручування списку дорожче (якщо тільки постійним фактором), тому що замість цього
current = current->next;
в operator++
ітераторі списку ви отримаєте
if (reversed)
current = current->prev;
else
current = current->next;
що ви не вирішили легко додати. Зважаючи на те, що списки, як правило, проходять набагато частіше, ніж вони перевертаються, було б дуже нерозумно, щоб стандарт надавав цю методику. Тому зворотній операції дозволяється мати лінійну складність. Зауважте, однак, що t ∈ O (1) ⇒ t ∈ O ( n ), тому, як було сказано раніше, технічна реалізація вашої "оптимізації" буде дозволена.
Якщо ви родом з Java або подібного фону, вам може бути цікаво, чому ітератор повинен перевіряти прапор кожен раз. Чи не могли б ми замість цього мати два різних ітераторних типи, обидва похідні від загального базового типу, і мати std::list::begin
і std::list::rbegin
поліморфно повернути відповідний ітератор? Хоча це можливо, це зробить все ще гірше, тому що просування ітератора було б непрямим (важко вбудованим) викликом функції. У Java ви все одно платите за цю ціну регулярно, але знову ж таки, це одна з причин, коли багато людей досягають C ++, коли продуктивність критична.
Як вказував у коментарях Бенджамін Ліндлі , оскільки reverse
ітераторів не можна визнати недійсними, єдиним підходом, дозволеним стандартом, є збереження вказівника назад до списку всередині ітератора, що викликає подвійний непрямий доступ до пам'яті.