| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1507 人关注过本帖
标题:哈夫曼编码
只看楼主 加入收藏
gulang
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2006-11-29
收藏
 问题点数:0 回复次数:0 
哈夫曼编码

请各位高手指教:

/*
*实验内容:构造哈夫曼树,求前缀码;并实现信息的译码。
*
*问题描述:
*从终端读入一段英文(也可以从文件中读出)(允许出现标点和空格),
*统计其中出现的不同字符的个数 n,以及每个字符出现的频率,
*然后根据统计数据建立哈夫曼树,求出各字符的编码并输出。
*根据上述编码对输入的信息进行译码
*
*
*
*/

#include"stdlib.h"
#include"stdio.h"
#include "string.h"
#define MAXINT 3421
#define N 50 /* 数组中最多容纳的元素个数,注意 n<=N */
#define M 2*N-1 /* 哈夫曼树中的最大结点数,注意 2*n-1<M */

/*用链表存储字符串的单词和个数.*/
int n=0;
typedef struct node *pnode;
typedef struct node //定义结构体存储输入字符串中的单词及其个数.
{
char info[8]; //单词
int num; //单词个数
pnode next;
};
typedef struct node * linklist;
typedef linklist * plinklist;
linklist createnulllist_link(void) /*创建空链表*/
{
linklist llist=(linklist)malloc(sizeof(struct node));
if (llist!=NULL)
llist->next=NULL;
else printf("Out of space!\n");
return (llist);
}

/*链表的插入*/
linklist insertlink(linklist llist,char e[8])
{
pnode p;
p=llist;
while (p->next!=NULL)
{
p=p->next;
if (strcmp(p->info,e)==0)
{
p->num++;
return llist;
}
}
pnode q=(pnode)malloc(sizeof(struct node));
if (q==NULL)
{
printf("Out of space!\n");
}
strcpy(q->info,e);
q->num=1;
p->next=q;
q->next=NULL;
n++;
return llist;
}


void output_link(linklist llist) /*输出字符串中的各单词及个数*/
{
llist=llist->next;
printf("\n");
while(llist!=NULL)
{
printf("%s \t%d\n ",llist->info,llist->num);
llist=llist->next;
}
printf("\n");
}

/* huffman树的构造方法*/

typedef struct /*哈夫曼树结点的结构*/
{
char data[8];
int weight;
int parent;
int lchild;
int rchild;
}htnode;
typedef struct /*存放哈夫曼码*/
{
char cd[N];
int start;
}hcode;

/*构造哈夫曼树*/
void createht(htnode ht[],int n)
{
int i,k,lnode,rnode;
int min1,min2;
for(i=0;i<2*n-1;i++)
{
ht[i].parent=ht[i].lchild=ht[i].rchild=-1; /*所有结点的相关域置初值-1*/
}
for (i=0;i<n-1;i++) /*构造哈夫曼树*/
{
min1=MAXINT;
min2=MAXINT;
lnode=-1; /*lnode和rnode为最小权重的两个结点位置*/
rnode=-1;
for (k=0;k<n+i;k++)
{
if (ht[k].weight<min1&&ht[k].parent==-1) /*只在尚未构造二叉树的结点中查找*/
{
min2=min1;
rnode=lnode;
min1=ht[k].weight;
lnode=k;
}
else if (ht[k].weight<min2&&ht[k].parent==-1)
{
min2=ht[k].weight;
rnode=k;
}
}
ht[lnode].parent=n+i;
ht[rnode].parent=n+i;
ht[n+i].weight=ht[lnode].weight+ht[rnode].weight;
ht[n+i].lchild=lnode;
ht[n+i].rchild=rnode;
}
}

/*构造哈夫曼编码*/
void createhcode(htnode ht[],hcode hcd[],int n)
{
int i,f,c;
hcode hc;
for (i=0;i<n;i++) /*根据哈夫曼树求哈夫曼编码*/
{
hc.start=n;
c=i;
f=ht[i].parent;
while (f!=-1) /*循序到树结点*/
{
if (ht[f].lchild==c) /*处理左孩子结点*/
hc.cd[hc.start--]='0';
else /*处理右孩子结点*/
hc.cd[hc.start--]='1';
c=f;
f=ht[f].parent;
}
hc.start++; /*start指向哈夫曼编码最开始字符*/
hcd[i]=hc;
}
}

/*输出哈夫曼编码*/
void disphcode(htnode ht[],hcode hcd[],int n)
{
int i,k;
int sum=0,m=0,j;
printf("输出哈夫曼编码:\n");
printf("单词 个数 哈夫曼编码 \n");
for (i=0;i<n;i++)
{
j=0;
printf("%s:\t %d\t\t",ht[i].data,ht[i].weight);
for (k=hcd[i].start;k<=n;k++)
{
printf("%c",hcd[i].cd[k]);
j++;
}
printf("\n");
}

}

void main()
{
char e[8];
linklist llist;
llist=createnulllist_link();
int i=0,j=0;
char str[1000]; /*字符串的长度(根据需要而定)*/
printf("请输入字符串或文章:\n");
gets(str);

/*计算字符串中各单词及其个数*/
for (i=0;i<=strlen(str);i++)
{
if (str[i]!=' '&&str[i]!=','&&str[i]!='.'&&str[i]!='\0')/*字符不为空格或标点符号*/
{
e[j]=str[i];
j++;
e[j]='\0';
}
else /*字符为空格或标点符号(标志一个单词结束)*/
{
if (!e) /*字符串e为空*/
continue;
else if(e[0]!='\0') /*字符串e不为空*/
llist=insertlink(llist,e);
for (j=0;j<8;j++) /*将字符变量e赋予空值*/
e[j]='\0';
j=0;
}
}
printf("这段文章的单词及其个数为:\n");
printf("\n");
printf("单词 个数 ");
output_link(llist); /*输出字符串中的各单词及个数*/
printf("字符串中单词的个数为:%d\n",n);
printf("\n");

htnode ht[M];
hcode hcd[N];
pnode p;
p=llist;
i=0;
while (p->next!=NULL) /*将字符串中的单词及个数赋予哈夫曼树的结构体*/
{
p=p->next;
strcpy(ht[i].data,p->info);
ht[i].weight=p->num;
i++;
}
printf("\n");
createht(ht,n); /*构造哈夫曼树*/
createhcode(ht,hcd,n); /*构造哈夫曼编码*/
disphcode(ht,hcd,n); /*输出哈夫曼编码*/
printf("\n");

}

搜索更多相关主题的帖子: 哈夫曼编码 
2006-11-30 13:46
快速回复:哈夫曼编码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015167 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved