一、需求

将给出的一段文本,比如 “i like like like java do you like a java” , 根据前面的讲的赫夫曼编码原理,对其进行数据压缩处理

二、步骤

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

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

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

编写方法,将准备构建赫夫曼树的Node放入List

通过list创建对应的赫夫曼树

1、创建赫夫曼树所需的节点Node

class Node implements Comparable {

Byte data;//存放数据 'a'=> 97

int weight;//权值:统计出现的次数

Node left;

Node right;

public Node(Byte data, int weight) {

this.data = data;

this.weight = weight;

}

/**

* 前序遍历

*/

public void preOder() {

System.out.println(this);

if (this.left != null) this.left.preOder();

if (this.right != null) this.right.preOder();

}

@Override

public String toString() {

return new StringJoiner(", ", Node.class.getSimpleName() + "[", "]")

.add("data=" + data)

.add("weight=" + weight)

.toString();

}

//根据权值从小到大排序

@Override

public int compareTo(Node o) {

return this.weight - o.weight;

}

}

2、得到字符串的byte数组

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

byte[] contentBytes = str.getBytes();

3、接受字节数组返回list

/**

* 接受字节数组返回list

* Node[data=32, weight=9],Node[data=100, weight=1].....

*

* @param bytes

* @return

*/

private static List getNodes(byte[] bytes) {

List list = new ArrayList<>();

//统计每个字符串出现的次数,使用map集合

HashMap map = new HashMap<>();

for (byte aByte : bytes) {

Integer count = map.get(aByte);

if (count == null) {//说明当前map中没有存入该字符

map.put(aByte, 1);

} else {//说明之前存入过

count++;

map.put(aByte, count);

}

}

//将map中的数据取出放入list中

for (Map.Entry entry : map.entrySet()) {

list.add(new Node(entry.getKey(), entry.getValue()));

}

return list;

}

4、通过list返回一棵赫夫曼树

通过list返回一棵赫夫曼树

/**

* 通过list返回一棵赫夫曼树

*

* @param list

* @return

*/

private static Node getHoffumanTree(List list) {

while (list.size() > 1) {

Collections.sort(list);

Node leftNode = list.get(0);

Node rightNode = list.get(1);

//通过取出的两个节点权重计算他们的根节点,root没有date

Node root = new Node(null, (leftNode.weight + rightNode.weight));

root.left = leftNode;

root.right = rightNode;

list.remove(leftNode);

list.remove(rightNode);

list.add(root);

}

return list.get(0);

}

5、生成赫夫曼树对应的赫夫曼编码表

将赫夫曼编码表存放在map集合中Map

形式:32->01 97->100 100->11000

在生成赫夫曼编码表时,拼接路径,创建StringBuilder存储某个叶子节点的路径

/**

* 重载,传一个根节点即可得到赫夫曼编码表

*

* @param node

*/

private static Map getCodes(Node node) {

if (node == null) return null;

getCodes(node,"",stringBuilder);

return hoffuCodes;

}

/*

* 生成霍夫曼树对应的赫夫曼编码表

* 1、将赫夫曼编码表存放在map集合中Map

* 形式:32->01 97->100 100->11000

* 2、在生成赫夫曼编码表时,拼接路径,创建StringBuilder存储某个叶子节点的路径

*/

static Map hoffuCodes = new HashMap<>();

static StringBuilder stringBuilder = new StringBuilder();

/**

* 功能:将传入的Node节点的所有叶子节点赫夫曼编码得到并存放到hoffumap中

*

* @param node 节点,默认根节点

* @param code 路径,左子节点为0,右子节点为1

* @param stringBuilder 拼接路径

*/

private static void getCodes(Node node, String code, StringBuilder stringBuilder) {

//进行字符串拼接

StringBuilder stringBuilder1 = new StringBuilder(stringBuilder);

stringBuilder1.append(code);

if (node != null) {

//if(node.data ==null) 不进行处理

if (node.data == null) {//说明时非叶子节点,继续寻找直到找到某一个叶子节点

//往左边查找

getCodes(node.left, "0", stringBuilder1);

//往右边查找

getCodes(node.right, "1", stringBuilder1);

} else {//如果当前已经为叶子节点,表示这个字符的赫夫曼编码已经产生,放入map集合中

hoffuCodes.put(node.data, stringBuilder1.toString());

}

}

}

