ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:18.92KB ,
资源ID:6750622      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6750622.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(哈夫曼编码HuffmanCoding.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

哈夫曼编码HuffmanCoding.docx

1、哈夫曼编码HuffmanCoding哈夫曼编码哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。 Huffman于1952年提出一种编码方式,该方式完全依据字符显现概率来构造异字头的平均长 度最短的码字,有时称之为最正确编码,一样就叫作Huffman编码。 以即最优二叉树,带权途径长度最小的二叉树,常常应用于数据紧缩。 在运算机信息处置中,“哈夫曼编码”是一种一致性编码法(又称熵编码法),用于数据的无损耗紧缩。这一术语是指利用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊的地方在于,它是依照每一个源字符显现的估算概

2、率而成立起来的(显现概率高的字符利用较短的编码,反之显现概率低的那么利用较长的编码,这便使编码以后的字符串的平均期望长度降低,从而达到无损紧缩数据的目的)。这种方式是由进展起来的。 例如,在英文中,e的显现概率很高,而z的显现概率那么最低。当利用哈夫曼编码对一篇英文进行紧缩时,e极有可能用一个位(bit)来表示,而z那么可能花去25个位(不是26)。用一般的表示方式时,每一个英文字母均占用一个字节(byte),即8个位。二者相较,e利用了一样编码的1/8的长度,z那么利用了3倍多。倘假设咱们能实现关于英文中各个字母显现概率的较准确的估算,就能够够大幅度提高无损紧缩的比例。 本文描述在网上能够找

3、到的最简单,最快速的哈夫曼编码。本方式不利用任何扩展动态库,比如STL或组件。只利用简单的C函数,比如:memset,memmove,qsort,malloc,realloc和memcpy。 因此,大伙儿都会发觉,明白得乃至修改那个编码都是很容易的。背景哈夫曼紧缩是个无损的紧缩算法,一样用来紧缩文本和程序文件。哈夫曼紧缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中显现频率高的符号,利用短的位序列,而那些很少显现的符号,那么用较长的位序列。编码利用我用简单的C函数写那个编码是为了让它在任何地址利用都会比较方便。你能够将他们放到类中,

4、或直接利用那个函数。而且我利用了简单的格式,仅仅输入输出缓冲区,而不象其它文章中那样,输入输出文件。bool CompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);bool DecompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);要点说明 速度为了让它快速运行,我花了很长时刻。同时,我没有利用任何动态库,比如STL或MFC。它紧缩1M数据少于100ms(P3处置器,主频1G)。紧缩紧缩代码超级简单,第一用ASCII值初始化511个

5、哈夫曼节点: CHuffmanNode nodes511;for(int nCount = 0; nCount 256; nCount+)nodesnCount.byAscii = nCount;然后,计算在输入缓冲区数据中,每一个ASCII码显现的频率: for(nCount = 0; nCount nSrcLen; nCount+)nodespSrcnCount.nFrequency+;然后,依照频率进行排序: qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);此刻,构造哈夫曼树,获取每一个ASCII码对应的位序列: int

6、 nNodeCount = GetHuffmanTree(nodes);构造哈夫曼树超级简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率确实是这两个节点的频率之和。如此,新节点确实是两个被替换节点的父节点了。如此循环,直到队列中只剩一个节点(树根)。 wCode 3): 3 以8位为界限右移后抵达右边字节的前面 (nDesIndex&7): &7 取得最高位. 注意:在紧缩缓冲区中,咱们必需保留哈夫曼树的节点和位序列,如此咱们才能在解紧缩时从头构造哈夫曼树(只需保留ASCII值和对应的位序列)。 解紧缩解紧缩比构造哈夫曼树要简单的多,将输入缓冲区中的每一个编码用

