返回顶部
首页 > 资讯 > 精选 >什么是赫夫曼编码
  • 673
分享到

什么是赫夫曼编码

2023-06-15 16:06:58 673人浏览 八月长安
摘要

本篇内容介绍了“什么是赫夫曼编码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 基本介绍赫夫曼编码也翻译为(哈夫曼编码)Huffm

本篇内容介绍了“什么是赫夫曼编码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

 基本介绍

  • 赫夫曼编码也翻译为(哈夫曼编码)Huffman coding,又称为霍夫曼编码,是一种编码方式,属于一种程序算法

  • 赫夫曼编码是赫夫曼树在电讯通讯中的经典的应用场景之一。

  • 赫夫曼编码广泛的用于数据文件压缩。其压缩率通常在20%~90%之间。

  • 赫夫曼码是可变字长编码(VLC)的一种.Hufuuman于1952年提出一种编码方法,称之为最佳编码。

原理剖析

在通信领域中信息的处理方式1:定长编码

如: i like like like java do you like a java  共40个字符,包括空格,其对应的ASCII码,与二进制编码如下图

什么是赫夫曼编码

按照二进制来传递信息,总的长度是359(包含空格)

在通信领域中信息的处理方式2:变长编码

i like like like java do you like a java 共40个字符,包括空格。变长编码处理如下图

什么是赫夫曼编码

字符的编码都不能是其他字符编码的前缀,符合此要求的编码叫做前缀编码,即不能匹配到重复的编码。

在通信领域中信息的处理方式3:赫夫曼编码

i like like like java do you like a java 共40个字符,包括空格。变长编码处理如下图

什么是赫夫曼编码

按照上面字符出现的次数构建一颗赫夫曼树,次数作为权值。

什么是赫夫曼编码

根据赫夫曼树,给各个字符,规定编码(前缀编码),向左的路径为0 向右的路径为1:编码如下:

什么是赫夫曼编码

按照上面的赫夫曼编码,我们的"i like like like java do you like a java"  字符串对应的编码(注意这里我们使用的无损压缩)如下图。

什么是赫夫曼编码

说明:

原来的长度是359,压缩了(359-133)/359=62.9%

此编码满足前缀编码,即字符的编码都不能是其他字符编码的前缀。不会造成匹配的多义性。

赫夫曼编码是无损压缩!!

注意:

这个赫夫曼树根据排序方法不同,也可能不一样,这样对应的赫夫曼编码也不完全一样,但是wpl是一样的,都是最小的,比如我们让每次生成的新的二叉树总是排在权值相同的二叉树的最后一个,则生成的二叉树为:

什么是赫夫曼编码

创建对应的赫夫曼树

根据赫夫曼编码压缩数据的原理,需要创建"i like like like java do you like a java" 对应的赫夫曼树

思路:

先创建node节点,Node {data{存放数据},weight(权值),left,right};

得到"i like like like java do you like a java" 对应的byte[] 数组;

编写一个方法,将准备构建赫夫曼树的node节点放到List集合;

可以通过集合List创建对应的赫夫曼树;

赫夫曼树应用案例

将一串字符串进行压缩与解压缩

