.Net'teki öncelik sırası [kapalı]


216

Öncelik kuyruğu veya yığın veri yapısının .NET uygulamasını arıyorum

Öncelik kuyrukları, basit öğelere göre daha fazla esneklik sağlayan veri yapılarıdır, çünkü yeni öğelerin rasgele aralıklarla bir sisteme girmesine izin verirler. Öncelik kuyruğuna yeni bir iş eklemek, bu tür varışlarda her şeyi yeniden sıralamaktan çok daha uygun maliyetlidir.

Temel öncelik kuyruğu üç birincil işlemi destekler:

  • Ekleme (S, x). K tuşuyla x öğesi verildiğinde, bunu Q öncelik sırasına ekleyin.
  • (S)-Minimum Bul. Anahtar değeri, öncelik sırası Q'daki diğer anahtarlardan daha küçük olan öğeye bir işaretçi döndürün.
  • Sil-En az (S). Anahtarı minimum olan öncelik sırası Q'dan öğeyi kaldırın

Yanlış yere bakmadığım sürece, çerçevede bir tane yok. İyi olanın farkında olan var mı yoksa kendiminkini mi seçmeliyim?


34
Bilginize Bir geliştirdik bulunabilir kolay kullanımlı, son derece optimize C # öncelikli sırayı, burada . Özellikle yol bulma uygulamaları (A *, vb.) İçin geliştirilmiştir, ancak diğer uygulamalar için de mükemmel şekilde çalışmalıdır. Bunu bir cevap olarak gönderirim, ancak soru yakın zamanda kapatıldı ...
BlueRaja - Danny Pflughoeft

1
ParallelExtensionsExtras bir ConcurrentPriorityQueue vardır code.msdn.microsoft.com/ParExtSamples
VoteCoffee

Java eşzamanlı API'sini Spring.Net için .net'e taşıma çabasının bir parçası olarak Utanmazlıkla PriorityQueue'yu tanıtın. Tam genel desteğe sahip bir yığın ve kuyruk. İkili indirilebilir burada .
Kenneth Xu

@ BlueRaja-DannyPflughoeft Buna bir cevap ekleyebilir misiniz?
mafu

1
Özetlemek gerekirse. .Net'te yığın veri yapısı yok, şimdi .net çekirdeğinde değil. Rağmen Array.Sort kullanıcıları büyük sayılar için. Dahili uygulamalar var.
Artyom

Yanıtlar:


44

PowerCollections içindeki OrderedBagve OrderedSetsınıflarını öncelik sıraları olarak kullanmayı seviyorum .


60
OrderedBag / OrderedSet gerekenden daha fazla iş yapar, yığın yerine kırmızı-siyah bir ağaç kullanırlar.
Dan Berindei

3
@DanBerindei: çalışan hesaplama (eski öğeleri silme) yapmanız gerekiyorsa gerekli değildir, yığın yalnızca min veya maks silinmesini destekler
Svisstack

69

IntervalHeap'ı C5 Genel Koleksiyon Kütüphanesi'nden beğenebilirsiniz . Kullanım kılavuzunu alıntılamak için

Sınıf , çiftler dizisi olarak saklanan bir aralık yığını kullanarak IntervalHeap<T>arabirimi uygular IPriorityQueue<T>. FindMin ve FindMax işlemleri ve indeksleyicinin get-erişimcisi O (1) zamanını alır. DeleteMin, DeleteMax, Ekleme ve Güncelleme işlemleri ve indeksleyicinin set-erişimcisi zaman alır O (log n). Sıradan bir öncelik sırasının aksine, aralık yığını aynı verimlilikle hem minimum hem de maksimum işlemleri sunar.

API yeterince basit

> var heap = new C5.IntervalHeap<int>();
> heap.Add(10);
> heap.Add(5);
> heap.FindMin();
5

Nuget https://www.nuget.org/packages/C5 veya GitHub https://github.com/sestoft/C5/ adresinden yükleyin.


3
Bu çok sağlam bir kütüphane gibi görünüyor ve 1400 birim testi ile geliyor.
ECC-Dan

2
Kullanmaya çalıştım ama ciddi kusurları var. IntervalHeap yerleşik bir öncelik kavramına sahip değildir ve sizi IComparable veya IComparer'ı "Öncelik" değil sıralı bir koleksiyon haline getirmeye zorlar. Daha da kötüsü, önceki bazı girişlerin önceliğini güncellemenin doğrudan bir yolu yoktur !!!
morteza khosravi

