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 不能是值类型"); if (!ContainsKey(kver.GetKey(v))) throw new ArgumentOutOfRangeException("v", v, "更新优先队列时无此健值"); var id = keys[kver.GetKey(v)]; var cmp = comparer.Compare(v, heap[id]); kver.SetValue(heap[id], kver.GetValue(v)); // 注意: 这一句要求 T 是引用类型,不能是值类型 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("优先队列为空"); }
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; } } }