可逼近信道容量编码技术之霍夫曼编码的实现
Posted 踟蹰横渡口,彳亍上滩舟。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可逼近信道容量编码技术之霍夫曼编码的实现相关的知识,希望对你有一定的参考价值。
可逼近信道容量编码技术之霍夫曼编码的实现
简介
在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。
通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。
关键词:哈夫曼树、编码、解码、设计
论文+代码下载地址:论文+代码下载地址
目录
运行结果 编码–》译码
主程序流程图
系统实现–主调函数
void Open(char s[])
//打开存放字符或编码的文件,将其存入字符串数组中 {
char name[10];
FILE *fp;
int i=0;
printf("请输入要打开的文件名:");
gets(name); //要打开的文件名
if((fp=fopen(name,"rt"))==NULL)
{
printf("打开失败!\\n");
//若打开失败,则直接退出
exit(1);
}
s[i++]=fgetc(fp);
while(s[i-1]!=EOF)
s[i++]=fgetc(fp);
s[i]='\\0'; //存取字符串结束
fclose(fp);}
系统实现–建立HuffmanTree
void CreatHFMTree(HFMTree *HT,int count[])
{
//创建哈夫曼树
int i;
HFMTree p,HT1,HT2; //HT1,HT2分别存放权值最小和次小的节点的位置 p=*HT=(HFMTree)malloc(sizeof(HFMNode));
p->next=p->LChild=p->RChild=p->Parent=NULL;
//初始化哈夫曼链表且有2n-1个节点
for(i=1;i<2*n-1;i++)
{
p->next=(HFMTree)malloc(sizeof(HFMNode));
p=p->next;
p->next=p->LChild=p->RChild=p->Parent=NULL;
}
for(i=0,p=*HT;i<n;i++)
//将各个字符出现的次数作为权值
{
//存入哈夫曼链表的前n个单元中
p->weight=count[i];
p=p->next;
}
for(i=n;i<2*n-1;i++) //将后n-1个节点赋权值,建树
{
SelectMin(*HT,i,&HT1,&HT2);
//每次从前i个节点中选取权值最小的两个节点
HT1->Parent=HT2->Parent=p;
p->LChild=HT1;
p->RChild=HT2;
p->weight=HT1->weight+HT2->weight;
//将两个节点的权值相加存入最后一个节点中
p=p->next; //p指向下一个没有存储权值的节点
}
}
系统实现–生成Huffman编码并写入文件
void HFMCode(HFMTree HT,CodeNode HC[],char str[])
{
//从每个叶子节点开始,利用哈夫曼树对每个字符进行编码,最终建立一个哈夫曼表
int i;
HFMTree q,p=HT;
for(i=0;i<n;i++)
//将字符存入哈夫曼编码结构体数组的字符单元中
{
HC[i].ch=str[i];
HC[i].code[n-1]='\\0'; //初始化编码的最后一位
}
for(i=0;i<n;i++)
{
HC[i].start=n-1;
for(q=p;q->Parent;q=q->Parent)
//判断q所指向的节点,左孩子置0,右孩子置1
if(q==q->Parent->LChild)
HC[i].code[--HC[i].start]='0';
else HC[i].code[--HC[i].start]='1';
p=p->next; //判断下一个叶子节点
}
}
系统实现–4电文译码
void DeCoding(char code[],HFMTree HT,char str[],char s[])
{
//对哈夫曼编码进行译码,放入字符串s中
int i,j,k=0;
HFMTree root,p,q;
for(root=HT;root->Parent;root=root->Parent);
//用root指向哈夫曼树的根结点
for(i=0,p=root;code[i];i++) //从根结点开始按编码顺序访问树
{ if(code[i]=='0')
p=p->LChild;
else p=p->RChild;
if(p->LChild==NULL&&p->RChild==NULL) //到根节点时将该节点对应的字符输出
{
for(j=0,q=HT;q!=p;q=q->next,j++);
s[k++]=str[j];
p=root; //回溯到根结点
}
}
s[k]='\\0'; //解码完毕,在字符串最后一个单元存入'\\0'
}
参看文献
参考文献
[1] 严蔚敏.数据结构(C语言版).清华大学出版社,2007
[2] 苏仕华.数据结构课程设计.机械工业出版社,2007
[3] 谭浩强.C语言程序设计教程.高等教育出版社,2006
以上是关于可逼近信道容量编码技术之霍夫曼编码的实现的主要内容,如果未能解决你的问题,请参考以下文章
计算机网络湖科大微课堂笔记 p17-18 编码与调制信道的极限容量