[算法]Huffman Coding/霍夫曼编码

哈夫曼编码是一种基于字符出现频率的可变长度编码,用于节省存储空间。它要求编码无前缀冲突,频繁的字符拥有较短的编码。通过构建优化的二叉树,可以得出各个字符的编码,例如a:0,b:101,c:100,等。这种方法尤其适用于数据压缩。
摘要由CSDN通过智能技术生成

前言

假设需要在计算机中保存一段由a,b,c,d,e,f组成的长字符串,最直接的编码方式为将a,b,c…一次编码为000,001,010,011,100,101,即每个字符的编码长度都相等为3。那么则需要保存 3 ∗ 1 0 6 3*10^6 3106位0或1。这样的编码方式被称为固定长度编码。那么是否存在更加节省空间的编码方式?

Huffman Coding

可变长度编码

如果我们可以提前统计这段长字符串中各个字符出现的次数,那么比较直接的想法是:为出现次数较多的字符对应更短的编码长度,而对出现次数少的字符使用较长的编码就可以有效地缩短总的编码长度。这种编码方式被称为可变长度编码

  • 注:可变长度编码必须满足一个条件’前缀编码’,即没有一个编码是其他编码的前缀(防止出现歧义)。
Huffman Coding

那么如何获得每个字符的编码呢?

  1. 将a,b,c,d,e,f 按照出现次数从小到大排列在队列中(单位:千次)
    在这里插入图片描述
  2. 将队列中第一位取出作为一个二叉树的左子节点,第二位作为右子节点,将左右子节点的频数相加作为根子节点的频数
    在这里插入图片描述
  3. 将Z重新放回队列中(仍保持频次从小到大),再取出最小的两位取出作为新节点的左右子节点,相加后作为根节点的频次,再次插入队列
    在这里插入图片描述
  4. 重复循环获得完整的二叉树
    在这里插入图片描述
  5. 以二叉树路径,按照左0右1的规则获得不同字符的编码。以上方的二叉树为例,获得的编码为:
  • a:0
  • b:101
  • c:100
  • d:111
  • e:1101
  • f:1100

结语

哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码(实际上也是所需存储空间最少的编码方式),一般就叫做Huffman编码(有时也称为霍夫曼编码)。

参考视频:

https://www.bilibili.com/video/BV18V411v7px/?spm_id_from=333.337.search-card.all.click&vd_source=061f796607009d1b58b8851972722015

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答。 首先,贪心算法是一种求解最优化问题的算法,其思想是在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优或者最优近似解的算法。贪心算法的核心是贪心选择性质和最优子结构性质。 其次,霍夫曼编码是一种无损数据压缩算法,它将出现频率较高的字符用较短的编码表示,而用较长的编码表示出现频率较低的字符,从而实现数据压缩的目的。霍夫曼编码的核心是构建霍夫曼树,使用贪心算法构建霍夫曼树。 下面是一个用Python实现霍夫曼编码的示例代码,供您参考: ```python import heapq from collections import defaultdict class HuffmanCoding: def __init__(self, text): self.text = text self.freq = defaultdict(int) self.heap = [] self.codes = {} self.reverse_codes = {} def create_frequency_dict(self): for char in self.text: self.freq[char] += 1 def create_heap(self): for key in self.freq: heapq.heappush(self.heap, (self.freq[key], key)) def merge_nodes(self): while len(self.heap) > 1: freq1, char1 = heapq.heappop(self.heap) freq2, char2 = heapq.heappop(self.heap) merged_freq = freq1 + freq2 merged_char = char1 + char2 heapq.heappush(self.heap, (merged_freq, merged_char)) def create_codes(self): root = self.heap[0][1] self._create_codes_helper(root, "") def _create_codes_helper(self, root, current_code): if len(root) == 1: self.codes[root] = current_code self.reverse_codes[current_code] = root return self._create_codes_helper(root[0], current_code + "0") self._create_codes_helper(root[1], current_code + "1") def encode(self): encoded_text = "" for char in self.text: encoded_text += self.codes[char] return encoded_text def decode(self, encoded_text): current_code = "" decoded_text = "" for bit in encoded_text: current_code += bit if current_code in self.reverse_codes: char = self.reverse_codes[current_code] decoded_text += char current_code = "" return decoded_text if __name__ == '__main__': text = "hello world" huffman = HuffmanCoding(text) huffman.create_frequency_dict() huffman.create_heap() huffman.merge_nodes() huffman.create_codes() encoded_text = huffman.encode() decoded_text = huffman.decode(encoded_text) print("Original text: ", text) print("Encoded text: ", encoded_text) print("Decoded text: ", decoded_text) ``` 希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值