我正在寻找优先级队列或堆数据结构的.NET实现

Priority queues are data structures that provide more flexibility than simple sorting, because they allow new elements to enter a system at arbitrary intervals. It is much more cost-effective to insert a new job into a priority queue than to re-sort everything on each such arrival. The basic priority queue supports three primary operations: Insert(Q,x). Given an item x with key k, insert it into the priority queue Q. Find-Minimum(Q). Return a pointer to the item whose key value is smaller than any other key in the priority queue Q. Delete-Minimum(Q). Remove the item from the priority queue Q whose key is minimum

除非我找错地方了,否则框架里没有。有谁知道好的吗,还是我自己卷?


当前回答

在Java Collections框架中的Java实现(Java .util. priorityqueue)上使用Java到c#的转换器,或者更智能地使用算法和核心代码,并将其插入到您自己制作的c#类中,该类遵循c# Collections框架用于队列的API,或者至少是Collections。

其他回答

下面是来自NGenerics团队的另一个实现:

NGenerics PriorityQueue

我喜欢使用PowerCollections中的OrderedBag和OrderedSet类作为优先队列。

. net 6+:正如@rustyx评论的那样,. net 6添加了System.Collections.Generic。PriorityQueue < TElement, TPriority >类。FWIW是开源的,用c#实现的。

早期的。net核心版本和。net框架:微软在。net框架中编写(并在线共享)了2个内部的PriorityQueue类。然而,正如@ mathumum -mut所评论的那样,其中有一个错误(SO社区当然已经提供了修复):微软内部PriorityQueue<T>?

class PriorityQueue<T>
{
    IComparer<T> comparer;
    T[] heap;
    public int Count { get; private set; }
    public PriorityQueue() : this(null) { }
    public PriorityQueue(int capacity) : this(capacity, null) { }
    public PriorityQueue(IComparer<T> comparer) : this(16, comparer) { }
    public PriorityQueue(int capacity, IComparer<T> comparer)
    {
        this.comparer = (comparer == null) ? Comparer<T>.Default : comparer;
        this.heap = new T[capacity];
    }
    public void push(T v)
    {
        if (Count >= heap.Length) Array.Resize(ref heap, Count * 2);
        heap[Count] = v;
        SiftUp(Count++);
    }
    public T pop()
    {
        var v = top();
        heap[0] = heap[--Count];
        if (Count > 0) SiftDown(0);
        return v;
    }
    public T top()
    {
        if (Count > 0) return heap[0];
        throw new InvalidOperationException("优先队列为空");
    }
    void SiftUp(int n)
    {
        var v = heap[n];
        for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
        heap[n] = v;
    }
    void SiftDown(int n)
    {
        var v = heap[n];
        for (var n2 = n * 2; n2 < Count; n = n2, n2 *= 2)
        {
            if (n2 + 1 < Count && comparer.Compare(heap[n2 + 1], heap[n2]) > 0) n2++;
            if (comparer.Compare(v, heap[n2]) >= 0) break;
            heap[n] = heap[n2];
        }
        heap[n] = v;
    }
}

一件容易的事。

我最近也遇到了同样的问题,最后为此创建了一个NuGet包。

这实现了一个标准的基于堆的优先级队列。它还具有BCL集合的所有常见的优点:ICollection<T>和IReadOnlyCollection<T>实现,自定义IComparer<T>支持,指定初始容量的能力,以及使集合更容易在调试器中使用的DebuggerTypeProxy。

还有一个内联版本的包,它只安装一个.cs文件到你的项目中(如果你想避免外部可见的依赖关系,这很有用)。

更多信息请访问github页面。