最近看了《算法》第四版这本书,里边关于优先队列讲的确实非常好,之前自己写过的最小堆代码过于臃肿了,这次重构一下,记录发上来
public class Heap<T> where T : IComparable<T>
{
readonly List<T> m_heap;
public int Count => m_heap.Count - 1;
public Heap()
{
m_heap = new List<T>{ default };
}
private void Swim(int pos)
{
while (pos > 1 && m_heap[pos].CompareTo(m_heap[pos >> 1]) < 0)
{
Swap(m_heap, pos, pos >> 1);
pos >>= 1;
}
}
private void Sink(int pos)
{
while (pos << 1 <= m_heap.Count - 1)
{
int j = pos << 1;
if (j < m_heap.Count - 1 && m_heap[j].CompareTo(m_heap[j + 1]) > 0) j++;
if (m_heap[pos].CompareTo(m_heap[j]) <= 0) break;
Swap(m_heap, pos, j);
pos = j;
}
}
public void Insert(T value)
{
m_heap.Add(value);
Swim(m_heap.Count - 1);
}
public T Remove()
{
T res = m_heap[1];
Swap(m_heap, 1, m_heap.Count - 1);
m_heap.RemoveAt(m_heap.Count - 1);
Sink(1);
return res;
}
public T Peek()
{
return m_heap[1];
}
private static void Swap(List<T> list, int a, int b)
{
T temp = list[a];
list[a] = list[b];
list[b] = temp;
}
}
主要就是Swim和Sink,提取了Swap函数以后,代码会大幅度简洁并简短。
这个后序有缘还会再优化,内存管理这块还不是特别清晰明了
之前第一版的序号计算有些问题,重新上传一版