怎么样用c语言程序编码哈夫曼树?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么样用c语言程序编码哈夫曼树?相关的知识,希望对你有一定的参考价值。
用程序代码写出并加有注释
#include<stdio.h>#include<stdlib.h>
#include<string.h>
#include <ctype.h>
#include<limits.h>
int function1(char ch,char *s)
int i;
for(i=0; s[i]!='\0'; i++)
if(ch==s[i])return 0;
return 1;
typedef struct
unsigned int weight;
unsigned int parent,lchild,rchild;
HTNode,*HuffmanTree; // 动态分配数组存储赫夫曼树
typedef char **HuffmanCode; // 动态分配数组存储赫夫曼编码表
// algo6-1.cpp 求赫夫曼编码。实现算法6.12的程序
int min(HuffmanTree t,int i)
// 函数void select()调用
int j,flag;
unsigned int k=UINT_MAX; // 取k为不小于可能的值
for(j=1; j<=i; j++)
if(t[j].weight<k&&t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
return flag;
void select(HuffmanTree t,int i,int &s1,int &s2)
// s1为最小的两个值中序号小的那个
s1=min(t,i);
s2=min(t,i);
/* if(s1>s2)
j=s1;
s1=s2;
s2=j;
*/
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n) // 算法6.12
// w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
int m,i,s1,s2,start;
unsigned c,f;
HuffmanTree p;
char *cd;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用
for(p=HT+1,i=1; i<=n; ++i,++p,++w)
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
for(; i<=m; ++i,++p)
(*p).parent=0;
for(i=n+1; i<=m; ++i) // 建赫夫曼树
// 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].rchild=s1;
HT[i].lchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
// printf("HT[%d].lchild:%d HT[%d].rchild:%d\n",i,s2,i,s1);
// 从叶子到根逆向求每个字符的赫夫曼编码
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
// 分配n个字符编码的头指针向量([0]不用)
cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间
cd[n-1]='\0'; // 编码结束符
for(i=1; i<=n; i++)
// 逐个字符求赫夫曼编码
start=n-1; // 编码结束符位置
for(c=i,f=HT[i].parent; f!=0; c=f,f=HT[f].parent)
// 从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='1';
else
cd[--start]='0';
HC[i]=(char*)malloc((n-start)*sizeof(char));
// 为第i个字符编码分配空间
strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC
free(cd); // 释放工作空间
void swap1(int *a ,int *b)
int t;
t=*a;
*a=*b;
*b=t;
void swap2(char *a,char *b)
char ch;
ch=*a;
*a=*b;
*b=ch;
int main(void)
HuffmanTree HT;
HuffmanCode HC;
char *s1,*s2;
int i,j=0,n,count,*m,t,flag=1;
scanf("%d",&n);
getchar();
s1=(char*)malloc((n+n)*sizeof(char));
s2=(char*)malloc(n*sizeof(char));
memset(s2,'\0',n*sizeof(char));
gets(s1);
count=strlen(s1);
for(i=0; i<count; i++)
if(!isspace(*(s1+i)))
if(function1(*(s1+i),s2))
*(s2+j)=*(s1+i);
j++;
else;
m=(int*)malloc(j*sizeof(int));
for(i=0; i<j; i++)
*(m+i)=0;
for(t=0; t<j; t++)
for(i=0; i<count; i++)
if(*(s2+t)==*(s1+i))
*(m+t)+=1;
for(i=0;i<j;i++)
while(flag)
flag = 0;
for (t=0; t<j-1; t++)
if(*(m+t)<*(m+t+1))
swap1(m+t,m+t+1);
swap2(s2+t,s2+t+1);
flag=1;
HuffmanCoding(HT,HC,m,j);
for(i=1,t=0; i<=j; i++,t++)
printf("%c %d %s\n",*(s2+t),*(m+t),HC[i]);
return 0;
参考技术A #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include
<ctype.h>
#include<limits.h>
int
function1(char
ch,char
*s)
int
i;
for(i=0;
s[i]!='\0';
i++)
if(ch==s[i])return
0;
return
1;
typedef
struct
unsigned
int
weight;
unsigned
int
parent,lchild,rchild;
HTNode,*HuffmanTree;
//
动态分配数组存储赫夫曼树
typedef
char
**HuffmanCode;
//
动态分配数组存储赫夫曼编码表
//
algo6-1.cpp
求赫夫曼编码。实现算法6.12的程序
int
min(HuffmanTree
t,int
i)
//
函数void
select()调用
int
j,flag;
unsigned
int
k=UINT_MAX;
//
取k为不小于可能的值
for(j=1;
j<=i;
j++)
if(t[j].weight<k&&t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
return
flag;
void
select(HuffmanTree
t,int
i,int
&s1,int
&s2)
//
s1为最小的两个值中序号小的那个
s1=min(t,i);
s2=min(t,i);
/*
if(s1>s2)
j=s1;
s1=s2;
s2=j;
*/
void
HuffmanCoding(HuffmanTree
&HT,HuffmanCode
&HC,int
*w,int
n)
//
算法6.12
//
w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
int
m,i,s1,s2,start;
unsigned
c,f;
HuffmanTree
p;
char
*cd;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
//
0号单元未用
for(p=HT+1,i=1;
i<=n;
++i,++p,++w)
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
for(;
i<=m;
++i,++p)
(*p).parent=0;
for(i=n+1;
i<=m;
++i)
//
建赫夫曼树
//
在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].rchild=s1;
HT[i].lchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
//
printf("HT[%d].lchild:%d
HT[%d].rchild:%d\n",i,s2,i,s1);
//
从叶子到根逆向求每个字符的赫夫曼编码
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
//
分配n个字符编码的头指针向量([0]不用)
cd=(char*)malloc(n*sizeof(char));
//
分配求编码的工作空间
cd[n-1]='\0';
//
编码结束符
for(i=1;
i<=n;
i++)
//
逐个字符求赫夫曼编码
start=n-1;
//
编码结束符位置
for(c=i,f=HT[i].parent;
f!=0;
c=f,f=HT[f].parent)
//
从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='1';
else
cd[--start]='0';
HC[i]=(char*)malloc((n-start)*sizeof(char));
//
为第i个字符编码分配空间
strcpy(HC[i],&cd[start]);
//
从cd复制编码(串)到HC
free(cd);
//
释放工作空间
void
swap1(int
*a
,int
*b)
int
t;
t=*a;
*a=*b;
*b=t;
void
swap2(char
*a,char
*b)
char
ch;
ch=*a;
*a=*b;
*b=ch;
int
main(void)
HuffmanTree
HT;
HuffmanCode
HC;
char
*s1,*s2;
int
i,j=0,n,count,*m,t,flag=1;
scanf("%d",&n);
getchar();
s1=(char*)malloc((n+n)*sizeof(char));
s2=(char*)malloc(n*sizeof(char));
memset(s2,'\0',n*sizeof(char));
gets(s1);
count=strlen(s1);
for(i=0;
i<count;
i++)
if(!isspace(*(s1+i)))
if(function1(*(s1+i),s2))
*(s2+j)=*(s1+i);
j++;
else;
m=(int*)malloc(j*sizeof(int));
for(i=0;
i<j;
i++)
*(m+i)=0;
for(t=0;
t<j;
t++)
for(i=0;
i<count;
i++)
if(*(s2+t)==*(s1+i))
*(m+t)+=1;
for(i=0;i<j;i++)
while(flag)
flag
=
0;
for
(t=0;
t<j-1;
t++)
if(*(m+t)<*(m+t+1))
swap1(m+t,m+t+1);
swap2(s2+t,s2+t+1);
flag=1;
HuffmanCoding(HT,HC,m,j);
for(i=1,t=0;
i<=j;
i++,t++)
printf("%c
%d
%s\n",*(s2+t),*(m+t),HC[i]);
return
0;
霍夫曼编码的编码效率怎么求?
主要是为了比较霍夫曼编码与费诺编码孰优孰劣
求效率首先要求得信号的熵,也就是最小的编码长度,比如是2.3,然后再求霍夫曼码的平均编码长度(各个概率和码位相乘再求和)比如是2.7,那么效率就是0.85。
霍夫曼编码的编码效率,我想可以用压缩率来表示吧。随机选取一段字符,计算其编码长度为 n。再对其用霍夫曼编码,得到长度为 m。于是 m/n 就是压缩率。
霍夫曼编码是变长编码,思路:对概率大的编的码字短,概率小的编的码字长,这样一来所编的总码长就小,这样编码效率就高。
扩展资料:
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
参考资料来源:百度百科-霍夫曼编码
参考技术A 求效率首先要求得信号的熵,也就是最小的编码长度,比如是2.3,然后再求霍夫曼码的平均编码长度(各个概率和码位相乘再求和)比如是2.7,那么效率就是0.85 参考技术B 霍夫曼编码是变长编码,思路:对概率大的编的码字短,概率小的编的码字长,这样一来所编的总码长就小,这样编码效率就高。你上面那样求是不对的,除非你 参考技术C 霍夫曼编码的编码效率,我想可以用压缩率来表示吧。随机选取一段字符,计算其编码长度为 n。再对其用霍夫曼编码,得到长度为 m。于是 m/n 就是压缩率。以上是关于怎么样用c语言程序编码哈夫曼树?的主要内容,如果未能解决你的问题,请参考以下文章