52

İşte benim bir .NET yığın girişimim

public abstract class Heap<T> : IEnumerable<T>
{
    private const int InitialCapacity = 0;
    private const int GrowFactor = 2;
    private const int MinGrow = 1;

    private int _capacity = InitialCapacity;
    private T[] _heap = new T[InitialCapacity];
    private int _tail = 0;

    public int Count { get { return _tail; } }
    public int Capacity { get { return _capacity; } }

    protected Comparer<T> Comparer { get; private set; }
    protected abstract bool Dominates(T x, T y);

    protected Heap() : this(Comparer<T>.Default)
    {
    }

    protected Heap(Comparer<T> comparer) : this(Enumerable.Empty<T>(), comparer)
    {
    }

    protected Heap(IEnumerable<T> collection)
        : this(collection, Comparer<T>.Default)
    {
    }

    protected Heap(IEnumerable<T> collection, Comparer<T> comparer)
    {
        if (collection == null) throw new ArgumentNullException("collection");
        if (comparer == null) throw new ArgumentNullException("comparer");

        Comparer = comparer;

        foreach (var item in collection)
        {
            if (Count == Capacity)
                Grow();

            _heap[_tail++] = item;
        }

        for (int i = Parent(_tail - 1); i >= 0; i--)
            BubbleDown(i);
    }

    public void Add(T item)
    {
        if (Count == Capacity)
            Grow();

        _heap[_tail++] = item;
        BubbleUp(_tail - 1);
    }

    private void BubbleUp(int i)
    {
        if (i == 0 || Dominates(_heap[Parent(i)], _heap[i])) 
            return; //correct domination (or root)

        Swap(i, Parent(i));
        BubbleUp(Parent(i));
    }

    public T GetMin()
    {
        if (Count == 0) throw new InvalidOperationException("Heap is empty");
        return _heap[0];
    }

    public T ExtractDominating()
    {
        if (Count == 0) throw new InvalidOperationException("Heap is empty");
        T ret = _heap[0];
        _tail--;
        Swap(_tail, 0);
        BubbleDown(0);
        return ret;
    }

    private void BubbleDown(int i)
    {
        int dominatingNode = Dominating(i);
        if (dominatingNode == i) return;
        Swap(i, dominatingNode);
        BubbleDown(dominatingNode);
    }

    private int Dominating(int i)
    {
        int dominatingNode = i;
        dominatingNode = GetDominating(YoungChild(i), dominatingNode);
        dominatingNode = GetDominating(OldChild(i), dominatingNode);

        return dominatingNode;
    }

    private int GetDominating(int newNode, int dominatingNode)
    {
        if (newNode < _tail && !Dominates(_heap[dominatingNode], _heap[newNode]))
            return newNode;
        else
            return dominatingNode;
    }

    private void Swap(int i, int j)
    {
        T tmp = _heap[i];
        _heap[i] = _heap[j];
        _heap[j] = tmp;
    }

    private static int Parent(int i)
    {
        return (i + 1)/2 - 1;
    }

    private static int YoungChild(int i)
    {
        return (i + 1)*2 - 1;
    }

    private static int OldChild(int i)
    {
        return YoungChild(i) + 1;
    }

