数据结构实验
实现哈夫曼树的编码与译码
主功能函数
//具体细节已经写在注释里面了
Java实现
package Haffman;
import java.io.*;
import java.util.*;
public class HuffMain {
public static void main(String[] args) {
String srcFile="D:\\test\\srcfile.txt";//要压缩的文件
String zipFile1="D:\\test\\b.txt";//压缩后的文件
zipFile(srcFile,zipFile1);//压缩函数
String dstFile="D:\\test\\dstfile.txt";//将压缩后的文件解压缩到新文件中\
// String srcFile="D:\\test\\beautiful.jpg";
//
// String zipFile1="D:\\test\\d.zip";
// zipFile(srcFile,zipFile1);
// String dstFile="D:\\test\\x.jpg";
unZipFile(zipFile1,dstFile);
}
/*
*
*将输入数据压缩,
* */
public static byte[] huffmanzip(byte[] bytes) {
List<HTreeNode> nodes = getNodes(bytes);//计算权重,创建每个结点,放在list集合里面.
HTreeNode<Object> tree = HuffmanTree.creatHuffTree(nodes);//根据每个结合的每个结点,创建哈夫曼树
Map<Object, String> HuffmanCodes = getCode(tree);//获取哈夫曼树的叶子结点的编码,键为data,值为编码。
byte[] zip = zip(bytes, huffmanCodes);//参数为data转换为字节后的data,huffmanCodes为哈夫曼树叶子结点的编码,返回值是一个压缩后的编码(byte数组)
return zip;
}
/*
* 将每个字节出现的频率统计出来,作为权值,将字节作为data,创建一个Node,再将所以的node放进一个list集合里面
*参数bytes数组,是将数据转化为字节后放进一个字节数组里面
* 返回值nodes是一个list集合,集合里面每个元素是一个结点,有data(字节类型)和权值
* */
private static List<HTreeNode> getNodes(byte[] bytes) {
ArrayList<HTreeNode> nodes = new ArrayList<>();
HashMap<Byte, Integer> Ma = new HashMap<>();
// 用map集合统计次数
for (byte a : bytes) {
Integer integer = Ma.get(a);//map集合的值是字节数组每个字节出现的频率,键就是每个字节
if (integer == null) {
Ma.put(a, 1);
} else {
Ma.put(a, integer + 1);
}
}
for (Map.Entry<Byte, Integer> entry : Ma.entrySet()) {
nodes.add(new HTreeNode(entry.getKey(), entry.getValue()));
}
return nodes;
}
/*
* 获取哈夫曼树叶子结点的编码
*
* */
private static Map<Object, String> huffmanCodes = new HashMap<>();
public static Map<Object, String> getCode(HTreeNode node) {
if (node == null) {
return null;
}
getCode(node.getLeft(),"0",new StringBuilder());
getCode(node.getRight(),"1",new StringBuilder());
return huffmanCodes