利用java实现Huffman编码。

哈夫曼树也称最优二叉树,也是带权路径最小的二叉树。

带权路径的值,就是各个节点的权重乘上深度,然后做和.

如下图,这棵树的带权路径值 为 1*3 + 2*3 + 3*2 +3*1 = 18

所以构建一个哈夫曼树的关键在于,让权重大的叶子更靠近根节点,权重小的叶子远离根节点。

哈夫曼编码就是借助哈夫曼树对文本进行编码操作。将一串字符串编码成 用 0 和 1 进行表示

假设有这么一串字符串:  abbcccddddd

首先字符串按照字符分割,得到一个个字符,然后统计各个字符出现的次数:

a->1

b->2

c->3

d->5

把字符当作叶子,字符出现的次数当作叶子的权重,可以构建出下面这棵树:

1. 首先选出出现次数最少的两个字符,当作叶子节点,根据他们的权重,计算出他们父节点的权重。

2. 再从剩下的节点中,与刚刚生成的节点比较,选出最小的一个或者两个,继续构造这棵树。

3. 重复这个过程,直到最后一个节点。

现在以abcdefg为例子:

出现字符次数相同的情景时,就按照字符进行排序。

按照坐左枝为0 右枝为1 规则进行编码。

比如 a 010   g 00

所以,对abcedfg 进行编码之后,01001110010111011100

java代码实现:

1. 创建一个类,实现Comparable用来排序

class HFNode implements Comparable<HFNode> {char character;int frequence;private HFNode left;private HFNode right;private String code;public char getCharacter() {return character;}public void setCharacter(char character) {this.character = character;}public int getFrequence() {return frequence;}public void setFrequence(int frequence) {this.frequence = frequence;}public HFNode getLeft() {return left;}public void setLeft(HFNode left) {this.left = left;}public HFNode getRight() {return right;}public void setRight(HFNode right) {this.right = right;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}@Overridepublic String toString() {return this.character + " " + this.frequence + " ";}@Overridepublic int compareTo(HFNode o) {if (this.frequence == o.frequence) {return this.getCharacter() - o.getCharacter();}return this.frequence - o.frequence;}

2. 分割字符串,统计每个字符出现的次数,并存放到队列中去。

Scanner in = new Scanner(System.in);String inLine = in.next();char[] chars = inLine.toCharArray();Map<Character, Integer> characterMap = new HashMap<>();for (int i = 0; i < chars.length; i++) {int count = characterMap.containsKey(chars[i]) ? characterMap.get(chars[i]) : 0;characterMap.put(chars[i], count + 1);}PriorityQueue<HFNode> pQueue = new PriorityQueue<>();Set<Character> key = characterMap.keySet();for (char c : key) {HFNode hfNode = new HFNode();hfNode.setCharacter(c);hfNode.setFrequence(characterMap.get(c));pQueue.add(hfNode);}

3. 构建哈夫曼树(两个叶子生成节点的字符,默认使用他的左树的字符)

每次取最小的两个节点出来,然后合并成一个新节点,再把新节点加入到队列中去。

while (pQueue.size() > 1) {HFNode newNode = new HFNode();HFNode leftNode = pQueue.remove();HFNode rightNode = pQueue.remove();newNode.setFrequence(rightNode.getFrequence() + leftNode.getFrequence());newNode.setLeft(leftNode);newNode.setRight(rightNode);newNode.setCode("");newNode.setCharacter(newNode.getLeft().getCharacter());pQueue.add(newNode);}HFNode finalTree = pQueue.remove();Queue<HFNode> queue = new ArrayDeque<>();if (finalTree != null) {queue.add(finalTree);finalTree.getLeft().setCode("0");finalTree.getRight().setCode("1");}

4. 广度优先遍历,并将节点和编码以字典的形式保存,用于后面按照输入顺序对编码进行输出

Map<Character, String> dict = new HashMap<>();while (!queue.isEmpty()) {HFNode node = queue.remove();if (node.getLeft() != null)node.getLeft().setCode(node.getCode() + "0");if (node.getRight() != null)node.getRight().setCode(node.getCode() + "1");if (node.getLeft() != null) {queue.add(node.getLeft());}if (node.getRight() != null) {queue.add(node.getRight());}if (node.getLeft() == null && node.getRight() == null) {dict.put(node.character, node.code);}}

5. 按照输入顺序,将编码输出

进行大量字符串拼接时,stringBuilder性能更好。

StringBuilder string = new StringBuilder();for (int i = 0; i < chars.length; i++) {string.append(dict.get(chars[i]));}System.out.println(string);

Huffman(哈夫曼)编码及java实现相关推荐

  1. C++实现huffman哈夫曼编码的算法(附完整源码)

