日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA——赫夫曼编码-译码器(Huffman Coding)

發(fā)布時間:2024/10/5 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA——赫夫曼编码-译码器(Huffman Coding) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基本概念

哈夫曼編碼(Huffman Coding):又稱霍夫曼編碼、赫夫曼編碼-,是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。Huffman于1952年提出一種編碼方法,該方法完全依據(jù)字符出現(xiàn)概率來構(gòu)造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做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 - 頻數(shù)*/public HuffmanTree(char[] code,int[] weight) {create(code,weight);}public void create() {// TODO 自動生成的方法存根create(default_code,default_weight);}/*** @param code - 字符集* @param weight - 頻數(shù)*/public void create(char[] code,int[] weight) {num=code.length; //獲取字符集字符總數(shù)node_tot=2*num-1; //總共需要2num-1個節(jié)點PriorityQueue<HTNode> Q = new PriorityQueue<HTNode>(); //優(yōu)先隊列排序HT=new HTNode[node_tot+1];HT[0]=new HTNode(0);//給葉子結(jié)點賦值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) {//找到兩個權(quán)值最小的結(jié)點作為左右子樹的根節(jié)點構(gòu)造新的二叉樹。HTNode s1=Q.remove();HTNode s2=Q.remove();id++;//創(chuàng)建新的節(jié)點//新節(jié)點的權(quán)值是兩個子節(jié)點之和HT[id]=new HTNode(id,'\0',s1.weight+s2.weight,s1.id,s2.id); s1.parent=s2.parent=id; //將兩個子節(jié)點的父節(jié)點設(shè)置為 id;//新節(jié)點重新放入隊列Q.add(HT[id]);}}/*** 從葉子到根逆向求每個字符的Huffman編碼*/public void createHuffmanCode() {int start,c,f;char[] cd=new char[num];HuffmanCodeList=new String[num+1]; //分配內(nèi)存空間//依次對所有字符編碼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';}}//復(fù)制編碼到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("字符集總數(shù):"+HT.length);for(int i=1;i<=num;i++) {print("\'"+HT[i].code+"\':"+HuffmanCodeList[i]);}}/*** 調(diào)用{@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);} }

運行結(jié)果

參考文章

https://blog.csdn.net/Wood_Du/article/details/80366094

https://shentuzhigang.blog.csdn.net/article/details/103198604

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的JAVA——赫夫曼编码-译码器(Huffman Coding)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。