using System.Linq; using System; namespace BF { /// /// 最小二叉堆 /// public class BFBinaryHeap where T : IComparable { T[] items; public int Count { get; private set; } public BFBinaryHeap() : this(50) { } public BFBinaryHeap(int size) { if (size < 0) throw new IndexOutOfRangeException(); items = new T[size]; } public void Enqueue(T value) { if (Count == items.Length) Resize(Count * 2); items[Count] = value; ++Count; UpAdjust(Count - 1); } public T Dequeue() { if (Count == 0) throw new InvalidOperationException(); var result = items[0]; --Count; if (Count > 0) { items[0] = items[Count]; items[Count] = default; DownAdjust(); } return result; } public T RemoveAtEnd() { if (Count == 0) throw new InvalidOperationException(); var result = items[Count - 1]; items[Count - 1] = default; --Count; return result; } void Resize(int newSize) { var temp = new T[newSize]; Array.Copy(items, 0, temp, 0, Count); items = temp; } /// /// 下沉调整 用于删除堆顶 /// void DownAdjust() { int parent = 0; int left = (parent * 2) + 1; // left index while (left < Count) { int right = left + 1; // right index (parent + 1) * 2 var t1 = items[right]; var t2 = items[left]; int min = (right < Count && t1.CompareTo(t2) < 0) ? right : left; t1 = items[min]; t2 = items[parent]; if (t1.CompareTo(t2) < 0) { items[parent] = t1; items[min] = t2; parent = min; left = (parent * 2) + 1; } else { break; } } } /// /// 上浮调整 用于插入 /// void UpAdjust(int index) { while (index > 0) { int parent = (index - 1) / 2; // parent index var t1 = items[index]; var t2 = items[parent]; if (t1.CompareTo(t2) < 0) { items[index] = t2; items[parent] = t1; } else { break; } index = parent; } } /// /// 如果t的value变小了 尝试上浮调整 /// public void TryUpAdjust(T t) { int index = GetIndex(t); UpAdjust(index); } int GetIndex(T value) { int Count = items.Length; for (int i = 0; i < Count; i++) { if (ReferenceEquals(items[i], value)) return i; } return -1; } } }