22

重複の可能性:
c# のフィボナッチ、バイナリ、または二項ヒープ?

.NET にヒープのようなクラスはありますか? 分を取得できるコレクションが必要です。エレメント。私はちょうど3つの方法が欲しい:

  • Add()
  • RemoveMinElement()
  • GetMinElement()

キーは一意である必要があり、同じ要素がいくつかある可能性があるため、並べ替えられたリストは使用できません。

4

2 に答える 2

14

SortedListまたはSortedDictionary(以下の説明を参照) をカスタム キーと共に使用できます。参照の等価性を持つ型を使用したが、関心のある値に基づいて比較できる場合、これは機能する可能性があります。

このようなもの:

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

SortedDictionaryバイナリヒープのパフォーマンス特性を持つを使用した実際の例を次に示します。

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

結果:

要素数: 100; getMinElement の比較回数: 0

要素数: 100; deleteMinElement の比較回数: 8

要素数: 1000; getMinElement の比較回数: 0

要素数: 1000; deleteMinElement の比較カウント: 10

要素数: 10000; getMinElement の比較回数: 0

要素数: 10000; deleteMinElement の比較回数: 13

要素数: 100000; getMinElement の比較回数: 0

要素数: 100000; deleteMinElement の比較回数: 14

要素数: 1000000; getMinElement の比較回数: 0

要素数: 1000000; deleteMinElement の比較カウント: 21

于 2010-02-09T19:21:30.003 に答える
2

プライオリティ キューは、問題にぴったりのように見えます: .Net のプライオリティ キュー

より多くの実装については、Google で「C# プライオリティ キュー」を参照してください。

于 2010-02-09T20:23:22.640 に答える