生成赫夫曼树对应的赫夫曼编码 , 如下表:

=01 a=100 d=11000 u=11001 e=1110 v=11011 i=101

y=11010 j=0010 k=1111 l=000 o=0011

使用赫夫曼编码来生成赫夫曼编码数据 ,即按照上面的赫夫曼编码,将"i like like like java do you like a java"

字符串生成对应的编码数据, 形式如下.

10101000101111111100100010111111110010001011111111001001010011011100011100000110111010001111001010 00101111111100110001001010011011100

6、对赫夫曼树得到的二进制字符通过赫夫曼编码表进行数据压缩

利用赫夫曼编码表,将byte数组转成赫夫曼编码字符串

将生成的赫夫曼编码字符串装成byte[],8位一个byte

/**

* 使用一个方法封装

*

* @param contentBytes 原始的字符串byte

* @return 经过赫夫曼编码处理过后的编码,压缩过后的编码

*/

private static byte[] huffmanZip(byte[] contentBytes) {

List nodes = getNodes(contentBytes);

//1、创建赫夫曼树

Node hofumanNode = getHoffumanTree(nodes);

//2、根据赫夫曼数生成对应的赫夫曼编码

Map codes = getCodes(hofumanNode);

//3、根据赫夫曼编码对原始数据压缩,得到压缩后的字节码数组

byte[] zip = zip(contentBytes, codes);

return zip;

}

/**

* 编写一个方法,将字符串对应的byte[]数组,通过生成霍夫曼编码表,返回一个赫夫曼编码压缩过后的byte[]

*

* @param bytes 原始字符串对应的byte[]

* @param hoffuCodes 生成的赫夫曼编码表map

* @return 返回赫夫曼编码处理后的byte数组

* "i like like like java do you like a java" => byte[] contentBytes

* => 对应的byte[]hoffumanCodeByte,8位对应一个byte放入到hoffumanCodeByte

*/

private static byte[] zip(byte[] bytes, Map hoffuCodes) {

//1、利用赫夫曼编码表,将byte数组转成赫夫曼编码字符串

StringBuilder hoffmanSB = new StringBuilder();

//遍历byte

for (byte b : bytes) {

hoffmanSB.append(hoffuCodes.get(b));

}

//2、将生成的hoffmanSB装成byte[],8位一个byte

int len = 0;

if (hoffmanSB.length() % 8 == 0) {//长度刚好位8的整数

len = hoffmanSB.length() / 8;

} else {

len = hoffmanSB.length() / 8 + 1;

}

//简化:int length = (hoffmanSB.length() +7)/ 8 ;

//创建存储压缩后的byte[]

byte[] hoffumanByte = new byte[len];

int index = 0;//统计第多少个byte

for (int i = 0; i < hoffmanSB.length(); i += 8) {//8位一个byte,所以步长为8

String strByte;

if (i + 8 > hoffmanSB.length()) {//说明不够8位

strByte = hoffmanSB.substring(i);

} else {

strByte = hoffmanSB.substring(i, i + 8);

}

//将strByte转成byte放入到hoffumanByte

hoffumanByte[index] = (byte) Integer.parseInt(strByte);

index++;

}

return hoffumanByte;

}

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

