Day579&580.霍夫曼编码 -数据结构和算法Java
Posted 阿昌喜欢吃黄桃
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day579&580.霍夫曼编码 -数据结构和算法Java相关的知识,希望对你有一定的参考价值。
霍夫曼编码
一、介绍
利用霍夫曼树,来构建或形成的一种编码【程序算法
】
二、原理剖析
1、定长编码
通过英文对照转换为Ascii码对应的二进制
2、变长编码
根据字符出现的次数,来规定对应的二进制值,出现的越多,二进制值越小,并最后根据数值对应转化
存在匹配的多异性
3、霍夫曼编码(无损压缩)
统计各个字符出现的个数,根据出现的字符出现的次数来构建一颗霍夫曼数
,次数作为权值;
根据上面构建的霍夫曼树,给一个个字符构建编码,树中朝左边的为0,朝右边的为1
,他是前缀编码
- 注意点
当对应字符出现的次数一样的情况,会出现霍夫曼编码不完全一样的情况
三、实现案例需求
四、思路分析
五、代码实现
package com.achang.hufumancode;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 霍夫曼编码
*/
public class HuffmanCode
static HashMap<Byte, String> huffManCodeMap = new HashMap<>();
static StringBuffer sb = new StringBuffer();
public static void main(String[] args)
String msg = "i like like like java do you like a java";
byte[] strBytes = msg.getBytes(StandardCharsets.UTF_8);
System.out.println("未压缩长度为:" + strBytes.length);
List<Node> nodes = getNodes(strBytes);
System.out.println(nodes);
Node huffmanTreeNode = buildHuffmanTree(nodes);
System.out.println("霍夫曼树的前序遍历:↓");
huffmanTreeNode.preOrder();
getCodes(huffmanTreeNode);
System.out.println("======生成的霍夫曼编码表:↓=======");
System.out.println(huffManCodeMap);
static HashMap<Byte, String> getCodes(Node nodeRoot)
if (nodeRoot == null)
return null;
else
getCodes(nodeRoot.left,"",sb);
getCodes(nodeRoot.right,"",sb);
return huffManCodeMap;
//生成霍夫曼树对应的霍夫曼编码
static void getCodes(Node node,String code,StringBuffer sb)
StringBuffer stringBuffer = new StringBuffer(sb);
stringBuffer.append(code);
if (node != null)
if (node.data == null)//非叶子节点
getCodes(node.left,"0",stringBuffer);//向左递归
getCodes(node.right,"1",stringBuffer);//向右递归
else //叶子节点
huffManCodeMap.put(node.data,stringBuffer.toString());
//获取对应数组对应字符出现的次数,并转成Node节点的集合
static List<Node> getNodes(byte[] strBytes)
ArrayList<Node> nodes = new ArrayList<>();
HashMap<Byte, Integer> countMap = new HashMap<>();
for (byte strByte : strBytes)
Integer count = countMap.get(strByte);
if (count == null)
count = 1;
else
count++;
countMap.put(strByte, count);
for (Map.Entry<Byte, Integer> byteIntegerEntry : countMap.entrySet())
nodes.add(new Node(byteIntegerEntry.getKey(), byteIntegerEntry.getValue()));
return nodes;
//构建霍夫曼树
static Node buildHuffmanTree(List<Node> list)
while (list.size() > 1)
Collections.sort(list);
Node leftNode = list.get(0);
Node rightNode = list.get(1);
//根节点只有权值,没有data
Node parent = new Node(null, leftNode.weight + rightNode.weight);
parent.left = leftNode;
parent.right = rightNode;
list.remove(leftNode);
list.remove(rightNode);
list.add(parent);
return list.get(0);
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;
@Override
public int compareTo(Node o)
//从小到大排序
return this.weight - o.weight;
@Override
public String toString()
return "Node【data=" + data + ",weight=" + weight + "】";
//前序遍历
public void preOrder()
System.out.println(this);
if (left != null)
this.left.preOrder();
if (right != null)
this.right.preOrder();
以上是关于Day579&580.霍夫曼编码 -数据结构和算法Java的主要内容,如果未能解决你的问题,请参考以下文章