Huffman编码原理(C++,java实现)

来源:互联网 发布:慈善协会网站源码 编辑:程序博客网 时间:2024/05/16 03:41

对于给定一组数利用huffman对其编码

原理介绍引用自  http://www.cnblogs.com/mcgrady/p/3329825.html

1. 首先介绍huffman树



2. 首先huffman树的构建



3. Huffman编码介绍



总结:Huffman编码时一种无损压缩编码(也就是可以通过解码得到原始被压缩数据)方案

Huffman 编码是一种不等长编码,也就是说并非所有的叶子节点都位于huffman的同一个层次上

Huffman 编码通过贪心算法解决前缀问题(huffman编码是一种前缀编码)


4. c++实现

#include <iostream>#include <stdio.h>#include <vector>using namespace std;struct HuffmanNode{int left;int right;int weight;int parent;};/************************************************************************//*          寻找最小的两个数                                     *//************************************************************************///void select(HuffmanNode* pHuffmanTree,int n,int &s1,int &s2){void select(vector<HuffmanNode> pHuffmanTree,int n,int &s1,int &s2){s1=-1;s2=-1;int nMin1=-1;int nMin2=-1;for (int i=0;i<n;i++){if (pHuffmanTree[i].parent==0 && pHuffmanTree[i].weight>0){if (s1<0 || nMin1>pHuffmanTree[i].weight){s2=s1;nMin2=nMin1;s1=i;nMin1=pHuffmanTree[s1].weight;}else if (s2<0 || nMin2>pHuffmanTree[i].weight){s2=i;nMin2=pHuffmanTree[i].weight;}}}//for(int i=0;i<data_size;i++){//if(Min>data[i]){//secondMin=Min;//Min=data[i];//}else{//secondMin=data[i];//}//}}void HuffmanCoding(int *pWeight,int N, vector<vector<char>> &code){if (N<=0){return;}int m=2*N-1;//完全二叉树中节点数目比叶子节点数的2倍少1vector<HuffmanNode> pHuffmanTree(m);//表示树中有m个节点int s1,s2;/*********建立叶子节点************/for (int i=0;i<N;i++){pHuffmanTree[i].weight=pWeight[i];//相当于是Huffman树的第一层pHuffmanTree[i].parent=0;pHuffmanTree[i].left=-1;pHuffmanTree[i].right=-1;}for (int i=N;i<m;i++)//建立huffman树中除叶子节点外的其它节点{select(pHuffmanTree,i,s1,s2);pHuffmanTree[s1].parent=pHuffmanTree[s2].parent=i;pHuffmanTree[i].left=s1;pHuffmanTree[i].right=s2;pHuffmanTree[i].weight=pHuffmanTree[s1].weight+pHuffmanTree[s2].weight;}//根据建立好的Huffman树,从叶子节点到根节点计算每个叶节点的编码int node,parent;for (int i=0;i<N;i++){vector<char> &cur=code[i];node=i;parent=pHuffmanTree[node].parent;while (parent!=0){if (pHuffmanTree[parent].left==node){cur.push_back('0');} else{cur.push_back('1');}node=parent;parent=pHuffmanTree[node].parent;}reverse(cur.begin(),cur.end());}}void CalFrequency(const char* str,int* pWeight){while (*str){pWeight[*str]++;str++;}}void CalExistChar(int* pWeight,int N,vector<int>& pChar){int j=0;for (int i=0;i<N;i++){if (pWeight[i]!=0)//将存在的字符加入vector中{pChar.push_back(i);if (j!=i){pWeight[j]=pWeight[i];}j++;}}}void PrintCode(char c,vector<char> &code){cout<<(int) c<<" "<<c<<":";for (vector<char>::iterator it= code.begin();it!=code.end();it++){cout<<*it;}cout<<"\n";}void Print(vector<vector<char>>& code, vector<int>&pChar){int size=(int)code.size();for (int i=0;i<size;i++){PrintCode(pChar[i],code[i]);}}int main(){const int N=256;char str[]="Failure is probably the fortification in your pole.\It is like a peek your wallet as the thief, \when you are thinking how to spend several hard-won lepta,\when you are wondering whether new money, it has laid background.\Because of you, then at the heart of the most lax, alert,\and most low awareness, and left it godsend failed.";int pWeight[N]={0};CalFrequency(str,pWeight);pWeight['\t']=0;vector<int> pChar;CalExistChar(pWeight,N,pChar);int N2=(int)pChar.size();vector<vector<char>> code(N2);HuffmanCoding(pWeight,N2,code);Print(code,pChar);}


java实现:

