先决条件: 贪婪算法 | (霍夫曼编码)、priority_queue::push() 和 C++ STL 中的 priority_queue::pop() 。
贪婪算法 | (霍夫曼编码):
C#:C# 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-优快云博客
JavaScript:JavaScript 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-优快云博客
python:python 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-优快云博客
java:java 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-优快云博客
c++ STL:c++ STL 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)-优快云博客
c++:c++ 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪算法设计核心代码-优快云博客
c语言:c语言 霍夫曼编码 | 贪婪算法(Huffman Coding | Greedy Algo)_霍夫曼的贪婪c语言-优快云博客
priority_queue::push() 和 C++ STL 中的 priority_queue::pop() :
C++ STL 中的 priority_queue::push() 和 priority_queue::pop()-优快云博客
给定一个字符数组 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[]中每个字符的所有存储的哈夫曼编码。
下面是上述方法的实现:
import queue
# Maximum Height of Huffman Tree.
MAX_SIZE = 100
class HuffmanTreeNode:
def __init__(self, character, frequency):
# Stores character
self.data = character
# Stores frequency of the character
self.freq = frequency
# Left child of the current node
self.left = None
# Right child of the current node
self.right = None
def __lt__(self, other):
return self.freq < other.freq
# Custom comparator class
class Compare:
def __call__(self, a, b):
# Defining priority on the basis of frequency
return a.freq > b.freq
# Function to generate Huffman Encoding Tree
def generateTree(pq):
# We keep on looping till only one node remains in the Priority Queue
while pq.qsize() != 1:
# Node which has least frequency
left = pq.get()
# Node which has least frequency
right = pq.get()
# A new node is formed with frequency left.freq + right.freq
# We take data as '$' because we are only concerned with the frequency
node = HuffmanTreeNode('$', left.freq + right.freq)
node.left = left
node.right = right
# Push back node created to the Priority Queue
pq.put(node)
return pq.get()
# Function to print the huffman code for each character.
# It uses arr to store the codes
def 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 not root.left and not root.right:
print(root.data, end=' ')
for i in range(top):
print(arr[i], end='')
print()
def HuffmanCodes(data, freq, size):
# Declaring priority queue using custom comparator
pq = queue.PriorityQueue()
# Populating the priority queue
for i in range(size):
newNode = HuffmanTreeNode(data[i], freq[i])
pq.put(newNode)
# Generate Huffman Encoding Tree and get the root node
root = generateTree(pq)
# Print Huffman Codes
arr = [0] * MAX_SIZE
top = 0
printCodes(root, arr, top)
# Driver Code
if __name__ == '__main__':
data = ['a', 'b', 'c', 'd', 'e', 'f']
freq = [5, 9, 12, 13, 16, 45]
size = len(data)
HuffmanCodes(data, freq, size)
输出:
f 0
c 100
d 101
a 1100
b 1101
e 111
时间复杂度: O(n*logn),其中 n 是唯一字符的数量
辅助空间: O(n)