package com.xie.huffmancode;  import java.util.*;  public class HuffmanCode {     public static void main(String[] args) {         String str = "i like like like java do you like a java";         byte[] contentBytes = str.getBytes();         System.out.println("contentBytes=" + Arrays.toString(contentBytes));         List<Node> nodes = getNodes(contentBytes);          //生成赫夫曼树         Node hufffmanTreeRoot = createHufffmanTree(nodes);          //生成的赫夫曼编码表         getCodes(hufffmanTreeRoot, "", stringBuilder);          byte[] huffmanCodeBytes = zip(contentBytes, huffmanCodes);         System.out.println("huffmanCodeBytes = " + Arrays.toString(huffmanCodeBytes));          byte[] decode = decode(huffmanCodes, huffmanCodeBytes);         System.out.println("赫夫曼解码后对应的数组" + new String(decode));                }      //完成数据的解压思路     //1.将huffmanCodeBytes[-88, -65, -56, -65, -56, -65, -55, 77, -57, 6, -24, -14, -117, -4, -60, -90, 28]     //  重新转成 赫夫曼编码对应的二进制字符串"101010001011111111001000101111...."     //2.赫夫曼编码对应的二进制字符串"101010001011111111001000101111...." => 对照赫夫曼编码表 => "i like like like java do you like a java"           public static byte[] decode(Map<Byte, String> huffmanCodes, byte[] huffmanBytes) {         StringBuilder stringBuilder = new StringBuilder();         for (int i = 0; i < huffmanBytes.length; i++) {             //判断是不是最后一个字节             boolean flag = (i == huffmanBytes.length - 1);             stringBuilder.append(byteToBitString(!flag, huffmanBytes[i]));         }          Map<String, Byte> map = new HashMap<>();         for (Map.Entry<Byte, String> entry : huffmanCodes.entrySet()) {             Byte k = entry.geTKEy();             String v = entry.getValue();             map.put(v, k);         }          List<Byte> list = new ArrayList<>();         for (int i = 0; i < stringBuilder.length();) {             int count = 1;             boolean flag = true;             Byte b = null;             while (flag) {                 String key = stringBuilder.substring(i, i + count);//i 不动,count移动,直到匹配一个字符                 b = map.get(key);                 if (b == null) {                     count++;                 } else {                     flag = false;                 }             }             list.add(b);             i += count;         }         byte[] bytes = new byte[list.size()];         for (int i = 0; i < list.size(); i++) {             bytes[i] = list.get(i);         }         return bytes;     }           public static String byteToBitString(boolean flag, byte b) {         //将b 转成 int         int temp = b;          //如果temp是正数还需要补高位         if (flag) {             // 按位或 如 256|1=> 1 0000 0000|0000 0001 => 1 0000 0001             temp |= 256;         }          //返回的是temp二进制的补码         String bitStr = Integer.toBinaryString(temp);         if (flag) {             //取后8位             return bitStr.substring(bitStr.length() - 8);         } else {             return bitStr;         }     }           public static byte[] huffmanZip(byte[] bytes) {         List<Node> nodes = getNodes(bytes);          //创建赫夫曼树         Node hufffmanTreeRoot = createHufffmanTree(nodes);         //生成赫夫曼编码         getCodes(hufffmanTreeRoot, "", stringBuilder);         //返回压缩后的赫夫曼编码字节数组         return zip(bytes, huffmanCodes);      }           public static byte[] zip(byte[] bytes, Map<Byte, String> huffmanCodes) {         //利用huffmanCodes 将 bytes 转成赫夫曼编码对应的字符串         StringBuilder stringBuilder = new StringBuilder();         for (byte b : bytes) {             stringBuilder.append(huffmanCodes.get(b));         }          // 将"101010001011111111001000101111...." 转成byte[]         // 统计返回byte[] huffmanCodeBytes 长度         int len;         if (stringBuilder.length() % 8 == 0) {             len = stringBuilder.length() / 8;         } else {             len = stringBuilder.length() / 8 + 1;         }         //创建 存储压缩后的byte[]数组         byte[] huffmanCodeBytes = new byte[len];         int index = 0;         for (int i = 0; i < stringBuilder.length(); i += 8) {             String strByte;             if (i + 8 > stringBuilder.length()) {                 strByte = stringBuilder.substring(i);             } else {                 strByte = stringBuilder.substring(i, i + 8);             }             //将strByte 转成一个byte ,放入到huffmanCodeBytes             huffmanCodeBytes[index] = (byte) Integer.parseInt(strByte, 2);             index++;         }         return huffmanCodeBytes;     }      //生成赫夫曼树对应的赫夫曼编码表     //思路:     //1. 将赫夫曼编码表存放在Map<Byte,String>,形式如32->01,97->100...     static Map<Byte, String> huffmanCodes = new HashMap<>();     //2. 在生成赫夫曼编码表时,需要拼接路径,定义一个StringBuilder  存储某个叶子节点的路径     static StringBuilder stringBuilder = new StringBuilder();           public static void getCodes(Node node, String code, StringBuilder stringBuilder) {         StringBuilder stringBuilder2 = new StringBuilder(stringBuilder);         stringBuilder2.append(code);         if (node != null) {             //判断当前node 是叶子节点还是非叶子节点             if (node.data == null) {//非叶子节点                  //向左递归处理                 getCodes(node.left, "0", stringBuilder2);                 //向右递归处理                 getCodes(node.right, "1", stringBuilder2);             } else {//叶子节点                 huffmanCodes.put(node.data, stringBuilder2.toString());             }         }     }      //前序遍历     public static void preOrder(Node root) {         if (root != null) {             root.preOrder();         } else {             System.out.println("赫夫曼树不能为空~~");         }     }           public static List<Node> getNodes(byte[] bytes) {         ArrayList<Node> nodes = new ArrayList<>();          //存储每个byte出现的次数         Map<Byte, Integer> counts = new HashMap<>();         for (byte b : bytes) {             counts.merge(b, 1, (a, b1) -> a + b1);         }          //把每个键值对转成一个node对象,并加入到nodes 集合         counts.forEach((k, v) -> nodes.add(new Node(k, v)));         return nodes;     }           public static Node createHufffmanTree(List<Node> nodes) {         while (nodes.size() > 1) {             //排序,从小到大             Collections.sort(nodes);              //(1)取出权值最小的节点(二叉树)             Node leftNode = nodes.get(0);              //(2) 取出权值第二小的节点(二叉树)             Node rightNode = nodes.get(1);             //(3) 构建一颗新的二叉树             Node parent = new Node(null, leftNode.weight + rightNode.weight);             parent.left = leftNode;             parent.right = rightNode;              //(4) 从ArrayList中删除处理过的二叉树             nodes.remove(leftNode);             nodes.remove(rightNode);             //(5) 将parent加入nodes             nodes.add(parent);         }         //nodes 的最后一个就是赫夫曼树的root节点         return nodes.get(0);     } }  //创建Node,带数据和权值 class Node implements Comparable<Node> {     //存放数据本身,比如'a'=>'97',' ' =>'32'     Byte data;     //权值,表示字符出现的次数     int weight;      Node left;     Node right;      public Node(Byte data, int weight) {         this.data = data;         this.weight = weight;     }      public void preOrder() {         System.out.println(this);         if (this.left != null) {             this.left.preOrder();         }         if (this.right != null) {             this.right.preOrder();         }     }      @Override     public int compareTo(Node o) {         //从小到大排序         return this.weight - o.weight;     }      @Override     public String toString() {         return "Node{" +                 "data=" + data +                 ", weight=" + weight +                 '}';     } }

 赫夫曼压缩文件注意事项

如果文件本身就经过压缩处理的,那么使用赫夫曼编码再压缩效率不会有明显的变化,比如视频,ppt等文件。

赫夫曼编码是按字节来处理的,因此可以处理所有的文件(二进制文件,文本文件)

如果一个文件中的内容,重复的数据不多,压缩效果也不会明显。

“什么是赫夫曼编码”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 什么是赫夫曼编码

本文链接: https://lsjlt.com/news/280747.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 什么是赫夫曼编码
    本篇内容介绍了“什么是赫夫曼编码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 基本介绍赫夫曼编码也翻译为(哈夫曼编码)Huffm...
    99+
    2023-06-15
  • Python语言实现哈夫曼编码
    汉语版:使用python实现huffman编码是一个能够很快地实现。所以我们选择使用python来实现我们这个程序。 l E-version: we will use python to realize this program call...
    99+
    2023-01-31
    语言 Python 哈夫曼
  • 如何正确理解霍夫曼编码
    这篇文章主要讲解了“如何正确理解霍夫曼编码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何正确理解霍夫曼编码”吧!说实话,很早之前我就听说过霍夫曼编码,除...
    99+
    2024-04-02
  • 使用R语言怎么编写一个霍夫曼编码
    本篇文章给大家分享的是有关使用R语言怎么编写一个霍夫曼编码,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。p=c(0.4,0.2,0.2,0.1,0.1)###输入形如c(0.4...
    99+
    2023-06-14
  • Java中的哈夫曼压缩原理是什么
    这篇文章主要介绍“Java中的哈夫曼压缩原理是什么”,在日常操作中,相信很多人在Java中的哈夫曼压缩原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的哈夫曼压缩原理是什么”的疑惑有所帮助!...
    99+
    2023-06-20
  • 用R语言实现霍夫曼编码的示例代码
    可读性极低,而且其实也没必要用R语言写,图个乐罢了  p=c(0.4,0.2,0.2,0.1,0.1)###输入形如c(0.4,0.2,0.2,0.1,0.1)的概率向...
    99+
    2024-04-02
  • C语言实现BMP图像处理(哈夫曼编码)
    哈夫曼(Huffman)编码是一种常用的压缩编码方法,是 Huffman 于 1952 年为压缩文本文件建立的。它的基本原理是频繁使用的数据用较短的代码代替,较少使用的数据用较长的代...
    99+
    2024-04-02
  • Java利用哈夫曼编码实现字符串压缩
    赫夫曼编码基本介绍 1) 赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 属于一种程序算法 2) 赫夫曼编码是赫哈夫曼树在电讯通信中...
    99+
    2024-04-02
  • C++哈夫曼树的概念是什么与怎么实现
    这篇文章主要介绍“C++哈夫曼树的概念是什么与怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++哈夫曼树的概念是什么与怎么实现”文章能帮助大家解决问题。一、 基本概念结点的权: 有某种现实...
    99+
    2023-06-30
  • 利用Python和C语言分别实现哈夫曼编码
    目录1.C语言实现1.1代码说明1.2运行结果2.Python实现2.1代码说明2.2运行结果1.C语言实现 1.1代码说明 a  创建双向链表: 在创建哈夫曼树的过程中,...
    99+
    2024-04-02
  • 如何利用Python和C语言分别实现哈夫曼编码
    1.C语言实现1.1代码说明a 创建双向链表:在创建哈夫曼树的过程中,需要不断对结点进行更改和删除,所以选用双向链表的结构更容易'''C #include <stdlib.h> #include <...
    99+
    2023-05-22
    Python C语言
  • java数据结构图论霍夫曼树及其编码示例详解
    目录霍夫曼树一、基本介绍二、霍夫曼树几个重要概念和举例说明 构成霍夫曼树的步骤霍夫曼编码一、基本介绍二、原理剖析注意:霍夫曼编码压缩文件注意事项霍夫曼树 一、基本介绍 二、霍夫曼树...
    99+
    2024-04-02
  • 冯诺伊曼结构是什么
    冯诺依曼结构是计算机体系结构的一种基本架构,它是由冯·诺伊曼于20世纪40年代提出的,该结构被广泛应用于现代计算机中,包括个人电脑、服务器、超级计算机等等。它为计算机的设计和实现提供了一个重要的框架。虽然它有一些局限性,但仍然被广泛应用于现...
    99+
    2023-08-16
  • dedecms是什么编码
    Dedecms使用 UTF-8编码,UTF-8是一种通用的字符编码方式,可以表示几乎所有的字符,并且具有较好的兼容性和跨平台性,UTF-8编码支持包括中文在内的多种语言和字符集,因此广泛应用于各类网站和软件系统中。本教程操作系统:Windo...
    99+
    2023-08-03
  • 阿里云服务器CPU最大赫兹是什么
    本文将深入探讨阿里云服务器CPU的最大赫兹,并解释其对服务器性能的影响。 在云计算领域,阿里云服务器是许多企业和个人的选择。阿里云服务器基于英特尔和AMD等厂商的硬件设备,这些设备具有多种规格和性能。其中,CPU(中央处理器)是一个关键的硬...
    99+
    2024-01-26
    阿里 服务器 CPU
  • HTML的编码是什么
    这篇文章主要为大家展示了“HTML的编码是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML的编码是什么”这篇文章吧。 常见编码个格式: UTF-8...
    99+
    2024-04-02
  • 冯诺依曼计算机的特点是什么
    冯诺依曼计算机的特点是:1、存储程序,将程序和数据存储在同一存储器中,并使用相同的数据格式;2、顺序执行,每条指令被依次取出、解码和执行,直到程序结束或者遇到跳转指令;3、存储器层次结构,按照存储器的速度和容量划分不同的层次;4、二进制表示...
    99+
    2023-08-15
  • base64编码指的是什么
    这篇文章给大家分享的是有关base64编码指的是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。base64编码是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表...
    99+
    2023-06-14
  • 什么是无代码编程
    今天就跟大家聊聊有关什么是无代码编程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。规模化的组织,常要面临这样的挑战:每个应用的基础设施是相同的,部分的代码也是相同的,甚至于它们可能只...
    99+
    2023-06-19
  • Python字符编码是什么
    本文小编为大家详细介绍“Python字符编码是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python字符编码是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. 字符编码简介1.1. ASCIIAS...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作