如何用java是实现哈夫曼编码
时间: 2023-07-19 08:09:54 浏览: 37
哈夫曼编码是一种无损数据压缩算法,它将出现频率较高的字符用较短的编码表示,而出现频率较低的字符用较长的编码表示。下面是一个简单的Java实现:
首先,我们需要定义一个节点类,表示哈夫曼树的节点,包含字符、权重、左右子节点等信息:
```java
class HuffmanNode {
char ch;
int freq;
HuffmanNode left, right;
public HuffmanNode(char ch, int freq) {
this.ch = ch;
this.freq = freq;
}
}
```
接下来,我们需要构建哈夫曼树。首先,我们需要统计每个字符出现的频率,然后将每个字符作为一个单独的节点插入一个最小堆中,每次弹出两个权重最小的节点,合并成一个新节点,并将新节点插入最小堆中,直到最小堆中只剩下一个节点,即为哈夫曼树的根节点。
```java
public static HuffmanNode buildHuffmanTree(char[] chars, int[] freqs) {
PriorityQueue<HuffmanNode> pq = new PriorityQueue<>((a, b) -> a.freq - b.freq);
for (int i = 0; i < chars.length; i++) {
pq.offer(new HuffmanNode(chars[i], freqs[i]));
}
while (pq.size() > 1) {
HuffmanNode left = pq.poll();
HuffmanNode right = pq.poll();
HuffmanNode parent = new HuffmanNode('\0', left.freq + right.freq);
parent.left = left;
parent.right = right;
pq.offer(parent);
}
return pq.poll();
}
```
接下来,我们需要生成每个字符对应的哈夫曼编码。从根节点开始,左子树路径上添加0,右子树路径上添加1,直到找到叶子节点,即为对应字符的哈夫曼编码。我们可以使用递归的方式生成编码。
```java
public static void generateCodes(HuffmanNode root, String code, Map<Character, String> codes) {
if (root == null) {
return;
}
if (root.left == null && root.right == null) {
codes.put(root.ch, code);
return;
}
generateCodes(root.left, code + "0", codes);
generateCodes(root.right, code + "1", codes);
}
```
最后,我们可以将原始数据按照哈夫曼编码进行压缩。将每个字符替换成对应的编码,然后将编码拼接起来,即可得到压缩后的数据。
```java
public static String compress(String data, Map<Character, String> codes) {
StringBuilder sb = new StringBuilder();
for (char ch : data.toCharArray()) {
sb.append(codes.get(ch));
}
return sb.toString();
}
```
完整的代码如下:
```java
import java.util.*;
class HuffmanNode {
char ch;
int freq;
HuffmanNode left, right;
public HuffmanNode(char ch, int freq) {
this.ch = ch;
this.freq = freq;
}
}
public class HuffmanCoding {
public static void main(String[] args) {
String data = "hello world";
char[] chars = data.toCharArray();
int[] freqs = new int[256];
for (char ch : chars) {
freqs[ch]++;
}
HuffmanNode root = buildHuffmanTree(chars, freqs);
Map<Character, String> codes = new HashMap<>();
generateCodes(root, "", codes);
String compressed = compress(data, codes);
System.out.println(compressed);
}
public static HuffmanNode buildHuffmanTree(char[] chars, int[] freqs) {
PriorityQueue<HuffmanNode> pq = new PriorityQueue<>((a, b) -> a.freq - b.freq);
for (int i = 0; i < chars.length; i++) {
pq.offer(new HuffmanNode(chars[i], freqs[i]));
}
while (pq.size() > 1) {
HuffmanNode left = pq.poll();
HuffmanNode right = pq.poll();
HuffmanNode parent = new HuffmanNode('\0', left.freq + right.freq);
parent.left = left;
parent.right = right;
pq.offer(parent);
}
return pq.poll();
}
public static void generateCodes(HuffmanNode root, String code, Map<Character, String> codes) {
if (root == null) {
return;
}
if (root.left == null && root.right == null) {
codes.put(root.ch, code);
return;
}
generateCodes(root.left, code + "0", codes);
generateCodes(root.right, code + "1", codes);
}
public static String compress(String data, Map<Character, String> codes) {
StringBuilder sb = new StringBuilder();
for (char ch : data.toCharArray()) {
sb.append(codes.get(ch));
}
return sb.toString();
}
}
```