代码展示

节点类

package demo9;public class Node implements Comparable<Node>{Byte data;int weight;Node left;Node right;public Node(Byte data,int weight){this.data = data;this.weight = weight;}@Overridepublic String toString() {return "Node{" + "data=" + data + ", weight=" + weight + '}';}@Overridepublic int compareTo(Node o) {return o.weight-this.weight;}
}

测试类

package demo9;import java.util.*;public class TestHuffmanCode {public static void main(String[] args) {String msg="can you can a can as a can canner can a can.";byte[] bytes = msg.getBytes();//进行赫夫曼编码压缩byte[] b = huffmanZip(bytes);
//        System.out.println(bytes.length);
//        System.out.println(b.length);//使用赫夫曼编码进行解码byte[] newBytes = decode(huffCodes,b);System.out.println(new String(newBytes));}/*** 使用指定的赫夫曼编码表进行解码* @param huffCodes* @param bytes* @return*/private static byte[] decode(Map<Byte, String> huffCodes, byte[] bytes) {StringBuilder sb = new StringBuilder();//把byte数组转为一个二进制的字符串for(int i=0;i<bytes.length;i++){byte b = bytes[i];//是否是最后一个boolean flag = (i==bytes.length-1);sb.append(byteToBitStr(!flag,b));}//把字符串按照指定的赫夫曼编码进行解码//把赫夫曼编码的键值对进行调换Map<String,Byte> map = new HashMap<>();for(Map.Entry<Byte,String> entry:huffCodes.entrySet()){map.put(entry.getValue(),entry.getKey());}//创建一个集合,用于存byteList<Byte> list = new ArrayList<>();//处理字符串for(int i=0;i<sb.length();){int count=1;boolean flag = true;Byte b = null;//截取出一个bytewhile(flag){String key = sb.substring(i,i+count);b = map.get(key);if(b==null){count++;}else{flag=false;}}list.add(b);i+=count;}//把集合转为数组byte[] b = new byte[list.size()];for(int i=0;i<b.length;i++){b[i]=list.get(i);}return b;}private static String byteToBitStr(boolean flag,byte b){int temp=b;if(flag){temp|=256;}String str = Integer.toBinaryString(temp);if(flag){return str.substring(str.length()-8);}else{return str;}}/*** 进行赫夫曼编码压缩的方法* @param bytes* @return*/private static byte[] huffmanZip(byte[] bytes) {//先统计每一个byte出现的次数,并放入一个集合中List<Node> nodes = getNodes(bytes);//创建一棵赫夫曼树Node tree = createHuffmanTree(nodes);//创建一个赫夫曼编码表Map<Byte,String> huffCodes = getCodes(tree);//编码byte[] b = zip(bytes,huffCodes);return b;}/*** 进行赫夫曼编码* @param bytes* @param huffCodes* @return*/private static byte[] zip(byte[] bytes, Map<Byte, String> huffCodes) {StringBuilder sb =new StringBuilder();//把需要压缩的byte数组处理成一个二进制的字符串for(byte b:bytes){sb.append(huffCodes.get(b));}//定义长度int len;if(sb.length()%8==0){len=sb.length()/8+1;}else{len=sb.length()/8+1;}
//        System.out.println(sb.toString());//用于存储压缩后的bytebyte[] by = new byte[len];//记录新byte的位置int index = 0;for(int i=0;i<sb.length();i+=8){String strByte;if(i+8>sb.length()){strByte = sb.substring(i);}else{strByte = sb.substring(i, i+8);}byte byt = (byte)Integer.parseInt(strByte,2);
//            System.out.println(strByte+":"+byt);by[index]=byt;index++;}return by;}//用于临时存储路径static StringBuilder sb = new StringBuilder();//用于存储赫夫曼编码static Map<Byte,String> huffCodes = new HashMap<>();/*** 根据赫夫曼树获取赫夫曼编码* @param tree* @return*/private static Map<Byte, String> getCodes(Node tree) {if(tree==null){return null;}getCodes(tree.left,"0",sb);getCodes(tree.right,"1",sb);return huffCodes;}private static void getCodes(Node node, String code, StringBuilder sb) {StringBuilder sb2 = new StringBuilder(sb);sb2.append(code);if(node.data==null){getCodes(node.left,"0",sb2);getCodes(node.right,"1",sb2);}else{huffCodes.put(node.data,sb2.toString());}}/*** 创建赫夫曼树* @param nodes* @return*/private static Node createHuffmanTree(List<Node> nodes) {while(nodes.size()>1){//排序Collections.sort(nodes);//取出两个权值最低的二叉树Node left = nodes.get(nodes.size()-1);Node right = nodes.get(nodes.size()-2);//创建一棵新的二叉树Node parent = new Node(null,left.weight+right.weight);//把之前取出来的两棵二叉树设置为新创建的二叉树的子树parent.left=left;parent.right=right;//把前面取出来的两棵二叉树删除nodes.remove(left);nodes.remove(right);//把新创建的二叉树放入集合中nodes.add(parent);}return nodes.get(0);}/*** 把byte数组转为node集合* @param bytes* @return*/private static List<Node> getNodes(byte[] bytes) {List<Node> nodes = new ArrayList<>();Map<Byte,Integer> counts = new HashMap<>();//统计每一个byte出现的次数for(byte b:bytes){Integer count = counts.get(b);if(count==null){counts.put(b,1);}else{counts.put(b,count+1);}}//把每一个键值对转为一个node对象for(Map.Entry<Byte, Integer> entry:counts.entrySet()){nodes.add(new Node(entry.getKey(),entry.getValue()));}return nodes;}
}

使用赫夫曼编码进行解码相关推荐

  1. 算法 - 赫夫曼编码(对字符串进行压缩 与 解压(解码)) - (对文件进行压缩解压)

    1.压缩:使用赫夫曼编码进行压缩 题目 构建赫夫曼树 package tree.huffmantree;import java.util.*;public class HuffmanCode {pub ...

  2. 《数据结构与算法》课程设计报告——赫夫曼编码/译码器

    题目 赫夫曼编码/译码器 实验目的 本课程设计是为了让同学们了解学习数据结构的作用和意义.数据结构是计算机科学与技术专业的专业基础课,是十分重要的课程.所有的计算机系统软件和应用软件都要用到各种类型的 ...

  3. 利用赫夫曼编码进行数据解压

    基本概念 代码实现 package com.atguigu.huffmancode;import com.sun.org.glassfish.external.statistics.CountStat ...

  4. 数据结构第二次实验-赫夫曼编码及其应用

    一.实验目的 1.目的:掌握赫夫曼(Huffman)树和赫夫曼编码的基本思想和应用. 2.任务:实现文件中数据的加解密与压缩. 二.实验内容及要求 1.任务描述 实验内容:将硬盘上的一个文本文件进行 ...

  5. 赫夫曼树以及赫夫曼编码实现

    介绍 赫夫曼树创建图解思路 一直找就找到最好的样子: 赫夫曼树创建代码实现 package 树;import java.util.ArrayList; import java.util.Collect ...

  6. 数据结构与算法(赫夫曼树,赫夫曼编码)

    赫夫曼树 基本介绍: (1)给定n个权值作为n给叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树(HuffmanTree),还有的树翻译为霍夫 ...

  7. 数据结构:赫夫曼编码

    目录 1. 基本介绍 2. 原理剖析 2.1 通信领域中信息的处理方式1-定长编码 2.2 通信领域中信息的处理方式2-变长编码 2.3 通信领域中信息的处理方式3-赫夫曼编码 3. 数据压缩(创建赫 ...

  8. 用赫夫曼树进行文件解压

    思路分析 代码实现 package com.atguigu.huffmancode;import com.sun.org.glassfish.external.statistics.CountStat ...

  9. 用赫夫曼树进行文件的压缩

    思路分析 代码实现 package com.atguigu.huffmancode;import com.sun.org.glassfish.external.statistics.CountStat ...

最新文章

  1. tarjan算法不是很懂先mark一下。
  2. 国外centos服务器配置epel源
  3. MPI编程及性能优化
  4. JAVA学习笔记-Scanner的使用
  5. python OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized
  6. TypeError: ‘builtin_function_or_method‘ object is not subscriptable 报错解决方法
  7. Linux中创建一个不能登录的用户useradd
  8. 软考之软件设计师之第一战计算机系统概论重点和坑
  9. 大漠多账号循环登录任务自动切换模板大漠绑定后台绑定游戏
  10. 前端初级学习阶段(3)
  11. wordpress个人博客申请Let’s Encrypt免费SSL证书
  12. 神龙X-Dragon,这技术“范儿”如何?
  13. 购物栏置底 - uni-ui组件uni-goods-nav放在屏幕下方的办法
  14. linux,rpm, tar, gz, bz, bz2, rar, zip, lha, deb, 解压
  15. 【目标检测】轻量级网络SqueezeNet
  16. 华硕服务器系统都还原不了,windows10系统还原失败怎么办|windows10系统还原失败如何解决...
  17. 高数---曲线积分和曲面积分
  18. 3D卷积网络论文阅读笔记
  19. 计算机无法选择管理,此电脑右键“管理”无法打开怎么办?
  20. java web图片旋转_修正web项目中图片旋转方向

热门文章

  1. 这年头能真正掌握Javaassist技术的程序员真不多
  2. 【数据库】对象名称 'dbo.student' 和索引名称 'stusage' 有重复的键
  3. Linux下GPT分区,gdisk修复损坏的分区表
  4. 国外 android 手机,Android手机浏览器(国外篇)横向对比评测
  5. 五种有效的学习方法 – 方法比努力重要
  6. GPS手机射频的一些测试项目
  7. 按降序显示奇数python_程序在Python中分别以升序和降序对所有偶数和奇数进行排序...
  8. 怎么删除计算机c盘应用,怎样删除电脑c盘中的垃圾
  9. uni-app - 苹果安卓系统监听物理返回按键(手机左滑返回监听)
  10. 《数值分析》-- 数值积分