重複の可能性:
c# のフィボナッチ、バイナリ、または二項ヒープ?
.NET にヒープのようなクラスはありますか? 分を取得できるコレクションが必要です。エレメント。私はちょうど3つの方法が欲しい:
Add()
RemoveMinElement()
GetMinElement()
キーは一意である必要があり、同じ要素がいくつかある可能性があるため、並べ替えられたリストは使用できません。
重複の可能性:
c# のフィボナッチ、バイナリ、または二項ヒープ?
.NET にヒープのようなクラスはありますか? 分を取得できるコレクションが必要です。エレメント。私はちょうど3つの方法が欲しい:
Add()
RemoveMinElement()
GetMinElement()
キーは一意である必要があり、同じ要素がいくつかある可能性があるため、並べ替えられたリストは使用できません。
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
プライオリティ キューは、問題にぴったりのように見えます: .Net のプライオリティ キュー
より多くの実装については、Google で「C# プライオリティ キュー」を参照してください。