【Java】哈夫曼编码

哈夫曼编码

目录

  1. 了解哈夫曼树及哈夫曼编码
  2. 代码实现哈夫曼编码
  3. 总结

前言:对于正在学习数据结构的小伙伴们,大家是不是想了解哈夫曼树和哈夫曼编码呢?现在让我们一起来探索哈夫曼编码。( •̀ ω •́ )✧( •̀ ω •́ )✧

1. 了解哈夫曼树及哈夫曼编码
哈夫曼树
给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
权值:在数学领域,权值指加权平均数中的每一个数的频数,也称为权值或权重。
路径长度:从数中的一个节点到另一个节点的分支构成两个点之间的路径,路径上的分支数目称作路径长度。
带权路径长度:节点的带权路径长度就是从该节点到树根之间的路径长度乘以该节点的权。

哈夫曼编码(Huffman Coding)
哈夫曼编码又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。该编码是Huffman于1952年提出的一种编码方法,该方法是完全依据字符出现的概率来构造出平均长度最短的码字,有时称为最佳编码,一般叫做Huffman编码。
哈夫曼编码的作用
压缩文件是哈夫曼编码的主要作用,就如我们向好友传输一个文件的压缩包,就可以用哈夫曼编码来压缩,只要好友再用同样的方式来解码就看到你发送文件的内容啦,如果你用其他的软件打开或者没有压缩,看到的可能是一堆乱码。
编码的原理
其实这个并不复杂,首先,你需要知道哈夫曼编码处理的是字符和字符对应的二进制配对问题,目的是压缩字符对应的二进制数据的长度。

其次,了解过数据传输的同学都知道,我们在网络上传输和存储的数据都是以字节的形式,其本质也就是一个个的二进制数,因为计算机最小单位只能区分0和1。所以可以说,我们计算机屏幕上看到或者用到的本质都是一个个二进制数构成的,所以这些二进制数和我们所有的数据构成一一映射的关系,我们用这些映射关系来表示数据。

最后,可想而知,对于一个英文字母b为例,ASCII编码,十进制为98,二进制为01100010。可以看出每一个字符都是由8个bit构成的,至于为什么,大家可以自己去了解一下。那么数据压缩是如何实现的呢?
相信聪明的你已经知道了
没错,如果我们把每一个字符对应的二进制编码缩短,而且使出现频率最高的字符的编码是最短的,这样就可以大大地减小了存储的空间。

举例
假设我们要传输"a",“b”,“c”,"d"这四个字符,先假设它们的权值都为2,3,4,8如果按照ASCII编码的方式,如下

字符 权重 ASCII编码
a 2 01100001
b 3 01100010
c 4 01100011
d 8 01100100

可知:用ASCII编码需要花费(2+3+4+8)x8=17x8=136(bit)。而用哈夫曼的不定长的编码,以左节点为0,右节点为1。
在这里插入图片描述
可以产生一个编码表

字符 权重 哈夫曼编码
a 2 000
b 3 001
c 4 01
d 8 1

可以计算得:
用哈夫曼编码花费的bit值为2x3+3x3+4x2+8x1=31(bit),可知哈夫曼编码可以大大地压缩数据的传输和存储的空间。

2. 代码实现哈夫曼编码
下面以打印"industriousness"这个单词为例

/**
* 哈夫曼树
* @author 梦想少年
* 创建哈夫曼树并输出其每个叶结点的编码
*/
public class HFMTree {
   
//主方法
public static void main(String[] args){
   
 HFMTree  hfmTree=new HFMTree();
 //创建一个字符串和对应权值的数组,如:i
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值