日期:2014-05-18 浏览次数:20980 次
public sealed class PriorityQueue<T> where T : IComparable<T> { private T[] heap; public int Count { get; private set; } public PriorityQueue(int capacity) { if (capacity <= 0) { throw new InvalidOperationException("优先队列的初始容量必须大于0"); } heap = new T[capacity]; } public PriorityQueue() : this(32) { } public PriorityQueue(T[] array) { Count = array.Length; heap = array; BuildMaxHeap(heap); } /// <summary> /// 获取优先级最高的元素 /// </summary> /// <returns></returns> public T Top() { ThrowExceptionIfPriorityQueueIsNull(); return heap[0]; } /// <summary> /// 删除并返回优先级最高的元素 /// </summary> /// <returns></returns> public T ExtractTop() { ThrowExceptionIfPriorityQueueIsNull(); T top = heap[0]; heap[0] = heap[this.Count - 1]; heap[this.Count - 1] = default(T); this.Count--; //保持堆的性质 HeapifyDown(0); return top; } private void ThrowExceptionIfPriorityQueueIsNull() { if (Count <= 0) throw new InvalidOperationException("优先队列为空"); } /// <summary> /// 增加索引位置元素的优先级 /// </summary> /// <param name="index">当前元素的索引</param> /// <param name="newValue">新的优先级元素</param> public void IncreasePriority(int index, T newValue) { if (index < 0 || index >= Count) { throw new IndexOutOfRangeException("当前索引超出队列范围"); } if (newValue.CompareTo(heap[index]) < 0) { throw new InvalidOperationException("新值必须大于当前值"); } heap[index] = newValue; HeapifyUp(index); } /// <summary> /// 从指定位置向下调整堆,保证堆的性质 /// </summary> /// <param name="current"></param> private void HeapifyDown(int current) { //当前元素的左子元素的索引 int left = (current + 1) * 2 - 1; //当前元素的右子元素的索引 int right = left + 1; int largest; if (left < Count && heap[left].CompareTo(heap[current]) > 0) { largest = left; } else { largest = current; } if (right < Count && heap[right].CompareTo(heap[largest]) > 0) { largest = right; } //如果单前值得优先级不为最高,则继续向下调整 if (largest != current) { Swap(ref heap[current], ref heap[largest]); HeapifyDown(largest); } } /// <summary> /// 给优先队列添加新的元素 /// </summary> /// <param name="key"></param> public void Insert(T key) { if (Count == heap.Length) { EnsureCapacity(Count); } heap[Count++] = key; HeapifyUp(Count - 1); } /// <summary> /// 将数组调整为最大堆 /// </summary> /// <param name="array"></param> private void BuildMaxHeap(T[] array) {