    private void Grow()
    {
        int newCapacity = _capacity*GrowFactor + MinGrow;
        var newHeap = new T[newCapacity];
        Array.Copy(_heap, newHeap, _capacity);
        _heap = newHeap;
        _capacity = newCapacity;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _heap.Take(Count).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class MaxHeap<T> : Heap<T>
{
    public MaxHeap()
        : this(Comparer<T>.Default)
    {
    }

    public MaxHeap(Comparer<T> comparer)
        : base(comparer)
    {
    }

    public MaxHeap(IEnumerable<T> collection, Comparer<T> comparer)
        : base(collection, comparer)
    {
    }

    public MaxHeap(IEnumerable<T> collection) : base(collection)
    {
    }

    protected override bool Dominates(T x, T y)
    {
        return Comparer.Compare(x, y) >= 0;
    }
}

public class MinHeap<T> : Heap<T>
{
    public MinHeap()
        : this(Comparer<T>.Default)
    {
    }

    public MinHeap(Comparer<T> comparer)
        : base(comparer)
    {
    }

    public MinHeap(IEnumerable<T> collection) : base(collection)
    {
    }

    public MinHeap(IEnumerable<T> collection, Comparer<T> comparer)
        : base(collection, comparer)
    {
    }

    protected override bool Dominates(T x, T y)
    {
        return Comparer.Compare(x, y) <= 0;
    }
}

Bazı testler:

[TestClass]
public class HeapTests
{
    [TestMethod]
    public void TestHeapBySorting()
    {
        var minHeap = new MinHeap<int>(new[] {9, 8, 4, 1, 6, 2, 7, 4, 1, 2});
        AssertHeapSort(minHeap, minHeap.OrderBy(i => i).ToArray());

        minHeap = new MinHeap<int> { 7, 5, 1, 6, 3, 2, 4, 1, 2, 1, 3, 4, 7 };
        AssertHeapSort(minHeap, minHeap.OrderBy(i => i).ToArray());

        var maxHeap = new MaxHeap<int>(new[] {1, 5, 3, 2, 7, 56, 3, 1, 23, 5, 2, 1});
        AssertHeapSort(maxHeap, maxHeap.OrderBy(d => -d).ToArray());

        maxHeap = new MaxHeap<int> {2, 6, 1, 3, 56, 1, 4, 7, 8, 23, 4, 5, 7, 34, 1, 4};
        AssertHeapSort(maxHeap, maxHeap.OrderBy(d => -d).ToArray());
    }

    private static void AssertHeapSort(Heap<int> heap, IEnumerable<int> expected)
    {
        var sorted = new List<int>();
        while (heap.Count > 0)
            sorted.Add(heap.ExtractDominating());

        Assert.IsTrue(sorted.SequenceEqual(expected));
    }
}

2
ExtractDominating, gerekenden daha uzun (potansiyel bellek sızıntısı) referans nesneye tutunmaz yığın değerini temizlemenizi tavsiye ederim. Değer türleri için açıkçası endişe edilmez.
Wout

5
Güzel ama ondan eşya çıkaramazsın? Bu, öncelik kuyrukları için önemli bir işlemdir.
Tom Larkworthy

Altta yatan nesne bir dizi gibi görünüyor. Bu bir ikili ağaç olarak daha iyi olmaz mıydı?
Grunion Shaftoe

1
@OhadSchneider çok güzel, sadece min yığın içine bakıyordum ve jenerik ve min veya max yığın yapmak ne yaptığını yapmaya çalıştım! büyük iş
Gilad

1
@Gilad IEqualityComparer<T>yeterli olmaz, çünkü bu sadece iki öğenin eşit olup olmadığını söylerken , aralarındaki ilişkiyi bilmeniz gerekir (kim daha küçük / daha büyük). Yine de kullanabileceğim doğru IComparer<T>...
Ohad Schneider

23

İşte yeni yazdım, belki de optimize edilmiş değil (sadece sıralı bir sözlük kullanır) ama anlaşılması basit. farklı türde nesneler ekleyebilirsiniz, böylece genel sıralar olmaz.

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++;

        }
    }
}

bu aynı önceliğe sahip birden fazla girişe izin vermiyor mu?
Nisan'da

2
öyle. Enqueue yöntemini çağırdığınızda, öğe bu önceliğin sırasına eklenir. (enqueue yöntemindeki diğer bölüm.)
kobi7

5
"Bilgisayar bilimi anlamında bir öncelik sırası değil" ile ne demek istiyorsun? Peki ya bunun bir öncelik kuyruğu olmadığına inanmanızı sağlar?
Mark Byers

14
-1 jenerik kullanmama.
Ocak'ta cdiggins

2
Heap / PriorityQueue'nun en büyük avantajlarından biri, min / maks ekstraksiyonunun O (1) karmaşıklığı, yani Peek işlemi. Ve burada numaralandırma kurulumu, döngü için vb. İçerir. Neden !? Ayrıca, O (logN) yerine "Enqueue" işlemi - yığının başka bir önemli özelliği, Queue girdisini eklemek için ikinci bir tane (yine O (longN)) nedeniyle "ContainsKey" ile bir O (longN) kaydırma özelliğine sahiptir. (gerekirse), kuyruğu (depolama [prio] satırı) gerçekten almak için üçüncü bir tane ve son olarak bu kuyruğa doğrusal bir ekleme. Bu, çekirdek algoritma uygulaması ışığında gerçekten çılgınca.
Jonan Georgiev


9

.NET için Microsoft Koleksiyonlarında belirtildiği gibi Microsoft , .NET Framework içinde 2 dahili PriorityQueue sınıfı yazdı (ve çevrimiçi paylaştı) . Kodları denemek için kullanılabilir.

