标签:变量 接受 ade EAP res arraylist fileinput html return
HuffmanNode
类作为实现的基础,每个结点都包含一个六项内容:权值、结点代表字母、字母的编码、左孩子、右孩子和父结点,为了方便之后进行结点的比较,这里还重新编写了一下compareTo
方法。public int compareTo(HuffmanNode<T> o) {
if (this.getWeight() > o.getWeight()){
return -1;
}
else if (this.getWeight() < o.getWeight()){
return 1;
}
return 0;
}
HuffmanTree
类里有两个方法,第一个方法createTree
方法用于构造树,第二个方法BFS
方法是使用广度优先遍历来给每一个叶子结点进行编码。具体方法及步骤在代码中都已写明。public static HuffmanNode createTree(List<HuffmanNode<String>> nodes) {
while (nodes.size() > 1){
// 对数组进行排序
Collections.sort(nodes);
// 当列表中还有两个以上结点时,构造树
// 获取权值最小的两个结点
HuffmanNode left = nodes.get(nodes.size() - 2);
left.setCode(0 + "");
HuffmanNode right = nodes.get(nodes.size() - 1);
right.setCode(1 + "");
// 生成新的结点,新结点的权值为两个子节点的权值之和
HuffmanNode parent = new HuffmanNode(left.getWeight() + right.getWeight(), null);
// 使新结点成为父结点
parent.setLeft(left);
parent.setRight(right);
// 删除权值最小的两个结点
nodes.remove(left);
nodes.remove(right);
nodes.add(parent);
}
return nodes.get(0);
}
public static List<HuffmanNode> BFS(HuffmanNode root){
Queue<HuffmanNode> queue = new ArrayDeque<HuffmanNode>();
List<HuffmanNode> list = new java.util.ArrayList<HuffmanNode>();
if (root != null){
// 将根元素加入队列
queue.offer(root);
root.getLeft().setCode(root.getCode() + "0");
root.getRight().setCode(root.getCode() + "1");
}
while (!queue.isEmpty()){
// 将队列的队尾元素加入列表中
list.add(queue.peek());
HuffmanNode node = queue.poll();
// 如果左子树不为空,将它加入队列并编码
if (node.getLeft() != null){
queue.offer(node.getLeft());
node.getLeft().setCode(node.getCode() + "0");
}
// 如果右子树不为空,将它加入队列并编码
if (node.getRight() != null){
queue.offer(node.getRight());
node.getRight().setCode(node.getCode() + "1");
}
}
return list;
}
HuffmanMakeCode
类用于将文件中的内容提取,放入数组并进行计数,这里将数组长度设置为27,因为还对空格进行了计数,以便于解码。具体方法及步骤在代码中都已写明。public class HuffmanMakeCode {
public static char[] word = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s'
,'t','u','v','w','x','y','z',' '};
public static int[] number = new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
public static String makecode(FileInputStream stream) throws IOException {
//读取文件(缓存字节流)
BufferedInputStream in = new BufferedInputStream(stream);
//一次性取多少字节
byte[] bytes = new byte[2048];
//接受读取的内容(n就代表的相关数据,只不过是数字的形式)
int n = -1;
String a = null;
//循环取出数据
while ((n = in.read(bytes, 0, bytes.length)) != -1) {
//转换成字符串
a = new String(bytes, 0, n, "GBK");
}
// 对文件内容进行计数
count(a);
return a;
}
// 实现对文件内容计数,内层循环依次比较字符串中的每个字符与对应字符是否相同,相同时计数;外层循环指定对应字符从a至空格
public static void count(String str){
for (int i = 0;i < 27;i++){
int num = 0;
for (int j = 0;j < str.length();j++){
if (str.charAt(j) == word[i]){
num++;
}
}
number[i] += num;
}
}
public static char[] getWord() {
return word;
}
public static int[] getNumber() {
return number;
}
}
HuffmanTest
类进行了文件的读取,构造哈夫曼树,编码,解码,文件的写入五个步骤,其中前三个步骤使用之前三个类中的方法即可实现,这里主要说一下后两个步骤。// 进行解码
List<String> list4 = new ArrayList<>();
for (int i = 0;i < result.length();i++){
list4.add(result.charAt(i) + "");
}
String temp = "";
String temp1 = "";
while (list4.size() > 0){
temp += "" + list4.get(0);
list4.remove(0);
for (int i = 0;i < list3.size();i++){
if (temp.equals(list3.get(i))){
temp1 += "" + list2.get(i);
temp = "";
}
}
}
System.out.println("文件解码结果为: " + temp1);
// 写入文件
File file = new File("C:\\Users\\45366\\IdeaProjects\\fwq20172303_Programming\\HuffmanTest2.txt");
Writer out = new FileWriter(file);
out.write(result);
out.close();
20172303 2018-2019-1《程序设计与数据结构》哈夫曼树编码与解码
标签:变量 接受 ade EAP res arraylist fileinput html return
原文地址:https://www.cnblogs.com/PFrame/p/10111647.html