First, you need an interface to get the keys and to get and set the values, as follows:
namespace Skyiv.Util
{
interface IKeyValue<T, K, V>
{
K GetKey(T x);
V GetValue(T x);
void SetValue(T x, V v);
}
}
Next, is our priority queue with the key value Keyedpriorityqueue<t, K, v> debut:
Using System;
Using System.Collections.Generic;
Namespace Skyiv.util
{
Class Keyedpriorityqueue<t, K, v>
{
Icomparer<t> comparer;
Ikeyvalue<t, K, v> kver;
Dictionary<k, int> keys;
BOOL Haskey;
T[] Heap;
public int Count {get; private set;}
Public Keyedpriorityqueue (Ikeyvalue<t, K, v> kv): This (null, KV) {}
public keyedpriorityqueue (int capacity, ikeyvalue<t, K, v> kv): This (capacity, NULL, KV) {}
Public Keyedpriorityqueue (icomparer<t> comparer, ikeyvalue<t, K, v> kv): This (comparer, KV) {}
public keyedpriorityqueue (int capacity, icomparer<t> comparer, ikeyvalue<t, K, v> kver)
{
This.keys = new dictionary<k, int> ();
This.comparer = (comparer = null)? Comparer<t>. Default:comparer;
This.kver = Kver;
This.haskey = (kver!= null);
This.heap = new T[capacity];
}
public bool ContainsKey (K key)
{
return keys. ContainsKey (key);
}
public void Update (T v)
{
if (!haskey) throw new NotSupportedException ();
if (typeof (T). Isvaluetype) throw new InvalidOperationException ("T cannot be a value type");
if (! ContainsKey (Kver. Getkey (v)) throw new ArgumentOutOfRangeException ("V", V, "No this health value when updating precedence queues");
var id = keys[kver. Getkey (v)];
var cmp = Comparer.compare (V, Heap[id]);
Kver. SetValue (Heap[id], kver. GetValue (v)); Note: This sentence requires T to be a reference type, not a value type
if (CMP < 0) Siftdown (ID);
else if (cmp > 0) siftup (ID);
}
public void Push (T v)
{
if (Count >= heap. Length) array.resize (ref heap, Count * 2);
if (Haskey) keys[kver. Getkey (v)] = Count;
Heap[count] = v;
Siftup (count++);
}
Public T Pop ()
{
var v = top ();
if (Haskey) keys. Remove (Kver. Getkey (v));
Heap[0] = Heap[--count];
if (Count > 0) siftdown (haskey?) (Keys[kver. Getkey (heap[0])] = 0): 0);
return v;
}
Public T Top ()
{
if (Count > 0) return heap[0];
throw new InvalidOperationException ("Priority queue is empty");
}
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[haskey? (Keys[kver. Getkey (heap[n2])] = N): n] = heap[n2];
Heap[haskey? (Keys[kver. Getkey (v)] = N): 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[haskey? (Keys[kver. Getkey (heap[n2])] = N): n] = heap[n2];
}
Heap[haskey? (Keys[kver. Getkey (v)] = N): n] = v;
}
}
}