急!!!C++ 哈弗曼编码 请问下列代码有什么用?
问题描述:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。
基本要求:
1、 权值数据存放在数据文件(文件名为data.txt,位于执行程序的当前目录中)
2、 采用静态存储结构;
3、 初始化:键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;
4、 编码:利用建好的哈夫曼树生成哈夫曼编码;
5、 输出编码;
6、 设字符集及频度如下表:
字符 空格 A B C D E F G H I J K L M
频度 186 64 13 22 32 103 21 15 47 57 1 5 32 20
字符 N O P Q R S T U V W X Y Z
频度 57 63 15 1 48 51 80 23 8 18 1 16 1
代码
#include "stdio.h"
#include "stdlib.h"
#define MAX 200
struct Huffnode
{
char data; /*结点值*/
int weight; /*权值*/
int parent; /*父结点*/
int left; /*左子结点*/
int right;/*右子结点*/
};
struct Huffcode
{
char cd[MAX];
int start;
};
Huffnode ht[2*MAX];
Huffcode hcd[MAX],d;
int i,k,f,l,r,n,c,m1,m2;
char ch,*menu[]={"-------------构建哈夫曼树------------",
"1.----------添加字符和权值-----------",
"2.----------输出哈夫曼编码-----------",
"3.----------退出系统-----------------"};
void Enter()
{
printf("输入元素个数:");
scanf("%d",&n);
for (i = 1;i <= n;i++)
{
getchar();
printf("第%d个元素=>\n\t结点值:",i);
scanf("%c",&ht[i].data);
printf("\t权值:");
scanf("%d",&ht[i].weight);
}
for (i = 1;i <= 2*n-1;i++)
{
ht[i].parent = ht[i].left = ht[i].right = 0;
}
for (i = n+1;i <= 2*n-1;i++)//构造哈夫曼树 (最外层的循环)
{
m1 = m2 = 32767;
l = r = 0; //l和r是最小权值的两个结点位置
for (k = 1;k <= i-1;k++)
{
if (ht[k].parent == 0)
{
if (ht[k].weight < m1)
{
m2 = m1;
r = l;
m1 = ht[k].weight;
l = k;
}
else if (ht[k].weight <m2)
{
m2 = ht[k].weight;
r = k;
}
}
}
ht[l].parent = i;
ht[r].parent = i;
ht[i].weight = ht[l].weight + ht[r].weight;
ht[i].left = l;
ht[i].right = r;
} //(最外层的循环)
for(i = 1;i <= n;i++) /*根据哈夫曼树求哈夫曼编码*/
{
d.start = n+1;
c = i;
f = ht[i].parent;
while (f != 0)
{
if(ht[f].left == c)
d.cd[--d.start] = '0';
else
d.cd[--d.start] = '1';
c = f;
f = ht[f].parent;
}
hcd[i] = d;
}
}
void Display()
{
printf("输出哈夫曼编码: \n");
for (i = 1;i <= n;i++)
{
printf("%c: ",ht[i].data);
for (k = hcd[i].start;k <= n;k++)
{
printf("%c",hcd[i].cd[k]);
}
printf("\n");
}
}
int menu_select()
{
int i,s;
char c[3];
for(i=0;i <4;i++)
printf("%s\n",menu[i]);
do
{
scanf("%s",c);
s=atoi(c);
}while(s <0||s>3);
return s;
}
void main()
{
for(;;)
{
switch(menu_select())
{
case 1:Enter();break;
case 2:Display();break;
case 3:exit(0);
}
}
}