I believe that a SortedSet>
with a custom Comparer
will do the job.
The Comparer
will look like the following:
class KeyValueComparer : IComparer> where K:IComparable where V:IComparable
{
public int Compare(KeyValuePair x, KeyValuePair y)
{
var res = x.Key.CompareTo(y.Key);
return res == 0 ? x.Value.CompareTo(y.Value) : res;
}
}
With such Comparer
, the SortedSet
will be sorted by Key and it will allow duplicates of keys.
You can get the Min
at constant time, RemoveMin
at O(logn)
, Add
an entry at O(logn)
and Update
a key at O(logn)
.
Here is a full (or almost) implementation:
public class Heap
where K : IComparable
where V : IComparable
{
private readonly SortedSet> _sortedSet;
// O(1)
public KeyValuePair Min
{
get { return _sortedSet.Min; }
}
public Heap()
{
_sortedSet = new SortedSet>(new KeyValueComparer());
}
// O(logn)
public void Add(K key, V value)
{
_sortedSet.Add(new KeyValuePair(key, value));
}
// O(logn)
public KeyValuePair RemoveMin()
{
var min = Min;
_sortedSet.Remove(min);
return min;
}
// O(logn)
public void Remove(K key, V value)
{
_sortedSet.Remove(new KeyValuePair(key, value));
}
// O(logn)
public void UpdateKey(K oldKey, V oldValue, K newKey)
{
Remove(oldKey, oldValue);
Add(newKey, oldValue);
}
private class KeyValueComparer : IComparer>
where K : IComparable
where V : IComparable
{
public int Compare(KeyValuePair x, KeyValuePair y)
{
var res = x.Key.CompareTo(y.Key);
return res == 0 ? x.Value.CompareTo(y.Value) : res;
}
}
}