package huffmanCode;import java.io.*;import java.nio.charset.StandardCharsets;import java.nio.file.Path;import java.nio.file.Paths;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.TreeSet;public class huffmanCode {public final int N=256;//所有AsccII有257个字符表示去除0有256public int Min,secondMin;//用来标识最小的两个数/** * read compressed file * @param filePath * @return content of text file */public static String readfile(Path filePath){List<String> linelist=Collections.emptyList(); try{linelist=java.nio.file.Files.readAllLines(filePath, StandardCharsets.UTF_8);}catch(IOException e){e.printStackTrace();}return linelist.toString();}/** * statistic the num of each char in String str * @param str * @return */public int[] countFrequency(String str){   int Num[]=new int[N];   char[] temp=str.toCharArray();   for(int i=0;i<temp.length;i++){   if(temp[i]!=0){   Num[temp[i]]++;   }   }return Num;}public ArrayList<Existchar> countExistChar(int[] Num){ArrayList<Existchar> cec=new ArrayList<Existchar>();for(int i=0;i<N;i++){if(Num[i]!=0){Existchar ec=new Existchar();ec.orgchar=(char) i;ec.num=Num[i];cec.add(ec);}}return cec;}public class Existchar{public char orgchar;public int num;public int left=0;public int right=0;public int parent=0;public String str="";}/** * toSelect the top min */public void selectTopTwoMin(ArrayList<Existchar> cec,int n){Min=-1;secondMin=-1;int Minval=Integer.MAX_VALUE;int secondMinval=Integer.MAX_VALUE;for(int i=0;i<n;i++){Existchar temp=cec.get(i);if(temp.parent==0){if(temp.num<Minval){secondMin=Min;secondMinval=Minval;Min=i;Minval=temp.num;}else if(temp.num<secondMinval){secondMin=i;secondMinval=temp.num;}}}}/** * construct Huffmantree * @param argcs */public void HuffmanCoding(ArrayList<Existchar> cec1){int N=cec1.size();int M=2*N-1;//the num of the HuffmanNodeArrayList<Existchar> cec=new ArrayList<Existchar>(M);for(int i=0;i<N;i++){cec.add(cec1.get(i));}for(int i=N;i<M;i++){selectTopTwoMin(cec,i);Existchar leftNode=cec.get(Min);Existchar rightNode=cec.get(secondMin);leftNode.parent=i;rightNode.parent=i;Existchar parentNode=new Existchar();parentNode.left=Min;parentNode.right=secondMin;parentNode.num=leftNode.num+rightNode.num;cec.add(parentNode);}for(int i=0;i<N;i++){String curstr="";Existchar curnode=cec.get(i);int parent=curnode.parent;while(parent!=0){Existchar parentNode=cec.get(parent);if(parentNode.left==i){curstr+='0';}else{curstr+='1';}parent=parentNode.parent;}curnode.str=new StringBuilder(curstr).reverse().toString();  ;cec1.set(i, curnode);}}public static void main(String argcs[]){huffmanCode code=new huffmanCode();String texPath="G://program/Java_pro/src/huffmanCode/tex.txt";String str=readfile(Paths.get(texPath));int Num[]=code.countFrequency(str);ArrayList<Existchar> cec=code.countExistChar(Num);code.HuffmanCoding(cec);for(int i=0;i<cec.size();i++){System.out.print(cec.get(i).orgchar+"\t\t\t");System.out.print(cec.get(i).str+"\n");}}}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 医保卡忘了密码怎么办 手机qq红包忘记支付密码怎么办 微信红包忘记支付密码怎么办 充点话费充错了怎么办 qq转账记录删除了怎么办 qq转账记录删了怎么办 qq怎么办?q币转给微信 q币送不了别人怎么办 新qq号忘记了怎么办 手机qq登不上去怎么办 qq的账号忘了怎么办 微信红包密码输错锁了怎么办 陌陌钱包异常钱怎么办 对公账户转错了怎么办 微信零钱转账限额怎么办 微信红包充错话费怎么办 qq支付20万限额怎么办 qq红包20万限额怎么办 微信充qb冲错了怎么办 液相色谱柱干了怎么办 微信钱包充流量没到账怎么办 qq买流量不到账怎么办 冲q币电话冲错号了怎么办 下载cf什么文件损坏怎么办 cf老是36_2怎么办啊 永辉超市积分卡怎么办 超市积分卡丢了怎么办 医保卡磁条坏了怎么办 社保卡磁条坏了怎么办 鞋子长了怎么办m.s.cn 厚底皮拖鞋穿松了怎么办 白色帆布鞋洗后发黄怎么办 运动鞋子买大了怎么办 格力空调出现fo怎么办 绝味鸭脖代金券的附券撕了怎么办 耐克鞋子开胶了怎么办 苹果6s自动重启怎么办 钱不够想买手机怎么办 安卓机屏幕密码忘了怎么办 屏幕解锁密码忘了怎么办 华为手机屏幕解锁密码忘了怎么办