Если нам нужны коллекции FIFO или LIFO (в основном push, pop и front/back), что мы должны использовать в Rust? Что-то вроде std::queue или std::stack из С++.
Есть ли коллекции очереди и стека?
Ответ 1
Прежде всего, Rust не предлагает (в стандартной библиотеке) любую библиотеку с гарантированной задержкой для добавления элементов: коллекции Rust обычно могут выделять память при добавлении новых элементов, а выделение памяти может занимать неограниченное количество времени в худшем случай.
При этом для каждого случая есть два претендента:
- стек может быть реализован либо поверх
Vec, либоLinkedList(обе функцииpop_backиpush_back) - очередь может быть реализована либо поверх
VecDeque, либоLinkedList(обе функцииpop_frontиpush_back)
Разница между Vec* и LinkedList заключается в том, что последняя упрощена: для каждого вызова push_back выполняется выделение памяти. С одной стороны, это здорово, потому что это означает, что стоимость push_back не зависит от количества элементов, уже находящихся в коллекции, с другой стороны... ну, распределение памяти может занять очень много времени.
Первое немного сложнее:
- он имеет лучшую пропускную способность, благодаря более удобной кешировке
- он имеет дополнительную емкость, гарантируя невыделение
push_back, пока существует избыточная емкость. - он все еще сохраняет амортизацию O (1)
push_back, даже если не резервировать избыточную мощность раньше времени
В общем, я бы посоветовал использовать Vec для стека и VecDeque для очереди.
Ответ 2
И VecDeque и LinkedList имеют push/pop _ front/back.
Ответ 3
У Матье М. это почти идеально. Vec - ваш стек (LIFO), а VecDeque - двусторонняя очередь, которая поддерживает все 4 варианта (FIFO, FILO, LIFO и LILO), используя:
.push_front(x) | .front() | .pop_front()
.push_back(x) | .back() | .pop_back()
Если вы хотите максимально повысить свою эффективность, я рекомендую ознакомиться с разделом "Общие сведения о Rusts Vec и его способности создавать быстрые и эффективные программы". В нем более подробно рассказывается о том, как происходит распределение и перераспределение в Vec и VecDeque, но самый большой VecDeque заключается в том, что если вы можете предсказать максимальное количество элементов, которые вам понадобятся в очереди, вы можете использовать VecDeque::with_capacity(x) если вы знаете, когда инициализируете его, или .reserve_exact(x) если в какой-то момент вы точно знаете, сколько еще слотов вам понадобится
Я настоятельно рекомендую ознакомиться с документацией по Rust на std::collections, в ней есть превосходный список наиболее распространенных коллекций, используемых в Rust, а также предложения о том, когда выбирать каждую из них.
И последнее, VecDeque не является частью прелюдии по умолчанию в Rust, поэтому, если вы хотите использовать ее, вам нужно включить это:
use std::collections::VecDeque;