前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >哈夫曼编码

哈夫曼编码

作者头像
晚上没宵夜
发布于 2022-05-09 13:12:25
发布于 2022-05-09 13:12:25
40700
代码可运行
举报
运行总次数:0
代码可运行

离开了校园,连手机流量都要省着用,然后突发奇想的思考如何才能节省传输大小

1. 哈夫曼树

构建最短带权路径长度的二叉树,叫做哈夫曼树,也叫最优树(权重越大的结点离树根越近)

1.1 基本定义

  • 路径:树中的一个节点到另一个节点之间的通路
  • 路径长度:某路径中所经过的节点数量
  • 节点的权:给节点赋值,这个值称为节点的权
  • 节点的带权路径长度:根节点到某节点的路径长度 * 该节点的权
  • 树的带权路径长度:树中所有叶子节点的带权路径长度之和,记作 "WPL"

1.2 构建步骤

  • 选出两个最小权值作为左右子树,新建其父节点(虚线),权值为左右子树权值之和
  • 从权值队列中删除第一步的左右子树的权值,添加第一步新增的二叉树到权值队列
  • 重复第一、二步,直到构建完权值队列中所有节点

1.3 构建图示

WPL:9 * 1 + 6 * 2 + 4 * 3 + 1 * 3 = 36

2. 哈夫曼编码

哈夫曼编码是一种编码方式,其可以对信息进行压缩,而从提高存储,传输的效率

2.1 基本定义

  • 等长编码:任何字符的编码长度都相同,比如ASCII。虽读写方便,但浪费资源,且有前缀码问题
  • 无前缀编码:任一个编码都不是其他任何编码的前缀。[01,10,11,100,101]中10是100的前缀,因此不是无前缀编码

2.2 构建步骤

  • 根据权值构建哈夫曼树
  • 将哈夫曼树的左树标 0,右树标记1,根节点不计算
  • 将权值替换为对应的字符
  • 列出字符对应的二进制

2.3 构建图示

假设字符A、B、C、D对应的权值为1、9、4、6

(4)

字符

编码

A

000

B

1

C

001

D

01

2.4 哈夫曼编码应用

通过哈夫曼编码传输文本、图片,查看前后对比

2.4.1 哈夫曼编码 java 实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author Howl
 * 哈夫曼编码
 */
public class HuffmanCode {
    /**
     * 哈夫曼树结点结构
     */
    private static class Node implements Comparable<Node> {
        /**
         * 权值、二进制编码0、1、左右孩子
         */
        int weight;
        String code;
        Node left;
        Node right;

        Node(int weight) {
            this.weight = weight;
        }

        Node(int weight, Node left, Node right) {
            this.weight = weight;
            this.left = left;
            this.right = right;
        }

        @Override
        public int compareTo(Node o) {
            return Integer.compare(this.weight, o.weight);
        }
    }

    /**
     * 根节点、存储全部节点
     */
    private Node root;
    private static Node[] nodes;

    /**
     * 构建哈夫曼树
     * 建树是从最小权值开始的,所以借助小根堆
     */
    public void createHuffman(int[] weights) {

        // 构建小根堆,弹出是最小的元素
        Queue<Node> nodeQueue = new PriorityQueue<>();
        nodes = new Node[weights.length];
        for (int i = 0; i < weights.length; i++) {
            nodes[i] = new Node(weights[i]);
            nodeQueue.add(nodes[i]);
        }

        // 节点队列只剩一个节点结束,即根节点构建完成
        while (nodeQueue.size() > 1) {

            // 弹出权值最小的两个结点
            Node left = nodeQueue.poll();
            Node right = nodeQueue.poll();

            // 创建新节点作为两结点的父节点
            Node parent = new Node(left.weight + right.weight, left, right);
            nodeQueue.add(parent);
        }

        // 哈夫曼树根,遍历要用,优先级队列GC
        root = nodeQueue.poll();
        // 实现编码
        encode();
    }

    /**
     * 输入字符下标,输出对应的哈夫曼编码
     */
    public String convertHuffmanCode(int index) {
        return nodes[index].code;
    }

    /**
     * 递归填充二进制编码
     */
    private void encode() {
        encode(root, "");
    }

    private void encode(Node node, String code) {
        if (node == null) {
            return;
        }
        node.code = code;
        encode(node.left, node.code + "0");
        encode(node.right, node.code + "1");
    }

