10: java資料結構和演算法: 構建哈夫曼樹, 獲取哈夫曼編碼, 使用哈夫曼編碼原理對檔案壓縮和解壓
阿新 • • 發佈:2020-07-24
最終結果哈夫曼樹,如圖所示:
直接上程式碼:
public class HuffmanCode { public static void main(String[] args) { //獲取哈夫曼樹並顯示 Hnode root = createHuffmanTree(createNodes()); root.beforePrint(); System.out.println("===================="); //從哈夫曼樹中讀取 哈夫曼編碼 getHuffmanCode(root); //從huffmanCodes 中讀取哈夫曼編碼:A:10, B:01, C:0011,D:11,E:000,F:00100,G:00101 System.out.println("哈夫曼編碼為:"+huffmanCodes); } //建立一個 Hnode節點的集合 public static List<Hnode> createNodes(){ List<Hnode> nodes = new ArrayList<Hnode>(); nodes.add(new Hnode(new Person(12,"A"),60)); nodes.add(new Hnode(new Person(13,"B"),45)); nodes.add(new Hnode(new Person(14,"C"),13)); nodes.add(new Hnode(new Person(15,"D"),69)); nodes.add(new Hnode(new Person(16,"E"),14)); nodes.add(new Hnode(new Person(17,"F"),5)); nodes.add(new Hnode(new Person(18,"G"),3)); return nodes; } //根據list 建立哈夫曼樹 public static Hnode createHuffmanTree(List<Hnode> nodes){ while(nodes.size() > 1){ //先對 nodes進行從小到大排序, 根據權重值進行從小到大排序 Collections.sort(nodes, new Comparator<Hnode>() { public int compare(Hnode o1, Hnode o2) { return o1.weight - o2.weight; } }); //取出前二個最小的元素,構建一個父節點只有權重 沒有資料的二叉樹 Hnode leftNode = nodes.get(0); Hnode rightNode = nodes.get(1); Hnode parent = new Hnode(null, leftNode.weight + rightNode.weight); parent.leftNode = leftNode; parent.rightNode = rightNode; //將原來nodes中已經處理的前二個最小元素刪除調,並將parent節點存入nodes中 nodes.remove(leftNode); nodes.remove(rightNode); nodes.add(parent); } //迴圈結束時候,nodes中只有一個節點了,且該節點就是哈夫曼樹的根節點 return nodes.get(0); } static StringBuilder stringBuilder = new StringBuilder(); static Map<String,String> huffmanCodes = new HashMap<String, String>(); //從哈夫曼樹中讀取 哈夫曼編碼: A:10, B:01, C:0011,D:11,E:000,F:00100,G:00101 public static void getHuffmanCode(Hnode root){ if (root == null) { return ; } getCode(root.leftNode,"0",stringBuilder); getCode(root.rightNode,"1",stringBuilder); } private static void getCode(Hnode node, String code, StringBuilder builder) { StringBuilder builder1 = new StringBuilder(builder); builder1.append(code); if (node != null) { if (node.person == null) { //如果資料為不null,說明是子節點 //左遞迴處理 getCode(node.leftNode,"0",builder1); //右遞迴處理 getCode(node.rightNode,"1",builder1); }else{ //如果資料為null,說明是葉子節點 huffmanCodes.put(node.person.name,builder1.toString()); } } } } //先建節點 class Hnode{ Person person;//資料 int weight;//權重 Hnode leftNode; Hnode rightNode; public Hnode(Person person, int weight) { this.person = person; this.weight = weight; } @Override public String toString() { return "Hnode{" + "data='" + person + '\'' + ", weight=" + weight + '}'; } //前序遍歷 public void beforePrint(){ System.out.println(this); if (this.leftNode != null) { this.leftNode.beforePrint(); } if (this.rightNode != null) { this.rightNode.beforePrint(); } } } class Person { int age; String name; public Person(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
結果如下: