先决条件: 贪婪算法 | (霍夫曼编码)、priority_queue::push() 和 C++ STL 中的 priority_queue::pop() 。
贪婪算法 | (霍夫曼编码):
C#:C# 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客
JavaScript:JavaScript 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客
python:python 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客
java:java 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客
c++ STL:c++ STL 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-CSDN博客
c++:c++ 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪算法设计核心代码-CSDN博客
c语言:c语言 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪c语言-CSDN博客
priority_queue::push() 和 C++ STL 中的 priority_queue::pop() :
C++ STL 中的 priority_queue::push() 和 priority_queue::pop()-CSDN博客
给定一个字符数组 ch[]和每个字符的频率作为freq[] 。任务是使用优先级队列为ch[]中的每个字符找到霍夫曼编码。
例子
输入: ch[] = { 'a', 'b', 'c', 'd', 'e', 'f' }, freq[] = { 5, 9, 12, 13, 16, 45 }
输出:
f 0
c 100
d 101
a 1100
b 1101
e 111
方法:
1、将ch[]中所有映射到相应频率freq[]的字符推入优先级队列。
2、要创建哈夫曼树,请从优先级队列中弹出两个节点。
3、将从优先级队列中弹出的两个节点指定为新节点的左子节点和右子节点。
4、将新形成的节点推送到优先级队列中。
5、重复以上所有步骤,直到优先级队列的大小变为 1。
6、遍历哈夫曼树(其根是优先级队列中剩下的唯一节点)以存储哈夫曼代码
7、打印ch[]中每个字符的所有存储的哈夫曼编码。
下面是上述方法的实现:
using System;
using System.Collections.Generic;
public class HuffmanTreeNode
: IComparable<HuffmanTreeNode> {
public char Data
{
get;
set;
}
public int Freq
{
get;
set;
}
public HuffmanTreeNode Left
{
get;
set;
}
public HuffmanTreeNode Right
{
get;
set;
}
public HuffmanTreeNode(char character, int frequency)
{
Data = character;
Freq = frequency;
Left = Right = null;
}
public int CompareTo(HuffmanTreeNode other)
{
return Freq - other.Freq;
}
}
public class GFG {
// Maximum Height of Huffman Tree.
private const int MaxSize = 100;
// Function to print the huffman code for each
// character. It uses arr to store the codes
private static void PrintCodes(HuffmanTreeNode root,
int[] arr, int top)
{
// Assign 0 to the left node and recur
if (root.Left != null) {
arr[top] = 0;
PrintCodes(root.Left, arr, top + 1);
}
// Assign 1 to the right node and recur
if (root.Right != null) {
arr[top] = 1;
PrintCodes(root.Right, arr, top + 1);
}
// If this is a leaf node, then we print root.Data
// We also print the code for this character from
// arr
if (root.Left == null && root.Right == null) {
Console.Write(root.Data + " ");
for (int i = 0; i < top; ++i) {
Console.Write(arr[i]);
}
Console.WriteLine();
}
}
// Function to generate Huffman Encoding Tree
private static HuffmanTreeNode
GenerateTree(SortedList<int, HuffmanTreeNode> list)
{
// We keep on looping till only one node remains in
// the SortedList
while (list.Count != 1) {
// Node which has least frequency
HuffmanTreeNode left = list.Values[0];
list.RemoveAt(0);
// Node which has least frequency
HuffmanTreeNode right = list.Values[0];
list.RemoveAt(0);
// A new node is formed with frequency left.Freq
// + right.Freq We take data as '$' because we
// are only concerned with the frequency
HuffmanTreeNode node = new HuffmanTreeNode(
'$', left.Freq + right.Freq);
node.Left = left;
node.Right = right;
// Add the new node back to the SortedList
list.Add(node.Freq, node);
}
return list.Values[0];
}
// Function to generate Huffman Codes
public static void HuffmanCodes(char[] data, int[] freq,
int size)
{
// Declaring SortedList using custom comparer
SortedList<int, HuffmanTreeNode> list
= new SortedList<int, HuffmanTreeNode>();
// Populating the SortedList
for (int i = 0; i < size; i++) {
HuffmanTreeNode newNode
= new HuffmanTreeNode(data[i], freq[i]);
list.Add(freq[i], newNode);
}
// Generate Huffman Encoding Tree and get the root
// node
HuffmanTreeNode root = GenerateTree(list);
// Print Huffman Codes
int[] arr = new int[MaxSize];
int top = 0;
PrintCodes(root, arr, top);
}
// Driver Code
public static void Main(string[] args)
{
char[] data = { 'a', 'b', 'c', 'd', 'e', 'f' };
int[] freq = { 5, 9, 12, 13, 16, 45 };
int size = data.Length;
// Function call
HuffmanCodes(data, freq, size);
}
}
输出:
f 0
c 100
d 101
a 1100
b 1101
e 111
时间复杂度: O(n*logn),其中 n 是唯一字符的数量
辅助空间: O(n)