前言
C#居然没有堆的数据结构,那就只能自己实现了。
实现参考:《挑战程序设计竞赛》
1 代码
mCompareFunc判断a小于b时为小跟堆,否则为大根堆。
public class Heap<T>
{
List<T> mHeapList = new List<T>();
Func<T, T, bool> mCompareFunc;
public int Size => mHeapList.Count;
public Heap(Func<T, T, bool> compareFunc)
{
mCompareFunc = compareFunc;
}
public void Push(T value)
{
int index = mHeapList.Count;
mHeapList.Add(value);
while (index > 0)
{
int parent = (index - 1) / 2;
if (mCompareFunc(mHeapList[parent], value)) break;
mHeapList[index] = mHeapList[parent];
index = parent;
}
mHeapList[index] = value;
}
public T Pop()
{
if (Empty())
{
throw new ArgumentOutOfRangeException("堆为空!");
}
T ret = mHeapList[0];
int size = mHeapList.Count - 1;
T x = mHeapList[size];
int index = 0;
while(index * 2 + 1 < size)
{
int leftChildIndex = index * 2 + 1;
int rightChildIndex = index * 2 + 2;
if (leftChildIndex < size && mCompareFunc(mHeapList[rightChildIndex], mHeapList[leftChildIndex]))
leftChildIndex = rightChildIndex;
// 已经没有大小颠倒则退出
if (!mCompareFunc(mHeapList[leftChildIndex], x)) break;
mHeapList[index] = mHeapList[leftChildIndex];
index = leftChildIndex;
}
mHeapList[index] = x;
mHeapList.RemoveAt(mHeapList.Count - 1);
return ret;
}
public T Top()
{
return mHeapList[0];
}
public bool Empty()
{
return mHeapList.Count == 0;
}
}
总结
如果要使用优先队列,那么其中一种实现就是把堆封装一下就可以了。