2 回答
TA贡献1831条经验 获得超9个赞
我已经使用最小堆实现了霍夫曼编码。你可能会从中得到一些想法。
internal class HuffmanTree
{
internal HuffmanTreeNode rootNode;
private Dictionary<char, int> dictFrequencies;
HuffmanPriorityQueue huffmanPriorityQueue;
internal void Build(string input)
{
dictFrequencies = input.GroupBy(x => x).ToDictionary(k => k.Key, v => v.Count());
huffmanPriorityQueue = new HuffmanPriorityQueue(dictFrequencies.Count);
foreach (var item in dictFrequencies)
{
huffmanPriorityQueue.Push(new HuffmanTreeNode { Symbol = item.Key, Frequency = item.Value, Left = null, Right = null });
}
while(huffmanPriorityQueue.Count() >= 2)
{
HuffmanTreeNode leftNode = huffmanPriorityQueue.Pop();
HuffmanTreeNode rightNode = huffmanPriorityQueue.Pop();
HuffmanTreeNode parentNode = new HuffmanTreeNode
{
Frequency = leftNode.Frequency + rightNode.Frequency,
Symbol = '*',
Left = leftNode,
Right = rightNode
};
this.rootNode = parentNode;
huffmanPriorityQueue.Push(parentNode);
}
}
internal class HuffmanPriorityQueue
{
HuffmanTreeNode[] items;
int top = 0;
public HuffmanPriorityQueue(int size)
{
items = new HuffmanTreeNode[size + 1];
}
internal void Push(HuffmanTreeNode node)
{
int i = ++top;
while (i > 1 && items[i / 2].Frequency > node.Frequency)
{
items[i] = items[i / 2];
i = i / 2;
}
items[i] = node;
}
internal HuffmanTreeNode Pop()
{
HuffmanTreeNode data = items[1];
items[1] = items[top];
items[top--] = null;
int i = 1;
int j = i * 2;
while (j <= top)
{
if ((j + 1) <= top && items[j + 1].Frequency < items[j].Frequency)
{
j += 1;
}
if (items[j].Frequency < items[i].Frequency)
{
HuffmanTreeNode temp = items[j];
items[j] = items[i];
items[i] = temp;
i = j;
j = i * 2;
}
else
break;
}
return data;
}
internal int Count()
{
return top;
}
}
internal class HuffmanTreeNode
{
internal char Symbol { get; set; }
internal int Frequency { get; set; }
internal HuffmanTreeNode Right { get; set; }
internal HuffmanTreeNode Left { get; set; }
}
添加回答
举报