【问题标题】:Why doesn't the .Net framework have a priority queue class?为什么 .Net 框架没有优先级队列类?
【发布时间】:2010-12-26 08:58:43
【问题描述】:

Stack Overflow 上有一些线程处理实现priority queues in .Net and C#。

我的问题具有更基本的性质:为什么 .Net 框架中没有开箱即用的优先级队列?甚至 C++ 标准库也有。

【问题讨论】:

标签: .net data-structures priority-queue standard-library library-design


【解决方案1】:

不久前有一个问题 (why C# does allow non-member functions like C++) 促使 Eric Lippert 写了一封 blog post 来说明原因。他在其中解释说:

有人问我“为什么 C# 不实现功能 X?”每时每刻。答案总是一样的:因为从来没有人设计、指定、实施、测试、记录和发布该功能。所有这六件事都是使功能发生所必需的。所有这些都花费了大量的时间、精力和金钱。功能并不便宜,我们非常努力地确保仅发布那些在时间、精力和资金预算有限的情况下为用户带来最大利益的功能。

我怀疑这可能就是为什么 .Net 没有提供优先级队列的答案 - 只是没有足够的时间、精力、金钱、需求(?)来实现一个。

【讨论】:

  • 谢谢,阿德里安,我在他写这篇博文时读过。我也很想听听非 MS 人员的意见 - 框架中实际上不需要数据结构吗?让所有其他开发人员自行实施是否足够微不足道?等等。我知道我的立场,但我可以根据别人的意见进行调整。 :-)
  • 时间是优先级的问题。如果他们说没有足够的时间,那么问题就变成了:“为什么不包含优先级队列,而要包含xxx?”并且 xxx 可以比优先级队列更少使用。我不知道,也许取 xxx=HybridDictionary。我敢肯定,他们有一些本来可以省略的东西,以便为优先队列腾出时间。
  • 是的,这正是我的意思,但你表述得更好...... ;-)
  • 要记住的一点是框架本身利用了框架的内容。举个例子:如果你看看HybridDictionary的用法,它被框架内部使用了很多(尤其是System.Windows.*和System.Web.*)。不需要HybridDictionary 作为框架的消费者(因此没有将其视为优先级队列的高优先级)并不一定意味着应该省略HybridDictionary - 它可能需要实现内部和所以被公开了。
  • 看这个:github.com/dotnet/runtime/issues/14032#issuecomment-656700280,他们需要 5 年,仍然没有PriorityQueue。
【解决方案2】:

.NET 4.0 引入了一个SortedSet<T> 类,以及由SortedSet<T> 和HashSet<T> 实现的ISet<T> 接口。这显然会使实现您自己的PriorityQueue<T> 类变得更简单。

但是,仍然没有IQueue<T> 接口,它至少承认需要优先级队列或除基本 BCL Queue<T> 之外的任何其他实现。同样,没有IStack<T>。

我个人觉得缺少这些最基本的接口令人失望和短视,特别是因为从现有类中提取简单接口的设计/规范/实现/测试/文档成本确实应该非常低。

public interface IQueue<T> : IEnumerable<T>, ICollection, IEnumerable
{
    T Dequeue();
    void Enqueue(T item);
    T Peek();
}

在那里,看到了吗?我已经做到了。

【讨论】:

  • 你已经编写了接口,但是类呢? .Net 中没有多少接口没有至少一个实现。
  • 该接口是否可以被不可枚举的队列使用,比如异步通信队列?那么队列端点呢,它们是否应该有自己的接口,以便您只能将推送功能赋予代码的一部分,而将拉能力赋予另一部分?问题不在于编写那 5 行代码,问题在于设计它以便没有人抱怨,并且它在此过程中为 .NET 运行时创造了价值。
  • ck:参见 System.Collections.Generic.Queue Lasse:异步/并发集合没有相同的行为契约,因此它们不需要实现接口。我的观点是,BCL 团队的态度似乎是,如果他们只提供一个构造的实现,就不需要接口,这不是正确的态度。恕我直言。
【解决方案3】:

这已正式成为 announced 并且在 .NET 6 预览版中。

PriorityQueue (System.Collections.Generic) 是一个新集合,可以添加具有值和优先级的新项目。在出队时,PriorityQueue 返回具有最低优先级值的元素。您可以认为这个新集合类似于 Queue,但每个入队元素都有一个影响出队行为的优先级值。

以下示例演示了 PriorityQueue 的行为。

// creates a priority queue of strings with integer priorities
var pq = new PriorityQueue<string, int>();

// enqueue elements with associated priorities
pq.Enqueue("A", 3);
pq.Enqueue("B", 1);
pq.Enqueue("C", 2);
pq.Enqueue("D", 3);

pq.Dequeue(); // returns "B"
pq.Dequeue(); // returns "C"
pq.Dequeue(); // either "A" or "D", stability is not guaranteed.

【讨论】:

    【解决方案4】:

    截至 2021 年 1 月,.Net Core 添加了 PriorityQueue 实现。可以在此处找到对 repo 和 API 的实际提交:https://github.com/dotnet/runtime/commit/826aa4f7844fd3d48784025ec6d47010867baab4

    【讨论】:

      【解决方案5】:

      它现在作为 .NET6 的一部分提供。查看以下博客文章以了解实施情况。

      https://dotnetcoretutorials.com/2021/03/17/priorityqueue-in-net/

      【讨论】:

        【解决方案6】:

        看这个:Add PriorityQueue to Collections,他们花了 farking 5 年,仍然没有 PriorityQueue。

        【讨论】:

          猜你喜欢
          • 2011-12-25
          • 2019-01-02
          • 2014-03-05
          • 2010-10-18
          • 2014-01-12
          • 2016-09-23
          • 1970-01-01
          • 2023-04-03
          • 2011-12-20
          相关资源
          最近更新 更多