    /**
     * 测试
     */
    public static void main(String[] args) {

        // 字符及其对应权值
        char[] chars = {'A', 'B', 'C', 'D', 'E', 'F'};
        int[] weights = {2, 3, 7, 9, 18, 25};

        HuffmanCode huffManCode = new HuffmanCode();
        huffManCode.createHuffman(weights);
        for (int i = 0; i < chars.length; i++) {
            System.out.println(chars[i] + ":" + huffManCode.convertHuffmanCode(i));
        }
    }
}
2.4.2 传输实现
  • 将原文进行哈夫曼编码,记录字符及其对应的编码,保存文件为 HuffmanCode
  • 将原文的字符用哈夫曼编码代替,保存文件为 HuffmanText
  • 将上面两个文件发送给对方
  • 对方根据这两份文件就可以解码出原文

3. 开源压缩框架

3.1 图片

Thumbnailator是专门压缩图片的,使用非常简洁

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 图片压缩
Thumbnails.of("C:\\Users\\Howl\\Desktop\\InPic.png")	// 输入图片地址
    .scale(1)											// 和原尺寸大小,即长度,1是原大小
    .outputQuality(0.5)									// 和原图的质量
    .outputFormat("jpg")								// 输出格式,png为高保真不会压缩
    .toFile("C:\\Users\\Howl\\Desktop\\OutPic");		// 输出地址
}

参考:

程序员小灰

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
漫画:“哈夫曼编码” 是什么鬼?
在上一期,我们介绍了一种特殊的数据结构 “哈夫曼树”,也被称为最优二叉树。没看过的小伙伴可以点击下方链接:
小灰
2020/04/22
89519
漫画:什么是 “哈夫曼树” ?
在一棵树中,从一个结点到另一个结点所经过的所有结点,被我们称为两个结点之间的路径。
小灰
2020/04/22
9761
【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)
参考资料 《算法(java)》                           — — Robert Sedgewick, Kevin Wayne 《数据结构》                                  — — 严蔚敏 赫夫曼树的概念 要了解赫夫曼树,我们要首先从扩充二叉树说起 二叉树结点的度 结点的度指的是二叉树结点的分支数目, 如果某个结点没有孩子结点,即没有分支,那么它的度是0;如果有一个孩子结点, 那么它的度数是1;如果既有左孩子也有右孩子, 那么这个结点的度是2. 扩充
啦啦啦321
2018/03/30
2K0
【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)
数据结构(15)–哈夫曼树以及哈夫曼编码的实现「建议收藏」
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说数据结构(15)--哈夫曼树以及哈夫曼编码的实现「建议收藏」,希望能够帮助大家进步!!!
Java架构师必看
2022/10/05
2.8K0
数据结构(15)–哈夫曼树以及哈夫曼编码的实现「建议收藏」
使用哈夫曼树实现文本编码、解码
现在许多实际问题抽象出来的数据结构往往都是二叉树的形式。哈夫曼编码可以对日常数据量很大的数据,进行数据压缩技术来实现存储和传输。
全栈程序员站长
2022/08/18
1.2K0
使用哈夫曼树实现文本编码、解码
哈夫曼编码
1.哈夫曼编码是一种可以被唯一解读的二进制编码 2.前缀编码保证了解码时不会有多种可能 3.哈夫曼编码有不等长和等长两种编码,为了保证不等长编码的唯一性,使用前缀编码 4.频率低的采用短编码,频率高的采用长编码。
大忽悠爱学习
2021/03/18
8050
数据结构实验哈夫曼编码算法的实现_哈夫曼编码算法的实现
哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,
全栈程序员站长
2022/09/23
6780
数据结构实验哈夫曼编码算法的实现_哈夫曼编码算法的实现
原以为哈夫曼树、哈夫曼编码很难,结果……
哈夫曼树、哈夫曼编码很多人可能听过,但是可能并没有认真学习了解,今天这篇就比较详细的讲一下哈夫曼树。
main方法
2021/07/19
6740
原以为哈夫曼树、哈夫曼编码很难,结果……
[数据结构与算法]赫夫曼树与赫夫曼编码
给你一个数列 {13, 7, 8, 3, 29, 6, 1},要求转成一颗赫夫曼树.
时间静止不是简史
2020/07/24
1.2K0
数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
哈夫曼树Huffman tree 又称最优完全二叉树,切入正题之前,先看几个定义 1、路径 Path 简单点讲,路径就是从一个指定节点走到另一个指定节点所经过的分支,比如下图中的红色分支(A->C->
菩提树下的杨过
2018/01/23
1.3K0
数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
文章目录 5.4.1 方式 5.4.2 由先根和中根遍历序列建二叉树 5.4.3 由后根和中根遍历序列建二叉树 5.4.4 由标明空子树的先根遍历建立二叉树 5.4.5 由完全二叉树的顺序存储结构建立二叉链式存储结构 5.5 哈夫曼树及哈夫曼编码 5.5.1 基本概念 5.5.2 最优二叉树 5.5.3 构建哈夫曼树 5.5.4 哈夫曼编码 5.5.5 哈夫曼编码类 5.4.1 方式 四种方式可以建立二叉树 由先根和中根遍历序列建二叉树 由后根和中根遍历序列建二叉树 由标明空子树的先根遍
陶然同学
2023/02/26
1.1K0
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
哈夫曼树与哈夫曼编码:聪明的数据压缩技术
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/14
1.1K1
哈夫曼树与哈夫曼编码:聪明的数据压缩技术
数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 数据结构图文解析之:树的简介及二叉排序树C++模板实现. 数据结构图文解析之:AVL树详解及C++模板实现 数据结构图文解析之:二叉堆详解及C++模板实现 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现 1. 哈夫曼编码简
Tencent JCoder
2018/07/02
1.1K0
Huffman 编码的编程与实现 C语言
一 、目的: 1.    掌握Huffman树的概念、存储结构; 2.    掌握建立Huffman树和Huffman编码的方法; 二 、环境: operating system version:Win11 CPU instruction set:  x64 Integrated Development Environment:Viusal Studio 2022 三 、内容: 利用动态分配数组存储赫夫曼树,设计一组输入数据(假定为一组整数),能够对其进行如下操作: 1)创建一个新的顺序表,实现动态空间分配的初始化 2)对输入的数据构造成一棵 Huffman 树; 3)根据生成的 Huffman 树进行 Huffman 编码 4)实现对输入数据的 Huffman 编码输出 。 四 、要求: 1) 实现 Huffman 树的生成 2) 完成 Huffman 编码的输出 。 五 、步骤: 1. 程序:
timerring
2025/05/24
1390
Huffman 编码的编程与实现 C语言
哈夫曼树和哈夫曼编码
  在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN)树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如JPEG中就应用了哈夫曼编码。 首先介绍什么是哈夫曼树。 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的 路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i
