霍夫曼编码(huffman coding) (java实现)

article/2025/9/24 16:54:44

文章目录

  • 一、浅谈赫夫曼编码
  • 二、获取赫夫曼编码
    • 1.获取字符出现的次数
    • 2.创建赫夫曼树
    • 3.指定编码
  • 三、代码实现
    • 1.指定编码代码
    • 2.完整代码
  • 总结


提示:以下是本篇文章正文内容,下面案例可供参考

一、浅谈赫夫曼编码

  赫夫曼编码(Huffman Coding),又称霍夫曼编码(哈夫曼编码),是一种编码方式,赫夫曼编码是可变字长编码(VLC)的一种。
  赫夫曼编码满足前缀编码,即某个字符的编码都不能是其他字符编码的前缀编码,因此不会造成匹配的多义性。

二、获取赫夫曼编码

赫夫曼编码一般用于通信领域中当作信息的一种处理方式 ,处理的规则如下
我们将不同的字符当成不同的节点,每个字符出现的次数作为该节点的权值,将所有节点构造成一个赫夫曼树 我的上一篇博客有提到赫夫曼树的创建(还请各位大佬斧正)link
形成赫夫曼树后,我们将二叉树的左路指定为0右路指定为1,沿赫夫曼树根节点到每个节点的路径保存相应的编码。

下面我们以字符串“hungryandhumble”为例

1.获取字符出现的次数

通过分析 各个字符出现的次数统计如下表1

      表1 各个字符出现的次数
在这里插入图片描述

2.创建赫夫曼树

注意: 赫夫曼树根据排列的方法不同,也可能不太一样,这样对应的赫夫曼编码也不完全一样,但是赫夫曼树的带权路径长度WPL都是一样的,均为最小值。

例如 在上面的例子中,有多个字符出现的次数一样,当我们在森林中取出两棵树形成新树的过程中,由于有多个字符权值相同, 比如我们既可能取出字符r和字符y,也有可能取出字符a和字符b。同时,我们每次在森林中取出的两棵树摆放的位置也会影响赫夫曼树的生成,比如我们既可以将取出的字符r放在左边,将字符y放在右边,也可以反过来。

赫夫曼树(哈夫曼树)的创建(java实现)
视频演示赫夫曼树的生成过程

按照上述规则,创建的赫夫曼树如下

在这里插入图片描述

3.指定编码

我们将二叉树的左路指定为0,右路指定为1
效果图如下
在这里插入图片描述
沿赫夫曼树根节点到每个节点的路径保存相应的编码。
效果图如下
在这里插入图片描述

三、代码实现

1.指定编码代码

//获取赫夫曼编码 向左边路径为0  右边为1//思路//1.每个节点的赫夫曼编码保存到huffmanCodes中//2.生成赫夫曼编码的时候用到StringBuilder拼接路径static Map<Byte, String> huffmanCodes = new HashMap<>();static StringBuilder stringBuilder = new StringBuilder();/*** @param node 节点* @param code 代码编码的值 0 / 1* @param stringBuilder 用于拼接编码*/public static void getCodes(Node02 node, String code, StringBuilder stringBuilder) {StringBuilder temp = new StringBuilder(stringBuilder); //保存上次拼接的值temp.append(code); //拼接if (node != null) {if (node.getData() == null) { //node为非叶子节点getCodes(node.getLeft(), "0", temp); //向左递归遍历getCodes(node.getRight(), "1", temp); //向右递归遍历} else { //说明bide是叶子节点huffmanCodes.put(node.getData(), temp.toString()); //将相应的赫夫曼编码保存到Map中}}}

2.完整代码

