能夠用一個數組存放原來的n個葉子結點和構造過程當中臨時生成的結點,數組大小爲2n-1。因此,哈夫曼樹類中有兩個成員字段:data數組用於存放結點集合;leafNum表示哈夫曼樹葉子結點的數目。而哈夫曼樹結點一共有5個域:java
public class Node<T> implements Comparable<Node<T>> { @Override //肯定位置 public int compareTo(Node<T> other) { if(other.getWeight() > this.getWeight()){ return 1; } if(other.getWeight() < this.getWeight()){ return -1; } return 0; } }
public Node<T> createTree(List<Node<T>> nodes) { while (nodes.size() > 1) { Collections.sort(nodes); Node<T> left = nodes.get(nodes.size() - 2); left.setCode(0 + ""); Node<T> right = nodes.get(nodes.size() - 1); right.setCode(1 + ""); Node<T> parent = new Node<T>(null, left.getWeight() + right.getWeight()); parent.setLeft(left); parent.setRight(right); nodes.remove(left); nodes.remove(right); nodes.add(parent); } return nodes.get(0); }
public List<Node<T>> breadth(Node<T> root) { List<Node<T>> list = new ArrayList<Node<T>>(); Queue<Node<T>> queue = new ArrayDeque<Node<T>>(); 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()); Node<T> node = queue.poll(); if (node.getLeft() != null) node.getLeft().setCode(node.getCode() + "0"); if (node.getRight() != null) node.getRight().setCode(node.getCode() + "1"); if (node.getLeft() != null) { queue.offer(node.getLeft()); } if (node.getRight() != null) { queue.offer(node.getRight()); } } return list; }
char[] chars = 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', ' ','\n'}; 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, 0};
//獲得相應字符出現的次數 public void num(String string) { for (int i = 0; i < 28; i++) { int temp = 0; for (int j = 0; j < string.length(); j++) { if (string.charAt(j) == chars[i]) temp++; } number[i] += temp; } }
File file = new File("abc.txt"); Word read = new Word(); String temp = read.txtString(file); System.out.println(temp); int[] num = read.getNumber(); char[] chars = read.getChars(); for (int i = 0; i < 28; i++) { System.out.print(chars[i] + ":" + num[i] + " "); list.add(new Node<String>(chars[i] + "", num[i])); } Collections.sort(list); System.out.println();
顯示結果:node
HuffmanTree huffmanTree = new HuffmanTree(); Node<String> root = huffmanTree.createTree(list); list2 = huffmanTree.breadth(root); for (int i = 0; i < list2.size(); i++) { if (list2.get(i).getData() != null) { list3.add(list2.get(i).getData()); list4.add(list2.get(i).getCode()); } } for (int i = 0; i < list2.size(); i++) { num2 += list2.get(i).getWeight(); } for (int i = 0; i < list3.size(); i++) { System.out.println(list3.get(i) + "出現的機率爲" + list2.get(i).getWeight() / num2 + " "); } System.out.println();
顯示結果:git
for (int i = 0; i < list4.size(); i++) { System.out.println(list3.get(i) + "的編碼爲" + list4.get(i) + " "); } System.out.println();
顯示結果:數組
HuffmanTreeTest:對原文件進行編碼數據結構
for (int i = 0; i < temp.length(); i++) { for (int j = 0; j < list3.size(); j++) { if (temp.charAt(i) == list3.get(j).charAt(0)) result += list4.get(j); } } System.out.println("編碼後爲:" + result); for (int i = 0; i < result.length(); i++) { list5.add(result.charAt(i) + ""); }
顯示結果(太長了只截取了部分)ide
while (list5.size() > 0) { temp2 = temp2 + "" + list5.get(0); list5.remove(0); for (int i = 0; i < list4.size(); i++) { if (temp2.equals(list4.get(i))) { temp3 = temp3 + "" + list3.get(i); temp2 = ""; } } } System.out.println();
顯示結果this
File file2 = new File("abc1.txt"); Writer out = new FileWriter(file2); out.write(temp3); out.close();