- 對給定的n個權值{W1,W2,W3,...,Wi,...,Wn}構成n棵二叉樹的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉樹Ti中只有一個權值爲Wi的根結點,它的左右子樹均爲空。(爲方便在計算機上實現算 法,通常還要求以Ti的權值Wi的升序排列。)
- 在F中選取兩棵根結點權值最小的樹做爲新構造的二叉樹的左右子樹,新二叉樹的根結點的權值爲其左右子樹的根結點的權值之和。
- 從F中刪除這兩棵樹,並把這棵新的二叉樹一樣以升序排列加入到集合F中。
- 重複上兩步的操做,直到集合F中只有一棵二叉樹爲止,即爲哈夫曼樹
public class HuffmanNode<T> implements Comparable<HuffmanNode<T>>{ private T letter; private double weight; private HuffmanNode lChild, rChild; private String code; public HuffmanNode(T letter, double weight){ this.letter = letter; this.weight = weight; code = ""; } public T getLetter() { return letter; } public double getWeight() { return weight; } public HuffmanNode getlChild() { return lChild; } public HuffmanNode getrChild() { return rChild; } public String getCode() { return code; } public void setLetter(T letter) { this.letter = letter; } public void setWeight(double weight) { this.weight = weight; } public void setlChild(HuffmanNode lChild) { this.lChild = lChild; } public void setrChild(HuffmanNode rChild) { this.rChild = rChild; } public void setCode(String code) { this.code = code; } @Override public String toString() { return "Huffman: " + letter + " 權值:" + weight + "編碼:" + code; } @Override public int compareTo(HuffmanNode<T> huffmanNode) { if(this.weight > huffmanNode.getWeight()) return -1; else return 1; } }
public HuffmanNode<T> createTree(List<HuffmanNode<T>> nodes) { while (nodes.size() > 1) { Collections.sort(nodes); HuffmanNode<T> left = nodes.get(nodes.size() - 2);//令其左孩子的編碼爲0 left.setCode("0"); HuffmanNode<T> right = nodes.get(nodes.size() - 1);//令其右孩子的編碼爲1 right.setCode("1"); HuffmanNode<T> parent = new HuffmanNode<T>(null, left.getWeight() + right.getWeight()); parent.setlChild(left); parent.setrChild(right); nodes.remove(left); nodes.remove(right); nodes.add(parent); } return nodes.get(0); }
public List<HuffmanNode<T>> breath(HuffmanNode<T> root) { List<HuffmanNode<T>> list = new ArrayList<HuffmanNode<T>>(); Queue<HuffmanNode<T>> queue = new LinkedList<>(); if (root != null) { queue.offer(root); root.getlChild().setCode(root.getCode() + "0"); root.getrChild().setCode(root.getCode() + "1"); } while (!queue.isEmpty()) { list.add(queue.peek()); HuffmanNode<T> node = queue.poll(); if (node.getlChild() != null) node.getlChild().setCode(node.getCode() + "0"); if (node.getrChild() != null) node.getrChild().setCode(node.getCode() + "1"); if (node.getlChild() != null) queue.offer(node.getlChild()); if (node.getrChild() != null) queue.offer(node.getrChild()); } return list; }
String result = ""; for(int f = 0; f < sum; f++){ for(int j = 0;j<letter.length;j++){ if(neirong.charAt(f) == letter[j].charAt(0)) result += code[j]; } }
for(int h = list4.size(); h > 0; h--){ string1 = string1 + list4.get(0); list4.remove(0); for(int i=0;i<code.length;i++){ if (string1.equals(code[i])) { string2 = string2+""+letter[i]; string1 = ""; } } }
Collections.frequency();
來實現,裏面的兩個形式參數,按照第二個形式參數表現的內容,記錄其在第一個列表內的重複次數,這樣只須要將文件內容一每一個字符的形式存放在一個列表中就行,而後進行比對便可。總的字符數目就是每個字母的重複次數。for(int a = 0; a <= getFileLineCount(file); a++){ String tp = bufferedReader.readLine(); neirong += tp; for(int b = 0; b < tp.length(); b++){ list2.add(String.valueOf(tp.charAt(b))); } Esum[0] += Collections.frequency(list2, list1.get(0)); Esum[1] += Collections.frequency(list2, list1.get(1)); Esum[2] += Collections.frequency(list2, list1.get(2)); Esum[3] += Collections.frequency(list2, list1.get(3)); Esum[4] += Collections.frequency(list2, list1.get(4)); Esum[5] += Collections.frequency(list2, list1.get(5)); Esum[6] += Collections.frequency(list2, list1.get(6)); Esum[7] += Collections.frequency(list2, list1.get(7)); Esum[8] += Collections.frequency(list2, list1.get(8)); Esum[9] += Collections.frequency(list2, list1.get(9)); Esum[10] += Collections.frequency(list2, list1.get(10)); Esum[11] += Collections.frequency(list2, list1.get(11)); Esum[12] += Collections.frequency(list2, list1.get(12)); Esum[13] += Collections.frequency(list2, list1.get(13)); Esum[14] += Collections.frequency(list2, list1.get(14)); Esum[15] += Collections.frequency(list2, list1.get(15)); Esum[16] += Collections.frequency(list2, list1.get(16)); Esum[17] += Collections.frequency(list2, list1.get(17)); Esum[18] += Collections.frequency(list2, list1.get(18)); Esum[19] += Collections.frequency(list2, list1.get(19)); Esum[20] += Collections.frequency(list2, list1.get(20)); Esum[21] += Collections.frequency(list2, list1.get(21)); Esum[22] += Collections.frequency(list2, list1.get(22)); Esum[23] += Collections.frequency(list2, list1.get(23)); Esum[24] += Collections.frequency(list2, list1.get(24)); Esum[25] += Collections.frequency(list2, list1.get(25)); Esum[26] += Collections.frequency(list2, list1.get(26)); Esum[27] += Collections.frequency(list2, list1.get(27)); Esum[28] += Collections.frequency(list2, list1.get(28)); }
for(int c = 0; c < Esum.length; c++) sum += Esum[c]; System.out.println("總字母個數:" + sum);
在此部分我用了一個能夠肯定文件內容行數的方法,便於當文件出現多行的時候的讀寫和編碼、解碼的相關操做。html
File file = new File("英文文件.txt"); File file1 = new File("編碼文件.txt"); File file2 = new File("解碼文件.txt"); if (!file1.exists() && !file2.exists()) { file1.createNewFile(); file2.createNewFile(); } FileReader fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(fileReader); FileWriter fileWriter1 = new FileWriter(file1); FileWriter fileWriter2 = new FileWriter(file2); fileWriter1.write(result); fileWriter2.write(string2); fileWriter1.close(); fileWriter2.close();