java振动数据压缩_【数据结构-Java】最佳实践-数据压缩(使用赫夫曼树)相关推荐

  1. 数据结构与算法之Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树)

    目录 赫夫曼树概述 定义 构造赫夫曼树步骤 代码实现 赫夫曼树概述 HuffmanTree因为翻译不同所以有其他的名字:赫夫曼树.霍夫曼树.哈夫曼树 赫夫曼树又称最优二叉树,是一种带权路径长度最短的二 ...

  2. 【赫夫曼树数据结构及其应用】

    本文主要介绍Java中赫夫曼树数据结构的基本原理.实现方式以及使用场景.赫夫曼树(Huffman Tree)是一种带权路径最短的二叉树,广泛应用于数据压缩和编码等领域. 一.赫夫曼树的基本概念 赫夫曼 ...

  3. 【赫夫曼树详解】赫夫曼树简介及java代码实现-数据结构07

    赫夫曼树(最优二叉树) 1. 简介 定义: 赫夫曼树是n个带权叶子结点构成的所有二叉树中,带权路径长度(WPL)最小的二叉树. 叶子结点的带权路径: 叶子结点权值*到根节点的路径长度(叶结点的层数) ...

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

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

  5. 数据结构 - 赫夫曼树

    wpl最小的就是赫夫曼树(所有叶子节点的带权路径长度之和最小) 写出来两个节点连接,然后循环就可以了 package tree.huffmantree;import java.util.ArrayLi ...

  6. 数据结构与算法——赫夫曼树基本实现

    目录 一.赫夫曼树 1.1 基本介绍 1.2 赫夫曼树创建步骤图解 1.3  代码实现 二.赫夫曼编码 2.1 基本介绍 2.1.1  通讯领域 - 定长编码 - 举例说明 2.1.2  通讯领域 - ...

  7. 高级数据结构之赫夫曼树

    思考两个问题 电报发送:二战的时候大家都知道那时候普遍会应用电报,如果让你来设计一个电报的发送编码你该如何设计呢? 电报加密后越短越好,发送快. 破解难 解码容易 换加密树也要快 可逆的 压缩算法:给 ...

  8. 数据结构(十五)— 树结构之赫夫曼树及其应用

    现在我们都是讲究效率的社会,什么都要求速度, 在不能出错的情况下,做任何事情都讲究越快越好.在计算机和互联网技术中,文本压缩就是一个非常重要的技术. 玩电脑的人几乎都会应用压缩和解压缩软件来处理文档. ...

  9. 数据结构--赫夫曼树

    数据结构 –赫夫曼树 文章目录 数据结构 一.一些概念 二.最优二叉树(赫夫曼树) 三.赫夫曼树的构造 四.赫夫曼编码 五.前缀编码 一.一些概念 路径:从树中一个结点到另一个结点之间的分支构成这两个 ...

最新文章

  1. LINUX系统中进程如何管理控制(一)
  2. application配置token_Kerrigan:配置中心管理UI的实现思路和技术细节
  3. 微信小程序组件化 快速实现可用模态窗
  4. 网络嗅探混杂模式与非混杂模式的区别
  5. 「后端小伙伴来学前端了」Vuex原理图分析及结合生活案例让大家快速理解
  6. Jquery tmpl模板中if条件有多个时的写法
  7. NodeJs连接Mysql数据库
  8. JavaScript 对象与数组参考大全
  9. Java虚拟机栈介绍
  10. ASP连接sql server实例解析
  11. java Runtime
  12. oracle unlimit权限,有关UNLIMITED TABLESPACE权限
  13. Pycharm汉化包+操作步骤
  14. 浅谈易用性测试及GUI常见的测试要求
  15. 怎么学单片机,怎么入门
  16. 教你30分钟快速搭建直播间
  17. 社会语义网络图用什么软件绘制_GitMind:免费在线思维导图软件
  18. 天啦撸,联合开发网竟然倒闭了!!!(分享一个非常牛的人工智能教程!!!)
  19. excel 筛选 粘贴_在筛选的Excel列表中粘贴快捷方式
  20. linux 子接口 非vlan,VLAN之间通过子接口通信配置示例

热门文章

  1. Matlab中的lsqcurvefit函数的使用
  2. LeetCode刷题记录15——21. Merge Two Sorted Lists(easy)
  3. csgo怎么控制电脑玩家_图文详解电脑怎么发起远程控制
  4. CUDA+OpenCV实现光线追踪(有无constant)
  5. 怎么编写段错误(Segmentation fault)的程序
  6. portscaner 多线程、多协程并发端口扫描
  7. Docker将容器制作成镜像并提交到远程仓库
  8. ZooKeeper学习
  9. javascript数组排序和prototype详解
  10. 第一讲SQL命令的DDL和DML操作讲解