7、对应的ASCII码逐个替换就能够够了。只要记住,那个地址的输入缓冲区是一个包括每一个ASCII值的编码的位流。因此,为了用ASCII值替换编码,咱们必需用位流搜索哈夫曼树,直到发觉一个叶节点,然后将它的ASCII值添加到输出缓冲区中: int nDesIndex = 0;DWORD nCode;while(nDesIndex 3)(nSrcIndex&7);pNode = pRoot;while(pNode-pLeft)pNode = (nCode&1) ? pNode-pRight : pNode-pLeft;nCode = 1;nSrcIndex+;pDesnDesIndex+ = pNo

8、de-byAscii;进程#include #include#include#include#include#define M 10typedef struct Fano_Node char ch;float weight;FanoNodeM;typedef struct nodeint start;int end;struct node *next;LinkQueueNode;typedef struct LinkQueueNode *front;LinkQueueNode *rear;LinkQueue;void EnterQueue(LinkQueue *q,int s,int e)Li

9、nkQueueNode *NewNode;NewNode=(LinkQueueNode *)malloc(sizeof(LinkQueueNode);if(NewNode!=NULL)NewNode-start=s;NewNode-end=e;NewNode-next=NULL;q-rear-next=NewNode;q-rear=NewNode;else printf(Error!);h)printf(Same noden);break;if(i=j) i+; for(i=1;i=n;i+) /*排序*/ max=i+1;for(j=max;j=n;j+)max=FNmax.weightFN

