是否有队列和堆栈集合?

时间:2016-11-28 16:17:57

标签: rust

如果我们需要FIFO或LIFO集合(基本上pushpopfront / back),我们应该在Rust中使用什么?类似于C ++中的std::queuestd::stack

3 个答案:

答案 0 :(得分:21)

首先,Rust不提供(在标准库中)任何具有添加元素延迟的库:Rust集合通常可以在添加新元素时分配内存,并且分配内存可能需要在最坏的情况下,无限的时间。

话虽如此,每个案件都有两个竞争者:

  • 可以在VecLinkedList之上实现堆栈(功能pop_backpush_back
  • 队列可以在VecDequeLinkedList之上实现(功能pop_frontpush_back

Vec*LinkedList之间的区别在于后者是简单的:每次调用push_back都会进行内存分配。一方面,这很好,因为这意味着push_back的成本与集合中已有元素的数量无关,另一方面......内存分配可能需要很长时间

前者有点复杂:

  • 由于具有更高的缓存友好性,它具有更高的吞吐量
  • 它有额外的容量,只要容量过剩,就可以保证不分配push_back
  • 即使不提前预留过剩产能,它仍然维持摊销 O(1)push_back

一般来说,我建议将Vec用于堆栈,将VecDeque用于队列。

答案 1 :(得分:9)

VecDequeLinkedList都有push / pop _ front / back

答案 2 :(得分:2)

Matthieu M.几乎完美。 Vec是您的堆栈(LIFO),VecDeque是一个双端队列,它使用以下方式支持所有4个变体(FIFO,FILO,LIFO和LILO):

.push_front(x) | .front() | .pop_front()
.push_back(x)  | .back()  | .pop_back()

如果您想最大程度地提高效率,建议您参考"Unterstanding Rust’s Vec and its capacity for fast and efficient programs"。它详细介绍了如何在VecVecDeque中进行分配和重新分配,但是最大的收获是,如果您可以预测在数据库中需要的最大元素数量,如果知道何时初始化队列,则可以使用VecDeque::with_capacity(x)队列,如果某个时刻您确切知道将需要多少 个插槽,可以使用.reserve_exact(x)

我强烈建议您查看std::collections上的Rust文档,其中列出了Rust中最常用的收藏集,以及有关何时选择它们的建议

最后一件事,VecDeque不是Rust中默认序言的一部分,因此,如果要使用它,则需要包括以下内容:

use std::collections::VecDeque;