mukekeheart
2018/02/27
2K0
哈夫曼树和哈夫曼编码
数据结构(五):哈夫曼树(Huffman Tree)
哈夫曼树(或者赫夫曼树、霍夫曼树),指的是一种满二叉树,该类型二叉树具有一项特性,即树的带权路径长最小,所以也称之为最优二叉树。
zhipingChen
2018/09/13
2.9K0
数据结构(五):哈夫曼树(Huffman Tree)
赫夫曼编码-1
赫夫曼树应用场景 赫夫曼编码式赫夫曼树在电讯通信中的经典应用之一。 赫夫曼树也广泛的应用于数据文件的压缩。其压缩效率通常在 20% -90% 之间 生成赫夫曼编码 步骤与赫夫曼树类似 package xmht.datastructuresandalgorithms.datastructure.tree.huffmancode; import org.jetbrains.annotations.NotNull; import java.util.*; /** * @author shengjk1 *
shengjk1
2020/06/08
4280
哈夫曼树、哈夫曼编码和字典树
        哈夫曼树(Huffman Tree)是一种带权路径长度最短的二叉树。哈夫曼树常常用于数据压缩,其压缩效率比较高。
周小末天天开心
2023/10/16
5660
哈夫曼树、哈夫曼编码和字典树
数据结构09 哈夫曼树
这一篇要总结的是树中的哈夫曼树(Huffman Tree),我想从以下几点对其进行总结: 1、什么是哈夫曼树 2、如何构建哈夫曼树 3、哈夫曼编码 4、代码实现 1、什么是哈夫曼树 什么是哈夫曼树
nnngu
2018/03/15
7880
数据结构09 哈夫曼树
哈夫曼树
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径
Java架构师必看
2021/12/27
7210
推荐阅读
相关推荐
漫画:“哈夫曼编码” 是什么鬼?
更多 >
LV.1
这个人很懒,什么都没有留下~
作者相关精选
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验