26 using System.Collections.Generic;
32 public interface IReadOnlyPriorityQueue<TElement, TPriority>
37 IEnumerable<KeyValuePair<TElement, TPriority>> Items {
get; }
39 bool Contains(TElement element);
44 bool TryGetPriority(TElement element, out TPriority priority);
48 TElement Peek(out TPriority priority);
53 public interface IPriorityQueue<TElement, TPriority>
54 : IReadOnlyPriorityQueue<TElement, TPriority>,
IClearable
57 TPriority
this[TElement element] {
get;
set; }
60 bool Remove(TElement element);
67 public sealed
class PriorityQueue<TElement, TPriority> : IPriorityQueue<TElement, TPriority>
68 where TPriority : IComparable<TPriority>
70 private List<TElement> payloads =
new List<TElement>();
71 private List<TPriority> priorities =
new List<TPriority>();
72 private Dictionary<TElement, int> positions =
new Dictionary<TElement, int>();
83 get {
return payloads.Count; }
86 public IEnumerable<KeyValuePair<TElement, TPriority>> Items
90 for (
int i = 0, n = Count; i < n; i++)
91 yield
return new KeyValuePair<TElement, TPriority>(payloads[i], priorities[i]);
95 public TPriority
this[TElement element]
99 return priorities[positions[element]];
105 if (positions.TryGetValue(element, out pos))
107 TPriority oldPriority = priorities[pos];
108 priorities[pos] = value;
109 int priorityDelta = value.CompareTo(oldPriority);
110 if (priorityDelta < 0) MoveUp(pos);
111 else if (priorityDelta > 0) MoveDown(pos);
115 payloads.Add(element);
116 priorities.Add(value);
118 positions[element] = pos;
124 public bool Contains(TElement element)
126 return positions.ContainsKey(element);
129 public bool TryGetPriority(TElement element, out TPriority priority)
132 if (!positions.TryGetValue(element, out pos))
134 priority =
default(TPriority);
137 priority = priorities[pos];
141 private void RemoveAt(
int pos)
144 TElement oldPayload = payloads[pos];
145 TPriority oldPriority = priorities[pos];
146 positions.Remove(oldPayload);
148 bool empty = (count <= 1);
149 if (!empty && pos != count - 1)
152 payloads[pos] = payloads[count - 1];
153 priorities[pos] = priorities[count - 1];
154 positions[payloads[pos]] = pos;
158 payloads.RemoveAt(count - 1);
159 priorities.RemoveAt(count - 1);
161 if (!empty && pos != count - 1)
163 int priorityDelta = priorities[pos].CompareTo(oldPriority);
164 if (priorityDelta > 0) MoveDown(pos);
165 else if (priorityDelta < 0) MoveUp(pos);
169 public bool Remove(TElement element)
172 bool success = positions.TryGetValue(element, out pos);
173 if (success) RemoveAt(pos);
177 public TElement Peek()
182 public TElement Peek(out TPriority priority)
184 priority = priorities[0];
190 if (Count == 0)
return false;
195 private void MoveUp(
int index)
197 TElement payload = payloads[index];
198 TPriority priority = priorities[index];
204 if (priority.CompareTo(priorities[parent]) >= 0)
break;
206 payloads[i] = payloads[parent];
207 priorities[i] = priorities[parent];
208 positions[payloads[i]] = i;
215 payloads[i] = payload;
216 priorities[i] = priority;
217 positions[payload] = i;
221 private void MoveDown(
int index)
223 TElement payload = payloads[index];
224 TPriority priority = priorities[index];
227 while (2 * i < Count)
232 if (priority.CompareTo(priorities[child]) >= 0) min = child;
235 if (child < Count && priorities[min].CompareTo(priorities[child]) >= 0) min = child;
239 payloads[i] = payloads[min];
240 priorities[i] = priorities[min];
241 positions[payloads[i]] = i;
248 payloads[i] = payload;
249 priorities[i] = priority;
250 positions[payload] = i;