哈夫曼编码HuffmanCoding文档格式.docx
《哈夫曼编码HuffmanCoding文档格式.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码HuffmanCoding文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
for(intnCount=0;
nCount<
256;
nCount++)
nodes[nCount].byAscii=nCount;
然后,计算在输入缓冲区数据中,每一个ASCII码显现的频率:
for(nCount=0;
nSrcLen;
nodes[pSrc[nCount]].nFrequency++;
然后,依照频率进行排序:
qsort(nodes,256,sizeof(CHuffmanNode),frequencyCompare);
此刻,构造哈夫曼树,获取每一个ASCII码对应的位序列:
intnNodeCount=GetHuffmanTree(nodes);
构造哈夫曼树超级简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率确实是这两个节点的频率之和。
如此,新节点确实是两个被替换节点的父节点了。
如此循环,直到队列中只剩一个节点(树根)。
wCode<
<
(nDesIndex&
7);
nDesIndex+=nodes[pSrc[nCount]].nCodeLength;
}
(nDesIndex>
>
3):
>
3以8位为界限右移后抵达右边字节的前面
(nDesIndex&
7):
&
7取得最高位.
注意:
在紧缩缓冲区中,咱们必需保留哈夫曼树的节点和位序列,如此咱们才能在解紧缩时从头构造哈夫曼树(只需保留ASCII值和对应的位序列)。
解紧缩
解紧缩比构造哈夫曼树要简单的多,将输入缓冲区中的每一个编码用对应的ASCII码逐个替换就能够够了。
只要记住,那个地址的输入缓冲区是一个包括每一个ASCII值的编码的位流。
因此,为了用ASCII值替换编码,咱们必需用位流搜索哈夫曼树,直到发觉一个叶节点,然后将它的ASCII值添加到输出缓冲区中:
intnDesIndex=0;
DWORDnCode;
while(nDesIndex<
nDesLen)
{
nCode=(*(DWORD*)(pSrc+(nSrcIndex>
3)))>
(nSrcIndex&
pNode=pRoot;
while(pNode->
pLeft)
pNode=(nCode&
1)?
pNode->
pRight:
pLeft;
nCode>
=1;
nSrcIndex++;
pDes[nDesIndex++]=pNode->
byAscii;
进程
#include<
#include<
#defineM10
typedefstructFano_Node
charch;
floatweight;
}FanoNode[M];
typedefstructnode
intstart;
intend;
structnode*next;
}LinkQueueNode;
typedefstruct
LinkQueueNode*front;
LinkQueueNode*rear;
}LinkQueue;
voidEnterQueue(LinkQueue*q,ints,inte)
LinkQueueNode*NewNode;
NewNode=(LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if(NewNode!
=NULL)
NewNode->
start=s;
end=e;
next=NULL;
q->
rear->
next=NewNode;
rear=NewNode;
elseprintf("
Error!
"
);
h)
printf("
Samenode\n"
break;
if(i==j)
i++;
}
for(i=1;
i<
=n;
i++)/*排序*/
{
max=i+1;
for(j=max;
j<
j++)
max=FN[max].weight<
FN[j].weight?
j:
max;
if<
FN[max].weight)
w=;
=FN[max].weight;
FN[max].weight=w;
c=;
=FN[max].ch;
FN[max].ch=c;
i++)/*初始化h*/
h=0;
EnterQueue(Q,1,n);
/*1和n进队*/
while(Q->
front->
next!
p=Q->
next;
/*出队*/
Q->
next=p->
if(p==Q->
rear)
rear=Q->
front;
sta=p->
start;
end=p->
end;
free(p);
Divide(FN,sta,&
m,end);
/*按权分组*/
for(i=sta;
=m;
i++)
fc[h]='
0'
;
h++;
if(sta!
=m)
EnterQueue(Q,sta,m);
else
fc[sta][h[sta]]='
\0'
for(i=m+1;
=end;
1'
if(m==sta&
&
(m+1)==end)=ch;
(*CW)[*p].weight=1;
for(k=i+1;
ch[k]!
='
k++)
if(ch==ch[k])
(*CW)[*p].weight++;
*s=i;
/********创建HuffmanTree********/
voidCreateHuffmanTree(Huffman*ht,WeightNodew,intn)
inti,j;
ints1,s2;
(*ht).weight=;
(*ht).parent=0;
(*ht).LChild=0;
(*ht).RChild=0;
for(i=n+1;
=2*n-1;
(*ht).weight=0;
for(j=1;
=i-1;
if(!
(*ht)[j].parent)
s1=j;
/*找到第一个双亲不为零的结点*/
for(;
s1=(*ht)[s1].weight>
(*ht)[j].weight?
s1;
(*ht)[s1].parent=i;
(*ht).LChild=s1;
s2=j;
s2=(*ht)[s2].weight>
s2;
(*ht)[s2].parent=i;
(*ht).RChild=s2;
(*ht).weight=(*ht)[s1].weight+(*ht)[s2].weight;
/***********叶子结点的编码***********/
voidCrtHuffmanNodeCode(Huffmanht,charch[],HuffmanCode*h,WeightNode*weight,intm,intn)
inti,j,k,c,p,start;
char*cd;
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='
i++)
start=n-1;
c=i;
p=;
while(p)
start--;
if(ht[p].LChild==c)
cd[start]='
c=p;
p=ht[p].parent;
(*weight).num=n-start;
(*h)=(char*)malloc((n-start)*sizeof(char));
p=-1;
strcpy((*h),&
cd[start]);
system("
pause"
/*********所有字符的编码*********/
voidCrtHuffmanCode(charch[],HuffmanCodeh,HuffmanCode*hc,WeightNodeweight,intn,intm)
inti,j,k;
for(i=0;
m;
for(k=1;
k<
k++)/*从(*weight)[k].c中查找与ch相等的下标K*/
if(ch==weight[k].c)
(*hc)=(char*)malloc((weight[k].num+1)*sizeof(char));
for(j=0;
=weight[k].num;
(*hc)[j]=h[k][j];
/*****解码*****/
voidTrsHuffmanTree(Huffmanht,WeightNodew,HuffmanCodehc,intn,intm)
inti=0,j,p;
***StringInformation***\n"
while(i<
m)
p=2*n-1;
hc[j]!
if(hc[j]=='
)
p=ht[p].LChild;
else
p=ht[p].RChild;
%c"
w[p].c);
/*打印原信息*/
main()
inti,n,m,s1,s2,j;
/*n为叶子结点的个数*/
charch[N],w[N];
/*ch[N]寄存输入的字符串*/
Huffmanht;
/*二叉数*/
HuffmanCodeh,hc;
/*h寄存叶子结点的编码,hc寄存所有结点的编码*/
WeightNodeweight;
/*寄存叶子结点的信息*/
\t***HuffmanCoding***\n"
pleaseinputinformation:
gets(ch);
/*输入字符串*/
CreateWeight(ch,&
m,&
weight,&
n);
/*产生叶子结点信息,m为字符串ch[]的长度*/
***WeightInformation***\nNode"
/*输出叶子结点的字符与权值*/
%c"
;
\nWeight"
%d"
CreateHuffmanTree(&
ht,weight,n);
/*产生Huffman树*/
\n***HuffamnTreeInformation***\n"
i++)/*打印Huffman树的信息*/
\t%d%d%d%d\n"
i,,,,;
CrtHuffmanNodeCode(ht,ch,&
h,&
weight,m,n);
/*叶子结点的编码*/
***NodeCode***\n"
/*打印叶子结点的编码*/
\t%c:
%s\n"
h);
CrtHuffmanCode(ch,h,&
hc,weight,n,m);
/*所有字符的编码*/
***StringCode***\n"
/*打印字符串的编码*/
%s"
hc);
TrsHuffmanTree(ht,weight,hc,n,m);
/*解码*/
Matlab中简易实现Huffman编译码:
n=input('
Pleaseinputthetotalnumber:
'
hf=zeros(2*n-1,5);
hq=[];
forki=1:
n
hf(ki,1)=ki;
hf(ki,2)=input('
Pleaseinputthefrequency:
hq=[hq,hf(ki,2)];
end
forki=n+1:
2*n-1
mhq1=min(hq);
m=size(hq);
m=m(:
2);
k=1;
whilek<
=m%delmin1
ifhq(:
k)==mhq1
hq=[hq(:
1:
(k-1))hq(:
(k+1):
m)];
m=m-1;
break
k=k+1;
whilehf(k,2)~=mhq1|hf(k,5)==1%findmin1location
hf(k,5)=1;
k1=k;
mhq2=min(hq);
=m%delmin2
k)==mhq2
whilehf(k,2)~=mhq2|hf(k,5)==1%findmin2location
k2=k;
hf(ki,2)=mhq1+mhq2;
hf(ki,3)=k1;
hf(ki,4)=k2;
hq=[hqhf(ki,2)];
clc
choose=input('
Pleasechoosewhatyouwant:
\n1:
Encoding\n2:
Decoding\n3:
.Exit\n'
whilechoose==1|choose==2
ifchoose==1
a=input('
PleaseinputtheletteryouwanttoEncoding:
whilehf(k,2)~=a
ifk>
=n
display('
Youdidnotinputthisnumber.'
r=[];
whilehf(k,5)==1
kc=n+1;
whilehf(kc,3)~=k&
hf(kc,4)~=k
kc=kc+1;
ifhf(kc,3)==k
r=[0r];
r=[1r];
k=kc;
r
PleaseinputthemetrixyouwanttoDecoding:
sa=size(a);
sa=sa(:
k=2*n-1;
whilesa~=0
ifa(:
1)==0
k=hf(k,3);
k=hf(k,4);
a=a(:
2:
sa);
sa=sa-1;
ifk==0
Themetrixyouenteredisawrongone.'
r=hf(k,2);
ifchoose~=1&
choose~=2
clc;