package com.xx.huffmantree;import java.util.*;/*** @author 谢鑫* @version 1.0* @date 2021/12/10 10:41*/
public class HuffmanCode {public static void main(String[] args) {String str = "hungryandhumble";List<Node02> nodes = getNodes(str);System.out.println(nodes);Node02 root = createHuffmanTree(nodes);preOrder(root);//测试生成的赫夫曼编码getCodes(root, "", stringBuilder);System.out.println(huffmanCodes);}public static List<Node02> getNodes(String aString) {List<Node02> nodes = new ArrayList<>(); //用于存放节点byte[] contents = aString.getBytes();Map<Byte, Integer> map = new HashMap<>(); //Byte对象存放字符 Iterator对象存放字符出现的次数(权值)Integer count = null; //记录每个字符的权值for (byte element : contents) {count = map.get(element);if (count == null) { //如果map中不包含此元素map.put(element, 1); //则添加进map 并将权值设为1} else { //否则权值加1map.put(element, ++count);}}//将map中的数据新建节点添加到list中返回Set keySet = map.keySet(); //获取map的全部key值for (Object key_ : keySet) {Byte key = (Byte) key_;nodes.add(new Node02(key, map.get(key)));}return nodes;}//创建哈夫曼树public static Node02 createHuffmanTree(List<Node02> nodes) {while (nodes.size() > 1) {Collections.sort(nodes); //每次取节点前进行从小打到排序Node02 left = nodes.remove(0); //访问并移除第一元素Node02 right = nodes.remove(0); //访问并移除新的第一个元素Node02 parent = new Node02(null, left.getWeight() + right.getWeight());//创建小树parent.setLeft(left);parent.setRight(right);//将parent放入到nodes中nodes.add(parent);}return nodes.get(0); //最后nodes中的节点即为创建好的哈夫曼树}//获取赫夫曼编码 向左边路径为0  右边为1//思路//1.每个节点的赫夫曼编码保存到huffmanCodes中//2.生成赫夫曼编码的时候用到StringBuilder拼接路径static Map<Byte, String> huffmanCodes = new HashMap<>();static StringBuilder stringBuilder = new StringBuilder();/*** @param node 节点* @param code 代码编码的值 0 / 1* @param stringBuilder 用于拼接编码*/public static void getCodes(Node02 node, String code, StringBuilder stringBuilder) {StringBuilder temp = new StringBuilder(stringBuilder); //保存上次拼接的值temp.append(code); //拼接if (node != null) {if (node.getData() == null) { //node为非叶子节点getCodes(node.getLeft(), "0", temp); //向左递归遍历getCodes(node.getRight(), "1", temp); //向右递归遍历} else { //说明bide是叶子节点huffmanCodes.put(node.getData(), temp.toString()); //将相应的赫夫曼编码保存到Map中}}}//前序遍历public static void preOrder(Node02 root) {if (root != null) {root.preOrder();} else {System.out.println("树空,无法完成前序遍历!");}}}class Node02 implements Comparable<Node02> {private Byte data; //存放字符本身private int weight; //存放权值Node02 left;Node02 right;public Node02(Byte data, int weight) {this.data = data;this.weight = weight;}public Byte getData() {return data;}public void setData(Byte data) {this.data = data;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public Node02 getLeft() {return left;}public void setLeft(Node02 left) {this.left = left;}public Node02 getRight() {return right;}public void setRight(Node02 right) {this.right = right;}//前序遍历public void preOrder() {System.out.println(this);if (this.getLeft() != null) {this.getLeft().preOrder();}if (this.getRight() != null) {this.getRight().preOrder();}}@Overridepublic String toString() {return "Node02{" +"data=" + data +", weight=" + weight +'}';}@Overridepublic int compareTo(Node02 o) { //从小到大排序return this.getWeight() - o.getWeight();}
}

输出结果为
在这里插入图片描述

总结

hungryandhumble相应字符对应的十进制与二进制如下表

在这里插入图片描述
若按二进制压缩 hungryandhumble的压缩代码为
011010000111010101101110011001110111001001111001011000010110111001100100011010000111010101101101011000100110110001100101 (长度为 120

若按赫夫曼编码压缩 hungryandumble的压缩代码为
01101010100000110010110110111000110101000111111101001 (长度为 52

使用赫夫曼编码压缩了 (120 - 52) / 120 = 56.7%


http://chatgpt.dhexx.cn/article/uf7Sx4Us.shtml

相关文章

霍夫曼树:霍夫曼编码(Huffman Tree:Huffman Coding)

一、简介 霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低&#xff0c;决定如何给符号编码。如果符号出现的频率越高&#xff0c;则给符号的码越短&#xff0c;相反符号的号码越长。 相关术语 路径&#xff1a;从书中一个节点到另一个节点之间的分支构成这两个…

霍夫曼编码

霍夫曼在1952年提出了霍夫曼编码&#xff0c;霍夫曼编码是一种无损的统计编码方法&#xff0c;利用信息符号概率分布特性来改编字长进行编码。适用于多元独立信源。霍夫曼编码对于出现概率大的信息符号用字长小的符号表示&#xff0c;对于出现概率小的信息用字长大的符号代替。…

霍夫曼(Huffman)编码算法详解之C语言版

一、Huffman编码 霍夫曼(Huffman)树是一类带权路径长度最短的二叉树树。Huffman树的一个非常重要的应用就是进行Huffman编码以得到0-1码流进行快速传输。 在电报收发等数据通讯中&#xff0c;常需要将传送的文字转换成由二进制字符0、1组成的字符串来传输。为了使收发的速度提…

哈夫曼编码

哈夫曼编码 概念前缀码的二叉树及权值哈夫曼编码的设计思想 实例伪代码 概念 哈夫曼编码是一种字符编码方式&#xff0c;是可变长编码的一种&#xff0c;1952年提出&#xff0c;依据字符在文件中出现的频率来建立一个用0,1串表示各字符&#xff0c;使平均每个字符的码长最短的…

图像处理—霍夫曼编码

图像压缩编码是专门研究图像数据压缩的技术&#xff0c;就是尽量减少表示数据图像所需要的数据量。 本章主要介绍图像压缩编码的基础知识&#xff0c;重点讲解常用的图像压缩编码方法&#xff0c;如霍夫曼编码、香农编码、算术编码、行程编码和预测编码及编码方法的MATLAB实现&…

哈夫曼编码(理解)

基础理解 什么是哈夫曼树&#xff08;Huffman Tree&#xff09; 给定N个带权值的叶子节点&#xff0c;如何构造出一个带权路径最小的二叉树&#xff1f; 在数据结构理论中&#xff0c;哈夫曼树又称为最优树&#xff0c;相关的知识点还有哈弗曼编码等。在正式介绍哈夫曼树之前…

学弟学妹们,学会霍夫曼编码后,再也不用担心网络带宽了!

CSDN 的学弟学妹们&#xff0c;大家好&#xff0c;我是沉默王二。 今天来给大家普及一下霍夫曼编码&#xff08;Huffman Coding&#xff09;&#xff0c;一种用于无损数据压缩的熵编码算法&#xff0c;由美国计算机科学家大卫霍夫曼在 1952 年提出——这么专业的解释&#xff…

哈夫曼编码详解

一&#xff1a;基本介绍 哈夫曼编码也翻译为 赫夫曼编码(Huffman Coding)&#xff0c;又称霍夫曼编码&#xff0c;是一种编码方式, 属于一种程序算法 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 赫夫曼编码广泛地用于数据文件压缩。其压缩率通常在20%&#xff5…

赫夫曼编码

一 基本介绍 1 赫夫曼编码也翻译为哈夫曼编码(Huffman Coding)&#xff0c;又称霍夫曼编码&#xff0c;是一种编码方式, 属于一种程序算法。 2 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 3 赫夫曼编码广泛地用于数据文件压缩。 其压缩率通常在20%&#xff5e;9…

哈夫曼编码(Huffman Coding)原理详解

哈夫曼编码 哈夫曼编码&#xff0c;又称为哈夫曼编码&#xff08;Huffman Coding&#xff09; 是一种可变长编码&#xff08; VLC, variable length coding)&#xff09;方式&#xff0c;比起定长编码的 ASCII 编码来说&#xff0c;哈夫曼编码能节省很多的空间&#xff0c;因…

霍夫曼编码详解

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;information-theory】&#xff0c;需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录 霍夫曼编码最佳…

霍夫曼编码(Huffman Coding)

霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种。 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用…

Typecho 博客美化

以前用typecho博客&#xff0c;现在学生服务器到期了&#xff0c;先记录到csdn上&#xff0c;以后工作有钱了&#xff0c;再租个服务器写博客:) 代码高亮 https://www.typechodev.com/plugin/482.html 天气功能 使用心知天气带的插件就可以轻松实现了。 https://www.seniverse…

Hexo博客之博客美化

https://lqgjava.github.io/2019/08/24/Hexo博客之博客美化/ 只需阅读这一篇文章&#xff0c;就可以让你的博客变得丰富多彩&#xff0c;有添加卡通人物&#xff0c;添加鼠标点击爱心&#xff0c;添加鼠标指针样式 添加彩色滚动变换、添加背景音乐、添加动态彩带等&#xff0…

CSDN博客美化

排列博客分类 管理博客-分类专栏下修改 双击分类名称&#xff0c;即可编辑&#xff0c;输入“#”“空格”“分类名称”可将一级分类改成二级分类。 显示的效果 分类图标设置 编辑-设置图标&#xff0c;可以这里找阿里素材库 效果图

【CSDN】CSDN博客美化教程

一、效果 二、MarkDown简明教程 MarkDown简明教程 三、摘要 添加摘要&#xff0c;增加可读性。 PS. 其实&#xff0c;可以根据深度学习算法&#xff0c;自动生成摘要。 四、自定义博客栏目 五、修改皮肤

博客美化作业详细教程

博客美化作业 第一步 下载作业资源 第二步 在文件夹内打开下载资源 单击后缀为HTML文件的网页文件&#xff0c;右击用编译器打开 这些软件都可以&#xff08;除了紫色的&#xff09; 第三步 准备工作 首先让我们重新看下作业要求&#xff1a; 必须使用“类选择器”来美化网…

【全网最全的博客美化系列教程】04.访客量统计的实现

全网最全的博客美化系列教程相关文章目录 【全网最全的博客美化系列教程】01.添加Github项目链接 【全网最全的博客美化系列教程】02.添加QQ交谈链接 【全网最全的博客美化系列教程】03.给博客添加一只萌萌哒的小仓鼠 【全网最全的博客美化系列教程】04.访客量统计的实现 【全网…

Hexo博客美化之——IP签名图一网打尽

love421个人博客地址&#xff1a;https://www.makedreamsir.xyz IP签名图可以实时显示来访者的坐标&#xff0c;IP地址&#xff0c;操作系统&#xff0c;浏览器等等。 使用方法&#xff1a;将下面生成的链接插入到合适的位置即可。 项目原地址&#xff1a;点我打开 原作者博…

Web前端:博客美化:一、模板美化

1、选用模板simplememory 2、写css放在 这些会覆盖掉原来的css样式 我是在网上找的css代码二次加工的 : &#xff09; /*1、针对simplememory的修改*/ #google_ad_c1, #google_ad_c2 {display:none;} .syntaxhighlighter a, .syntaxhighlighter div, .syntaxhighlighter code, …