10、j.weight?j:max;ifFNmax.weight)w=;=FNmax.weight;FNmax.weight=w;c=;=FNmax.ch;FNmax.ch=c; for(i=1;ifront-next!=NULL) p=Q-front-next; /*出队*/ Q-front-next=p-next;if(p=Q-rear) Q-rear=Q-front;sta=p-start;end=p-end; free(p);Divide(FN,sta,&m,end); /*按权分组*/ for(i=sta;i=m;i+)fch=0;h+;if(sta!=m) EnterQueue(Q,st

11、a,m); else fcstahsta=0;for(i=m+1;i=end;i+)fch=1;h+; if(m=sta&(m+1)=end) =ch;(*CW)*p.weight=1;for(k=i+1;chk!=0;k+)if(ch=chk)(*CW)*p.weight+;*s=i; /*创建HuffmanTree*/ void CreateHuffmanTree(Huffman *ht,WeightNode w,int n) int i,j;int s1,s2;for(i=1;i=n;i+)(*ht).weight =;(*ht).parent=0;(*ht).LChild=0;(*ht

12、).RChild=0;for(i=n+1;i=2*n-1;i+)(*ht).weight=0;(*ht).parent=0;(*ht).LChild=0;(*ht).parent=0;for(i=n+1;i=2*n-1;i+)for(j=1;j=i-1;j+)if(!(*ht)j.parent)break;s1=j; /*找到第一个双亲不为零的结点*/ for(;j(*ht)j.weight?j:s1;(*ht)s1.parent=i;(*ht).LChild=s1;for(j=1;j=i-1;j+)if(!(*ht)j.parent)break;s2=j; /*找到第一个双亲不为零的结点*/

13、 for(;j(*ht)j.weight?j:s2;(*ht)s2.parent=i;(*ht).RChild=s2; (*ht).weight=(*ht)s1.weight+(*ht)s2.weight; /*叶子结点的编码*/ void CrtHuffmanNodeCode(Huffman ht,char ch,HuffmanCode *h,WeightNode *weight,int m,int n) int i,j,k,c,p,start;char *cd;cd=(char *)malloc(n*sizeof(char);cdn-1=0;for(i=1;i=n;i+) start=n-

14、1; c=i; p=; while(p) start-; if(htp.LChild=c) cdstart=0; else cdstart=1; c=p; p=htp.parent; (*weight).num=n-start; (*h)=(char *)malloc(n-start)*sizeof(char); p=-1;strcpy(*h),&cdstart); system(pause);/*所有字符的编码*/void CrtHuffmanCode(char ch,HuffmanCode h,HuffmanCode *hc,WeightNode weight,int n,int m)in

15、t i,j,k;for(i=0;im;i+)for(k=1;k=n;k+) /*从(*weight)k.c中查找与ch相等的下标K*/if(ch=weightk.c) break;(*hc)=(char *)malloc(weightk.num+1)*sizeof(char);for(j=0;j=weightk.num;j+)(*hc)j=hkj; /*解码*/ void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)int i=0,j,p;printf(*StringInformation*n);while

16、(im)p=2*n-1;for(j=0;hcj!=0;j+)if(hcj=0)p=htp.LChild;elsep=htp.RChild;printf(%c,wp.c); /*打印原信息*/i+; main() int i,n,m,s1,s2,j; /*n为叶子结点的个数*/ char chN,wN; /*chN寄存输入的字符串*/ Huffman ht; /*二叉数 */HuffmanCode h,hc; /* h寄存叶子结点的编码,hc 寄存所有结点的编码*/WeightNode weight; /*寄存叶子结点的信息*/ printf(t*HuffmanCoding*n); printf

17、(please input information :);gets(ch); /*输入字符串*/ CreateWeight(ch,&m,&weight,&n); /*产生叶子结点信息,m为字符串ch的长度*/ printf(*WeightInformation*n Node ); /*输出叶子结点的字符与权值*/ for(i=1;i=n;i+)printf(%c ,;printf(nWeight );for(i=1;i=n;i+)printf(%d ,; CreateHuffmanTree(&ht,weight,n); /*产生Huffman树*/ printf(n*HuffamnTreeIn

18、formation*n); for(i=1;i=2*n-1;i+) /*打印Huffman树的信息*/ printf(t%d %d %d %dn,i,; CrtHuffmanNodeCode(ht,ch,&h,&weight,m,n); /*叶子结点的编码*/printf( *NodeCode*n); /*打印叶子结点的编码*/ for(i=1;i=n;i+) printf(t%c:,; printf(%sn,h);CrtHuffmanCode(ch,h,&hc,weight,n,m); /*所有字符的编码*/ printf(*StringCode*n); /*打印字符串的编码*/ for(i

19、=0;im;i+)printf(%s,hc);system(pause);TrsHuffmanTree(ht,weight,hc,n,m); /*解码*/ system(pause); Matlab 中简易实现Huffman编译码:n=input(Please input the total number: );hf=zeros(2*n-1,5);hq=;for ki=1:nhf(ki,1)=ki;hf(ki,2)=input(Please input the frequency: );hq=hq,hf(ki,2);endfor ki=n+1:2*n-1hf(ki,1)=ki;mhq1=min

20、(hq);m=size(hq);m=m(:,2);k=1;while k=m%del min1if hq(:,k)=mhq1hq=hq(:,1:(k-1) hq(:,(k+1):m);m=m-1;breakelsek=k+1;endendk=1;while hf(k,2)=mhq1|hf(k,5)=1%find min1 locationk=k+1;endhf(k,5)=1;k1=k;mhq2=min(hq);k=1;while k=ndisplay(Error! You did not input this number.);breakendendif k=nbreakendr=;while

21、 hf(k,5)=1kc=n+1;while hf(kc,3)=k&hf(kc,4)=kkc=kc+1;endif hf(kc,3)=kr=0 r;elser=1 r;endk=kc;endrelsea=input(Please input the metrix you want to Decoding: );sa=size(a);sa=sa(:,2);k=2*n-1;while sa=0if a(:,1)=0k=hf(k,3);elsek=hf(k,4);enda=a(:,2:sa);sa=sa-1;if k=0display(Error! The metrix you entered is a wrong one.);breakendendif k=0breakendr=hf(k,2);rendchoose=input(Please choose what you want:n1: Encodingn2: Decodingn3:.Exitn);clcendif choose=1&choose=2clc;end

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1