DÜZENLEME: @ mathusum-mut yorumladığı gibi, Microsoft'un dahili PriorityQueue sınıflarından birinde bir hata var (SO topluluğu elbette bunun için düzeltmeler sağlamıştır): Microsoft'un dahili PriorityQueue <T>' sindeki hata ?


10
Buradaki uygulamalardan birinde bir hata bulundu: stackoverflow.com/questions/44221454/…
MathuSum Mut

ohh! PriorityQueue<T>Microsoft'un paylaşılan kaynağındaki tüm bu sınıfların internalerişim belirteci ile işaretlendiğini görebiliyorum . Bu yüzden sadece çerçevenin iç işlevleri tarafından kullanılırlar. Sadece windowsbase.dllbir C # projesine başvurarak genel tüketim için kullanılamazlar . Tek yol, paylaşılan kaynağı bir sınıf dosyası içinde projenin kendisine kopyalamaktır.
RBT


7
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;
    }
}

kolay.


13
Bazen gibi şeyler görmek for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2]; ve tek astar değerinde olup olmadığını merak ediyorum

1
@DustinBreakey kişisel stil :)
Shimou Dong 16:07

3
ama kesinlikle başkaları tarafından okunamaz. Soru işaretini geliştirmeyen kodun geliştiricinin başına yazılmasını düşünün.
alzaimar

3

Java Koleksiyonlar çerçevesindeki Java uygulamasında (java.util.PriorityQueue) bir Java'dan C # çevirmenine veya algoritmayı ve çekirdek kodunu daha akıllıca kullanın ve C # Koleksiyonlar çerçevesine yapışan kendi C # sınıfınıza takın Kuyruklar için API veya en azından Koleksiyonlar.


Bu işe yarıyor, ancak maalesef IKVM Java jeneriklerini desteklemediğinden tip güvenliğini kaybediyorsunuz.
Mekanik salyangoz

8
Derlenmiş Java bayt kodu ile uğraşırken "Java jenerikleri" diye bir şey yoktur. IKVM bunu destekleyemez.
Mark

3

AlgoKit

Aradım bir açık kaynak kütüphanesini yazdığı AlgoKit yoluyla ulaşılabilir, Nuget . Bu içerir:

  • Örtülü d-ary yığınları (ArrayHeap),
  • Binom yığınları ,
  • Yığınları eşleştirme .

Kod kapsamlı bir şekilde test edilmiştir. Kesinlikle denemenizi tavsiye ederim.

Misal

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);

Neden bu üç yığın?

En uygun uygulama seçimi, girişe bağımlıdır - Larkin, Sen ve Tarjan , öncelik kuyruklarının temelden başa ampirik bir deneysel çalışmasında gösterildiği gibi , arXiv: 1403.0252v1 [cs.DS] . Örtülü d-ary yığınlarını, eşleme yığınlarını, Fibonacci yığınlarını, binom yığınlarını, açık d-ary yığınlarını, rütbe eşleşmesini yığınlarını, deprem yığınlarını, ihlal yığınlarını, sıra rahatlığı zayıf yığınları ve katı Fibonacci yığınlarını test ettiler.

AlgoKit, test edilenler arasında en verimli olduğu görülen üç çeşit yığın içerir.

Seçim ipucu

Nispeten az sayıda eleman için, örtülü yığınlar, özellikle de dördüncül yığınlar (örtük 4-ary) kullanmakla ilgileneceksiniz. Daha büyük yığın boyutlarında çalışma durumunda, binom yığınları ve eşleştirme yığınları gibi itfa edilmiş yapılar daha iyi performans göstermelidir.



1

Son zamanlarda aynı sorunu yaşadım ve bunun için bir NuGet paketi oluşturdum.

Bu, yığın tabanlı standart bir öncelik kuyruğu uygular. Ayrıca BCL koleksiyonlarının tüm olağan inceliklerine sahiptir: ICollection<T>ve IReadOnlyCollection<T>uygulama, özel IComparer<T>destek, başlangıç ​​kapasitesini belirleme yeteneği DebuggerTypeProxyve koleksiyonun hata ayıklayıcıda çalışmasını kolaylaştırmak için.

Ayrıca, projenize yalnızca tek bir .cs dosyası yükleyen paketin Inline sürümü de vardır (harici olarak görünür bağımlılıklar almaktan kaçınmak istiyorsanız yararlıdır).

Daha fazla bilgi github sayfasında bulunabilir .


1

Basit bir Max Yığın Uygulaması.

