霍夫曼编码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 10
typedef struct s
{
char ch,parent;
int weight;
    struct s *lchild,*rchild;
}htnode;
int n;
htnode *creat(htnode *h)                      //创建
{
int i,j,t;
char c;
    htnode *p[10],*temp;
printf("请输入节点个数:");
scanf("%d",&n);
    for(i=0;i<n;i++)                        //赋值到叶子节点中
{
p[i]=(htnode *)malloc(sizeof(htnode));
p[i]->lchild =p[i]->rchild=NULL;
        printf("第 %d 个字符:",i+1);
c=getchar();
scanf("%c",&(p[i]->ch));
   printf("       权值:");
   scanf("%d",&p[i]->weight); 
}                                        //数据接收成功
    printf("huffman树已经成功建立!\n");  
    for(i=0;i<n-1;i++)                       //按权值排序
for(j=0;j<n-1-i;j++)
if(p[j]->weight>p[j+1]->weight)
{ temp=p[j] ; p[j]=p[j+1] ; p[j+1]=temp; }                  
for(i=0;i<n-1;i++)                        //建立huffman树
{
htnode *q;
q=(htnode *)malloc(sizeof(htnode));
q->lchild=p[0];  p[0]->parent='0';
q->rchild=p[1];  p[1]->parent='1';
q->ch = '#';
q->parent='=';
q->weight=p[0]->weight+p[1]->weight;
for(j=2;j<n-i;j++)                      //找地儿插入,然后统一前移
if(q->weight<=p[j]->weight)
{
for(t=n-i;t>j;t--) 
p[t]=p[t-1];
p[t]=q;
break;
}
if(j==n-i)
p[n-i]=q;
for(t=0;t<n-i-1;t++)
p[t]=p[t+2];
h=q;                                     
}
return h;                                   //返回根节点
}
char m[10][10];
char code(htnode *p,int j)                      //编码,巧用‘#’和‘*’字符
{
int i=0;
char k;
while(1)
{
for(; p->lchild->ch=='#' ; p=p->lchild ,i++)
m[j][i]=p->lchild->parent;
if(p->lchild->ch!='*')               
{
m[j][i]='0'; m[j][i+1]='\0';
k=p->lchild->ch;
p->lchild->ch='*';
return k;
}
else if(p->rchild->ch!='*'&&p->rchild->ch!='#')
{
m[j][i]= '1' ;m[j][i+1]='\0';
            k=p->rchild->ch;
p->ch  ='*';
p->rchild->ch='*';
return k;
}
else
{
p=p->rchild;
m[j][i++]='1';
}
}
}
void decode(char ch[])                     //译码
{
int i,j,t=0,k=0;
char s[40];
printf("请输入密码: ");
scanf("%s",s);
    printf("所得译码为: ");
while(s[t]!='\0')
{
for(i=0; i<n; i++)
{
j=0;
while(m[i][j++]==s[t++] && m[i][j]!='\0');
if(m[i][j]=='\0'&&m[i][j-1]==s[t-1])
{
putchar(ch[i]);
k=t;                        //若成功匹配,则存储t值,以备下次匹配失败后再传给t
break;
}
else t=k;
}
}
printf("\n");
}
int d=0;
void freeht(htnode *p)                     //销毁

if(p)
{
freeht(p->lchild);
   freeht(p->rchild);
free(p);
d++;
}
}
main()                                    //主函数
{
htnode *h;
int j;
char ch[10];
h = creat(h);
for(j=0;j<n;j++)
{
ch[j]=code(h,j);
printf("%c: %s\n",ch[j],m[j]);
}
decode(ch);
freeht(h);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值