web-dev-qa-db-fra.com

Classe de tas dans .NET

Duplicata possible:
tas de Fibonacci, binaire ou binomial en c #?

Existe-t-il une classe comme heap dans .NET? J'ai besoin d'une sorte de collection à partir de laquelle je peux récupérer min. élément. Je veux juste 3 méthodes:

  • Ajouter()
  • RemoveMinElement ()
  • GetMinElement ()

Je ne peux pas utiliser de liste triée car les clés doivent être uniques et je pourrais avoir plusieurs éléments identiques.

19
Tomek Tarczynski

Vous pouvez utiliser SortedList ou SortedDictionary (voir la discussion ci-dessous) avec une clé personnalisée. Si vous avez utilisé un type avec une égalité référentielle, mais que vous pouvez le comparer en fonction de la valeur qui vous intéresse, cela peut fonctionner.

Quelque chose comme ça:

class HeapKey : IComparable<HeapKey>
{
    public HeapKey(Guid id, Int32 value)
    {
        Id = id;
        Value = value;
    }

    public Guid Id { get; private set; }
    public Int32 Value { get; private set; }

    public int CompareTo(HeapKey other)
    {
        if (_enableCompareCount)
        {
            ++_compareCount;
        }

        if (other == null)
        {
            throw new ArgumentNullException("other");
        }

        var result = Value.CompareTo(other.Value);

        return result == 0 ? Id.CompareTo(other.Id) : result;
    }
}

Voici un exemple pratique d'utilisation d'un SortedDictionary qui a des caractéristiques de performances de tas binaire:

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

namespace SortedDictionaryAsBinaryHeap
{
    class Program
    {
        private static Boolean _enableCompareCount = false;
        private static Int32 _compareCount = 0;

        static void Main(string[] args)
        {
            var rnd = new Random();

            for (int elementCount = 2; elementCount <= 6; elementCount++)
            {
                var keyValues = Enumerable.Range(0, (Int32)Math.Pow(10, elementCount))
                    .Select(i => new HeapKey(Guid.NewGuid(), rnd.Next(0, 10)))
                    .ToDictionary(k => k);
                var heap = new SortedDictionary<HeapKey, HeapKey>(keyValues);

                _compareCount = 0;
                _enableCompareCount = true;
                var min = heap.First().Key;
                _enableCompareCount = false;
                Console.WriteLine("Element count: {0}; Compare count for getMinElement: {1}",
                                  (Int32)Math.Pow(10, elementCount),
                                  _compareCount);   

                _compareCount = 0;
                _enableCompareCount = true;
                heap.Remove(min);
                _enableCompareCount = false;
                Console.WriteLine("Element count: {0}; Compare count for deleteMinElement: {1}", 
                                  (Int32)Math.Pow(10, elementCount),  
                                  _compareCount);   
            }

            Console.ReadKey();
        }

        private class HeapKey : IComparable<HeapKey>
        {
            public HeapKey(Guid id, Int32 value)
            {
                Id = id;
                Value = value;
            }

            public Guid Id { get; private set; }
            public Int32 Value { get; private set; }

            public int CompareTo(HeapKey other)
            {
                if (_enableCompareCount)
                {
                    ++_compareCount;
                }

                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }

                var result = Value.CompareTo(other.Value);

                return result == 0 ? Id.CompareTo(other.Id) : result;
            }
        }
    }
}

Résultats:

Nombre d'éléments: 100; Comparer le nombre de getMinElement: 0

Nombre d'éléments: 100; Comparer le nombre de deleteMinElement: 8

Nombre d'éléments: 1000; Comparer le nombre de getMinElement: 0

Nombre d'éléments: 1000; Comparer le nombre de deleteMinElement: 10

Nombre d'éléments: 10000; Comparer le nombre de getMinElement: 0

Nombre d'éléments: 10000; Comparer le nombre de deleteMinElement: 13

Nombre d'éléments: 100000; Comparer le nombre de getMinElement: 0

Nombre d'éléments: 100000; Comparer le nombre de deleteMinElement: 14

Nombre d'éléments: 1000000; Comparer le nombre de getMinElement: 0

Nombre d'éléments: 1000000; Comparer le nombre de deleteMinElement: 21

10
codekaizen

Les files d'attente prioritaires semblent correspondre à votre problème: file d'attente prioritaire en .Net

Google pour les "files d'attente prioritaires C #" pour plus d'implémentations.

2
Ed Power