    C++实现huffman哈夫曼编码的算法 C++实现huffman哈夫曼编码的算法完整源码(定义,实现,main函数测试) C++实现huffman哈夫曼编码的算法完整源码(定义,实现,main函数测 ...

  2. 哈夫曼编码(java版+详细代码)

    哈夫曼编码: 根据数据出现的频率对数据进行编码,从而压缩原始数据. 例如对一个文本we年其中各种字符出现的次数; a:10 b:20 c:40 d:80 我们可以把啊,abcd,设为00,01,10, ...

  3. Huffman(哈夫曼)编码--又称最佳编码(最有效的二进制编码)

    2019独角兽企业重金招聘Python工程师标准>>> 在看一道Google笔试题时用到哈夫曼编码,于是去搜了下资料.题目如下: 用二进制来编码字符串"abcdabaa&q ...

  4. [源码和文档分享]C语言实现的基于Huffman哈夫曼编码的数据压缩与解压缩

    一.实验题目 用哈夫曼编码实现文件压缩 二.实验目的 了解文件的概念 掌握线性链表的插入.删除等算法 掌握Huffman树的概念及构造方法 掌握二叉树的存储结构及遍历算法 利用Huffman树及Huf ...

  5. 使用Java实现哈夫曼编码(Huffman Coding)

    文章目录 (一)需求分析 (二)构建哈夫曼树 (三)构建哈夫曼编码 (四)哈夫曼编码的解码 (五)哈夫曼编码压缩的原理 (六)总结 (七)Java代码实现哈夫曼树:构建节点类&二叉树类 (八) ...

  6. C#,哈夫曼编码(Huffman Code)压缩(Compress )与解压缩(Decompress)算法与源代码

    David A. Huffman 哈夫曼编码简史(Huffman code) 1951年,哈夫曼和他在MIT信息论的同学需要选择是完成学期报告还是期末考试.导师Robert M. Fano给他们的学期 ...

  7. 【数据结构】图解霍夫曼编码,看了就能懂

    今天来给大家普及一下霍夫曼编码(Huffman Coding),一种用于无损数据压缩的熵编码算法,由美国计算机科学家大卫·霍夫曼在 1952 年提出--这么专业的解释,不用问,来自维基百科了. 说实话 ...

  8. 【数据结构】-哈夫曼树以及哈夫曼编码

    哈夫曼树的几个定义 哈夫曼树又叫最优二叉树:特点是带权路径最短 带权路径长度:该结点到根结点的路径长度乘以该结点的权值. 树的带权路径长度(WPL):所有叶子结点到根结点的带全路径长度之和. 最优二叉 ...

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

    CSDN 的学弟学妹们,大家好,我是沉默王二. 今天来给大家普及一下霍夫曼编码(Huffman Coding),一种用于无损数据压缩的熵编码算法,由美国计算机科学家大卫·霍夫曼在 1952 年提出-- ...

  10. 电文的编码和译码,哈夫曼编码译码(C语言)

    内容: 从键盘接收一串电文字符,输出对应的Huffman(哈夫曼)编码,同时,能翻译由Huffman编码生成的代码串,输出对应的电文字符串.设计要求: (1)构造一棵Huffman树:         ...

最新文章

  1. Docker 之 Docker基础操作
  2. Request.ServerVariables完整参考
  3. neo4j查询节点与相应的边的方法
  4. python中not加变量是_MyPython--基础篇--变量
  5. java设计模式之设计原则⑥里氏代换原则
  6. lintcode 落单的数(位操作)
  7. weakhashmap_Java WeakHashMap putAll()方法与示例
  8. 深度学习(五十七)tensorflow andorid yolo物体检测测试
  9. java集合的扩容研究
  10. 太阳系混的最惨行星:被“降级”至今未归队
  11. OpenCV骨架提取代码
  12. Celery入门--定时任务的开发及运行
  13. DBA运维福音:10分钟,一行命令安装Oracle数据库
  14. 云原生 | Docker:基础篇
  15. 开发手札:Unity与Android交互
  16. #ArcGis中如何对属性表中的字段进行顺序赋值??
  17. 打印钻石图形python_Python pandas高效数据处理之绘图
  18. 史铁生散文《我与地坛》
  19. 红灯须硬闯,马路要横穿(文/王路)
  20. Mysql传智jing_dong数据库

热门文章

  1. 2016年计算机二级应用试题,计算机二级office真题及答案
  2. 微信支付的回调函数实现验签以及解密
  3. Image Segmentation论文学习翻译-SLIC Superpixels Compared to State-of-the-Art Superpixel Methods
  4. 程序员不能错过的28份技术知识图谱,你的进阶路上必备
  5. android plc 课程,基于Android的智能PLC操控软件设计与实现
  6. 数据预处理之数据清理,数据集成,数据规约,数据变化和离散化
  7. r星服务器在那个文件,gta5修改host文件连接r星服务器方法介绍
  8. 软考中级网络工程师知识点
  9. 2021年软考信息系统监理师考试知识点整理
  10. 【程序员猎奇】分享一个好东西给大家!