public void UpdateKeyTest(string[] keys, string oldKey, string newKey) { var keyComparer = StringComparer.Ordinal; var valueComparer = EqualityComparer<int>.Default; var heap = new BinaryHeapWithUpdates<string, int>(keyComparer, valueComparer); var pairs = new List<KeyValuePair<string, int>>(); foreach (var key in keys) { int value = key.GetHashCode(); heap.Insert(key, value); pairs.Add(new KeyValuePair<string, int>(key, value)); } int oldKeyIndex = Array.IndexOf(keys, oldKey); int oldValue = pairs[oldKeyIndex].Value; pairs[oldKeyIndex] = new KeyValuePair<string, int>(newKey, oldValue); heap.UpdateKey(oldValue, newKey); var expected = pairs.OrderBy(p => p.Key, keyComparer).ToArray(); for (int i = 0; i < keys.Length; i++) { var min = heap.ExtractMin(); Assert.Equal(expected[i], min); } }
// O(E*log(N)) public static Dictionary<Node, ulong> Dijkstra(Node from) { var dist = new Dictionary<Node, ulong>(); var heap = new BinaryHeapWithUpdates<ulong, Node>(Comparer<ulong>.Default, EqualityComparer<Node>.Default); dist.Add(from, 0); heap.Insert(0, from); while (!heap.IsEmpty()) { var min = heap.ExtractMin(); foreach (var edge in min.Value.Edges) { ulong newDistance = min.Key + edge.Length; if (!dist.ContainsKey(edge.ToNode)) { dist.Add(edge.ToNode, newDistance); heap.Insert(newDistance, edge.ToNode); } else if (newDistance < dist[edge.ToNode]) { dist[edge.ToNode] = newDistance; heap.UpdateKey(edge.ToNode, newDistance); } } } return dist; }
// O(E*log(N)) public static ulong[] Dijkstra(IList<N> nodes, int fromNode) { var dist = new ulong[nodes.Count]; var heap = new BinaryHeapWithUpdates<ulong, int>(Comparer<ulong>.Default, EqualityComparer<int>.Default); for (int i = 0; i < dist.Length; i++) dist[i] = ulong.MaxValue; dist[fromNode] = 0; heap.Insert(0, fromNode); while (!heap.IsEmpty()) { var min = heap.ExtractMin(); foreach (E edge in nodes[min.Value].Edges) { ulong d = min.Key + edge.Length; if (d < dist[edge.ToNode]) { if (dist[edge.ToNode] == ulong.MaxValue) heap.Insert(d, edge.ToNode); else heap.UpdateKey(edge.ToNode, d); dist[edge.ToNode] = d; } } } return dist; }