Java掌握哈夫曼树、哈夫曼编码的概念和基本理论,设计实现哈夫曼编码。
时间: 2023-07-03 12:08:33 浏览: 49
哈夫曼树是一种二叉树,它的叶子节点表示待编码的字符,每个字符对应一个权值(出现频率),哈夫曼树的根节点到每个叶子节点的路径表示该字符的编码,路径上0表示左子树,1表示右子树,路径上的0和1组成的编码是唯一的。
哈夫曼编码是通过哈夫曼树来实现的,对于给定的字符集合和权值,通过构造哈夫曼树,可以得到每个字符的编码。编码的长度是最短的,这样可以减小存储和传输的数据量,提高传输效率。
下面是Java实现哈夫曼编码的示例代码:
```java
import java.util.*;
public class HuffmanCoding {
// 定义哈夫曼树节点
private static class Node implements Comparable<Node> {
byte ch; // 字符
int freq; // 频率
Node left, right; // 左、右孩子
public Node(byte ch, int freq) {
this.ch = ch;
this.freq = freq;
}
public boolean isLeaf() {
return left == null && right == null;
}
// 按照频率比较大小
public int compareTo(Node other) {
return this.freq - other.freq;
}
}
// 构造哈夫曼树
private static Node buildHuffmanTree(Map<Byte, Integer> freqMap) {
PriorityQueue<Node> pq = new PriorityQueue<>();
for (Map.Entry<Byte, Integer> entry : freqMap.entrySet()) {
pq.offer(new Node(entry.getKey(), entry.getValue()));
}
while (pq.size() > 1) {
Node left = pq.poll();
Node right = pq.poll();
Node parent = new Node((byte) 0, left.freq + right.freq);
parent.left = left;
parent.right = right;
pq.offer(parent);
}
return pq.poll();
}
// 生成字符编码表
private static Map<Byte, String> generateCodeTable(Node root) {
Map<Byte, String> codeTable = new HashMap<>();
generateCodeTable(root, "", codeTable);
return codeTable;
}
// 递归生成字符编码
private static void generateCodeTable(Node node, String code, Map<Byte, String> codeTable) {
if (node == null) {
return;
}
if (node.isLeaf()) {
codeTable.put(node.ch, code);
}
generateCodeTable(node.left, code + "0", codeTable);
generateCodeTable(node.right, code + "1", codeTable);
}
// 对原始数据进行哈夫曼编码
public static byte[] encode(byte[] data) {
Map<Byte, Integer> freqMap = new HashMap<>();
for (byte b : data) {
freqMap.put(b, freqMap.getOrDefault(b, 0) + 1);
}
Node root = buildHuffmanTree(freqMap);
Map<Byte, String> codeTable = generateCodeTable(root);
StringBuilder sb = new StringBuilder();
for (byte b : data) {
sb.append(codeTable.get(b));
}
String codeStr = sb.toString();
int padding = 8 - codeStr.length() % 8; // 补齐位数
for (int i = 0; i < padding; i++) {
codeStr += "0";
}
byte[] codeBytes = new byte[codeStr.length() / 8];
for (int i = 0; i < codeBytes.length; i++) {
codeBytes[i] = (byte) Integer.parseInt(codeStr.substring(i * 8, i * 8 + 8), 2);
}
return codeBytes;
}
// 对哈夫曼编码进行解码
public static byte[] decode(byte[] codeBytes, Node root) {
StringBuilder sb = new StringBuilder();
for (byte b : codeBytes) {
String binaryStr = Integer.toBinaryString((b & 0xFF) | 0x100).substring(1);
sb.append(binaryStr);
}
String codeStr = sb.toString();
List<Byte> result = new ArrayList<>();
Node node = root;
for (char c : codeStr.toCharArray()) {
if (c == '0') {
node = node.left;
} else if (c == '1') {
node = node.right;
}
if (node.isLeaf()) {
result.add(node.ch);
node = root;
}
}
byte[] data = new byte[result.size()];
for (int i = 0; i < data.length; i++) {
data[i] = result.get(i);
}
return data;
}
}
```
使用示例:
```java
public class Main {
public static void main(String[] args) {
String str = "Hello, world!";
byte[] data = str.getBytes();
byte[] codeBytes = HuffmanCoding.encode(data);
Node root = HuffmanCoding.buildHuffmanTree(HuffmanCoding.countFreq(data));
byte[] decoded = HuffmanCoding.decode(codeBytes, root);
System.out.println(new String(decoded)); // Hello, world!
}
}
```
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)