先决条件: 贪婪算法 | (霍夫曼编码)、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[]中每个字符的所有存储的哈夫曼编码。
下面是上述方法的实现:
// javascript Program for Huffman Coding
// using Priority Queue
class HuffmanTreeNode {
// Initializing the
// current node
constructor(character, frequency) {
// Stores character
this.data = character;
// Stores frequency of
// the character
this.freq = frequency;
// Left child of the
// current node
this.left = null;
// Right child of the
// current node
this.right = null;
}
}
// Custom comparator class
class Compare {
constructor() {}
static compare(a, b) {
// Defining priority on
// the basis of frequency
return a.freq - b.freq;
}
}
// Function to generate Huffman
// Encoding Tree
function generateTree(pq) {
// We keep on looping till
// only one node remains in
// the Priority Queue
while (pq.length > 1) {
// Node which has least
// frequency
const left = pq.shift();
// Remove node from
// Priority Queue
const right = pq.shift();
// A new node is formed
// with frequency left->freq
// + right->freq
// We take data as '$'
// because we are only
// concerned with the
// frequency
const node = new HuffmanTreeNode('$', left.freq + right.freq);
node.left = left;
node.right = right;
// Push back node
// created to the
// Priority Queue
pq.push(node);
pq.sort(Compare.compare);
}
return pq[0];
}
// Function to print the
// huffman code for each
// character.
// It uses arr to store the codes
function printCodes(root, arr, top) {
// Assign 0 to the left node
// and recur
if (root.left) {
arr[top] = 0;
printCodes(root.left, arr, top + 1);
}
// Assign 1 to the right
// node and recur
if (root.right) {
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 && !root.right) {
console.log(root.data + ' ' + arr.slice(0, top).join(''));
}
}
function HuffmanCodes(data, freq, size) {
// Maximum Height of Huffman Tree.
const MAX_SIZE = 100;
// Declaring priority queue
// using custom comparator
const pq = [];
// Populating the priority
// queue
for (let i = 0; i < size; i++) {
const newNode = new HuffmanTreeNode(data[i], freq[i]);
pq.push(newNode);
}
pq.sort(Compare.compare);
// Generate Huffman Encoding
// Tree and get the root node
const root = generateTree(pq);
const arr = new Array(MAX_SIZE);
const top = 0;
// Print Huffman Codes
printCodes(root, arr, top);
}
// Driver Code
const data = ['a', 'b', 'c', 'd', 'e', 'f'];
const freq = [5, 9, 12, 13, 16, 45];
const size = data.length;
HuffmanCodes(data, freq, size);
// This code is contributed by shiv1o43g
输出:
f 0
c 100
d 101
a 1100
b 1101
e 111
时间复杂度: O(n*logn),其中 n 是唯一字符的数量
辅助空间: O(n)