JAVA——赫夫曼编码-译码器(Huffman Coding)
生活随笔
收集整理的這篇文章主要介紹了
JAVA——赫夫曼编码-译码器(Huffman Coding)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基本概念
哈夫曼編碼(Huffman Coding):又稱霍夫曼編碼、赫夫曼編碼-,是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。Huffman于1952年提出一種編碼方法,該方法完全依據字符出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做Huffman編碼(有時也稱為霍夫曼編碼)。
源代碼?
HTNode.java?
package huffman;public class HTNode implements Comparable<HTNode> {int id;int weight;char code;int parent,lchild,rchild;public HTNode(int id) {this.id=id;this.weight=-1;this.code='\0';this.parent=-1;this.lchild=-1;this.rchild=-1;}public HTNode(int id,int weight) {this.id=id;this.weight=weight;this.code='\0';this.parent=-1;this.lchild=-1;this.rchild=-1;}public HTNode(int id,char code,int weight) {this.id=id;this.weight=weight;this.code=code;this.parent=-1;this.lchild=-1;this.rchild=-1;}public HTNode(int id,char code,int weight,int lchild,int rchild) {this.id=id;this.weight=weight;this.code=code;this.parent=-1;this.lchild=lchild;this.rchild=rchild;}public HTNode(int id,char code,int weight,int parent,int lchild,int rchild) {this.id=id;this.weight=weight;this.code=code;this.parent=parent;this.lchild=lchild;this.rchild=rchild;}public int compareTo(HTNode x) {if (x.weight < this.weight) {return 1;} else if (x.weight > this.weight) {return -1;}return 0;} }HuffmanTree.java
/*** */ package huffman;import java.util.*;/*** @author ShenTuZhiGang* @version 1.0* @since 1.0*/ public class HuffmanTree {private HTNode[] HT=null; private final int MAX_INDEX=128;private char[] code;private int[] weight;private int num;private int node_tot;private String[] HuffmanCodeList;private static final char[] default_code= {' ','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'};private static final int[] default_weight= {186,64,13,22,32,103,21,15,47,57,1,5,32,20,57,63,15,1,48,51,80,23,8,18,1,16,1}; private static final int default_num=27;/*** */public HuffmanTree() {create();}/*** @param code - 字符集* @param weight - 頻數*/public HuffmanTree(char[] code,int[] weight) {create(code,weight);}public void create() {// TODO 自動生成的方法存根create(default_code,default_weight);}/*** @param code - 字符集* @param weight - 頻數*/public void create(char[] code,int[] weight) {num=code.length; //獲取字符集字符總數node_tot=2*num-1; //總共需要2num-1個節點PriorityQueue<HTNode> Q = new PriorityQueue<HTNode>(); //優先隊列排序HT=new HTNode[node_tot+1];HT[0]=new HTNode(0);//給葉子結點賦值for(int i=1;i<=num;i++) {HT[i]=new HTNode(i,code[i-1],weight[i-1]);Q.add(HT[i]);}int id=num;//Huffman編碼while(Q.size()>=2) {//找到兩個權值最小的結點作為左右子樹的根節點構造新的二叉樹。HTNode s1=Q.remove();HTNode s2=Q.remove();id++;//創建新的節點//新節點的權值是兩個子節點之和HT[id]=new HTNode(id,'\0',s1.weight+s2.weight,s1.id,s2.id); s1.parent=s2.parent=id; //將兩個子節點的父節點設置為 id;//新節點重新放入隊列Q.add(HT[id]);}}/*** 從葉子到根逆向求每個字符的Huffman編碼*/public void createHuffmanCode() {int start,c,f;char[] cd=new char[num];HuffmanCodeList=new String[num+1]; //分配內存空間//依次對所有字符編碼for(int i=1; i<=num; i++){start=num;//從葉子到根逆向求編碼for(c=i,f=HT[i].parent;f!=-1;c=f,f=HT[f].parent) {if(HT[f].lchild==c) {cd[--start]='0';}else{cd[--start]='1';}}//復制編碼到Huffman編碼表HuffmanCodeList[i]=new String(cd,start,num-start);}}/*** @return HuffmanTreeString - HuffmanTree的字符串顯示形式(括號法)*/@Override public String toString() {return super.toString()+":[size="+node_tot+","+toBrackets(node_tot)+"]";}/*** @param code_str - 需要編碼的字符串* @return encode - 完成Huffman編碼的字符串*/public String enCode(String code_str) {int len=code_str.length();String encode=new String();//依次與所有字符編碼開始匹配for(int i=0;i<len;i++) {for(int j=1;j<=num;j++) {//匹配成功if(code_str.charAt(i)==HT[j].code ) {encode=encode+HuffmanCodeList[j];}}}return encode;}/*** @param code_str - 需要譯碼的字符串* @return encode - 完成Huffman譯碼的字符串*/public String deCode(String code_str) {int len=code_str.length();String decode=new String();String temp=new String();//依次與所有字符編碼開始匹配for(int i=0;i<len;i++) {temp=temp+code_str.charAt(i);for(int j=1;j<=num;j++) {//匹配成功if(HuffmanCodeList[j].equals(temp)) {decode=decode+HT[j].code;temp="";break;}}}return decode;}/*** 輸出每個字符的Huffman編碼*/public void printHuffmanCodeList() {print("字符集總數:"+HT.length);for(int i=1;i<=num;i++) {print("\'"+HT[i].code+"\':"+HuffmanCodeList[i]);}}/*** 調用{@link huffman.HuffmanTree#toBrackets(int) toBrackets(int root)}方法,生成HuffmanTree的括號法表示形式* 括號法顯示HuffmanTree* @return resstr - HuffmanTree的括號法表示形式*/public String printHuffmanTree() {return toBrackets(node_tot);}/*** 括號法顯示HuffmanTree* 遞歸法* @param root - HuffmanTree ROOT* @return resstr - HuffmanTree的括號法表示形式*/public String toBrackets(int root) {String resstr="";if(root!=-1){resstr+=(HT[root].code=='\0')?HT[root].weight:HT[root].code;if(HT[root].lchild!=-1||HT[root].rchild!=-1){resstr+="("+toBrackets(HT[root].lchild)+","+toBrackets(HT[root].rchild)+")";}}return resstr;}public static void print(Object obj) {System.out.println(obj);} }Main.java
/*** */ package huffman;/*** @author ShenTuZhiGang**/ public class Main {/*** @param args*/public static void main(String[] args) {// TODO 自動生成的方法存根HuffmanTree MyHT=new HuffmanTree();MyHT.createHuffmanCode();MyHT.printHuffmanCodeList();print(MyHT.enCode("THIS PROGRAME IS MY FAVORITE"));print(MyHT.deCode("1101000101100011111100001001010011000100010101011001001011111101100011111111110010100011111111110011101011000001001001001101101010"));print(MyHT.toString());print(MyHT.printHuffmanTree());}public static void print(Object obj) {System.out.println(obj);} }運行結果
參考文章
https://blog.csdn.net/Wood_Du/article/details/80366094
https://shentuzhigang.blog.csdn.net/article/details/103198604
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的JAVA——赫夫曼编码-译码器(Huffman Coding)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA Swing——框架(JFram
- 下一篇: Maven——Maven概述