我正在寻找优先级队列或堆数据结构的.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

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


当前回答

这是我刚刚写的一个,也许它没有那么优化(只是使用了一个排序的字典),但很容易理解。 您可以插入不同类型的对象,因此没有泛型队列。

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;

namespace PrioQueue
{
    public class PrioQueue
    {
        int total_size;
        SortedDictionary<int, Queue> storage;

        public PrioQueue ()
        {
            this.storage = new SortedDictionary<int, Queue> ();
            this.total_size = 0;
        }

        public bool IsEmpty ()
        {
            return (total_size == 0);
        }

        public object Dequeue ()
        {
            if (IsEmpty ()) {
                throw new Exception ("Please check that priorityQueue is not empty before dequeing");
            } else
                foreach (Queue q in storage.Values) {
                    // we use a sorted dictionary
                    if (q.Count > 0) {
                        total_size--;
                        return q.Dequeue ();
                    }
                }

                Debug.Assert(false,"not supposed to reach here. problem with changing total_size");

                return null; // not supposed to reach here.
        }

        // same as above, except for peek.

        public object Peek ()
        {
            if (IsEmpty ())
                throw new Exception ("Please check that priorityQueue is not empty before peeking");
            else
                foreach (Queue q in storage.Values) {
                    if (q.Count > 0)
                        return q.Peek ();
                }

                Debug.Assert(false,"not supposed to reach here. problem with changing total_size");

                return null; // not supposed to reach here.
        }

        public object Dequeue (int prio)
        {
            total_size--;
            return storage[prio].Dequeue ();
        }

        public void Enqueue (object item, int prio)
        {
            if (!storage.ContainsKey (prio)) {
                storage.Add (prio, new Queue ());
              }
            storage[prio].Enqueue (item);
            total_size++;

        }
    }
}

其他回答

你可能会发现这个实现很有用: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx

它是通用的,基于堆数据结构

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

NGenerics PriorityQueue

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

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

AlgoKit

我写了一个名为AlgoKit的开源库,可以通过NuGet获得。它包含:

隐式d-ary堆(ArrayHeap), 二项堆, 配对堆。

代码已经经过了广泛的测试。我强烈建议你试一试。

例子

var comparer = Comparer<int>.Default;
var heap = new PairingHeap<int, string>(comparer);

heap.Add(3, "your");
heap.Add(5, "of");
heap.Add(7, "disturbing.");
heap.Add(2, "find");
heap.Add(1, "I");
heap.Add(6, "faith");
heap.Add(4, "lack");

while (!heap.IsEmpty)
    Console.WriteLine(heap.Pop().Value);

为什么有三堆?

实现的最佳选择强烈依赖于输入-正如Larkin, Sen和Tarjan在优先队列的回归基础经验研究中所显示的,arXiv:1403.0252v1 [cs.DS]。他们测试了隐式d-ary堆、配对堆、斐波那契堆、二项式堆、显式d-ary堆、排名配对堆、震动堆、违反堆、排名放松的弱堆和严格斐波那契堆。

AlgoKit具有三种类型的堆,在测试中似乎是最有效的。

关于选择的提示

对于数量相对较少的元素,您可能会对使用隐式堆感兴趣,特别是第四元堆(隐式4元)。在操作较大堆大小的情况下,像二项式堆和配对堆这样的平摊结构应该执行得更好。