https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace AlgorithmsMadeEasy
{
    class MaxHeap
    {
        private static int capacity = 10;
        private int size = 0;
        int[] items = new int[capacity];

        private int getLeftChildIndex(int parentIndex) { return 2 * parentIndex + 1; }
        private int getRightChildIndex(int parentIndex) { return 2 * parentIndex + 2; }
        private int getParentIndex(int childIndex) { return (childIndex - 1) / 2; }

        private int getLeftChild(int parentIndex) { return this.items[getLeftChildIndex(parentIndex)]; }
        private int getRightChild(int parentIndex) { return this.items[getRightChildIndex(parentIndex)]; }
        private int getParent(int childIndex) { return this.items[getParentIndex(childIndex)]; }

        private bool hasLeftChild(int parentIndex) { return getLeftChildIndex(parentIndex) < size; }
        private bool hasRightChild(int parentIndex) { return getRightChildIndex(parentIndex) < size; }
        private bool hasParent(int childIndex) { return getLeftChildIndex(childIndex) > 0; }

        private void swap(int indexOne, int indexTwo)
        {
            int temp = this.items[indexOne];
            this.items[indexOne] = this.items[indexTwo];
            this.items[indexTwo] = temp;
        }

        private void hasEnoughCapacity()
        {
            if (this.size == capacity)
            {
                Array.Resize(ref this.items,capacity*2);
                capacity *= 2;
            }
        }

        public void Add(int item)
        {
            this.hasEnoughCapacity();
            this.items[size] = item;
            this.size++;
            heapifyUp();
        }

        public int Remove()
        {
            int item = this.items[0];
            this.items[0] = this.items[size-1];
            this.items[this.size - 1] = 0;
            size--;
            heapifyDown();
            return item;
        }

        private void heapifyUp()
        {
            int index = this.size - 1;
            while (hasParent(index) && this.items[index] > getParent(index))
            {
                swap(index, getParentIndex(index));
                index = getParentIndex(index);
            }
        }

        private void heapifyDown()
        {
            int index = 0;
            while (hasLeftChild(index))
            {
                int bigChildIndex = getLeftChildIndex(index);
                if (hasRightChild(index) && getLeftChild(index) < getRightChild(index))
                {
                    bigChildIndex = getRightChildIndex(index);
                }

                if (this.items[bigChildIndex] < this.items[index])
                {
                    break;
                }
                else
                {
                    swap(bigChildIndex,index);
                    index = bigChildIndex;
                }
            }
        }
    }
}

/*
Calling Code:
    MaxHeap mh = new MaxHeap();
    mh.Add(10);
    mh.Add(5);
    mh.Add(2);
    mh.Add(1);
    mh.Add(50);
    int maxVal  = mh.Remove();
    int newMaxVal = mh.Remove();
*/

-3

Sistem kütüphanesinden bir PriorityQueuekullanımın aşağıdaki uygulaması SortedSet.

using System;
using System.Collections.Generic;

namespace CDiggins
{
    interface IPriorityQueue<T, K> where K : IComparable<K>
    {
        bool Empty { get; }
        void Enqueue(T x, K key);
        void Dequeue();
        T Top { get; }
    }

    class PriorityQueue<T, K> : IPriorityQueue<T, K> where K : IComparable<K>
    {
        SortedSet<Tuple<T, K>> set;

        class Comparer : IComparer<Tuple<T, K>> {
            public int Compare(Tuple<T, K> x, Tuple<T, K> y) {
                return x.Item2.CompareTo(y.Item2);
            }
        }

        PriorityQueue() { set = new SortedSet<Tuple<T, K>>(new Comparer()); }
        public bool Empty { get { return set.Count == 0;  } }
        public void Enqueue(T x, K key) { set.Add(Tuple.Create(x, key)); }
        public void Dequeue() { set.Remove(set.Max); }
        public T Top { get { return set.Max.Item1; } }
    }
}

6
Sette eklemeye çalıştığınız öğeyle aynı "önceliğe" sahip bir öğeniz varsa SortedSet.Add başarısız olur (ve false değerini döndürür). Yani ... A.Compare (B) == 0 ve A zaten listede varsa, PriorityQueue.Enqueue işleviniz sessizce başarısız olur.
Joseph

Ne açıklamak Zihin T xve K key? Bu yinelenen izin için bir hile olduğunu tahmin T xve benzersiz bir anahtar (örneğin UUID) oluşturmak gerekir?
Thariq Nugrohotomo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.