数据结构之树的应用

一、 实验题目:

树的应用——哈夫曼编码

二、 实验内容:

利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。

从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,求出各字符的哈夫曼编码。要求:

1. 输出存放哈夫曼树的数组HT的初态和终态;

2. 输出每个字符的哈夫曼编码;

3. 输入由上述若干字符组成的字符串,对电文进行编码并输出;

4. (选做)输入电文的哈夫曼编码,进行译码并输出。

三、 实验要求:

1. 使用C语言完成算法设计和程序设计并上机调试通过。

2. 撰写实验报告,提供实验结果和数据。

3. 写出算法设计小结和心得。

四、 程序源代码:

#include<stdio.h>

#include<stdlib.h>

#define M 10

typedef struct{

char data;

int weight,parent,lchild,rchild;

}HTNode,*HuffmanTree;

typedef struct{

char cd[M];

int start;

}huffnode;

typedef char * *HuffmanCode;

void Coding(HuffmanTree &HT,huffnode hcd[],int n,char str[]) {

for (int i=0;str[i]!='\0';i++)  {   

for (int j=1;j<=n;j++)   {    

if (str[i]==HT[j].data)    {  

for (int k=hcd[j].start;k<=n;k++)  {   

printf("%c",hcd[j].cd[k]);

}     

break;   

}

}

}  

printf("\n");   

}

void HuffmanCoding(HuffmanTree &HT,int n){

int m,i,s1,s2,m1,m2,k;

int c,f;  

huffnode hcd[20],d;

m=2*n-1;

HuffmanTree p;

p=(HuffmanTree)malloc((m+1)*sizeof(HTNode));

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));

if(n<1) return;

for( i=1;i<=2*n-1;++i){

HT[i].data=HT[i].parent=HT[i].lchild=HT[i].rchild=HT[i].weight=0;

}

for(p=HT,i=1;i<=n;++i) {

getchar();

printf("第%d个元素的\n结点值",i);

scanf("%c",&HT[i].data);

    printf("\t权重:  ");

scanf("%d",&HT[i].weight);

p[i].data=HT[i].data;

p[i].weight=HT[i].weight;

}

printf("哈夫曼树初始\n");

printf("\tdata\tweight\tparent\tlchild\trchild\n");

for( i=1;i<=2*n-1;++i){

printf("\t%c\t%d\t%d\t%d\t%d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

}

for(i=n+1;i<=m;i++){

  m1=m2=32767;

  s1=s2=0;

for (int k=1; k<=i-1; k++)   

{  if ((HT[k].parent==0)&&(HT[k].weight<m1))

    { m2=m1;  s2=s1;

       m1=HT[k].weight;

       s1=k;

     }

    else if ((HT[k].parent==0)&&(HT[k].weight<m2))

    { m2=HT[k].weight;

        s2=k;

    }

}

HT[s1].parent=i;  

HT[s2].parent=i;  

HT[i].weight=HT[s1].weight+HT[s2].weight;  

HT[i].lchild=s1;  

HT[i].rchild=s2;

}

printf("哈夫曼树终态\n");

printf("\tdata\tweight\tparent\tlchild\trchild\n");

for( i=1;i<=2*n-1;++i){

printf("\t%c\t%d\t%d\t%d\t%d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

}

//哈弗曼的编码

for (i=1;i<=n;i++)  {    

d.start=n+1;

            c=i;

f=HT[i].parent;

while(f){

if(HT[f].lchild==c)

d.cd[--d.start]='0';

else

d.cd[--d.start]='1';

c=f;

f=HT[f].parent;

}

hcd[i]=d;

}   

printf("哈夫曼编码:\n");  

printf("结点信息\t权值\t哈夫曼编码\n");

for (i=1;i<=n;i++)  {   

printf("%c\t\t%d\t",HT[i].data,HT[i].weight);   

for ( k=hcd[i].start;k<=n;k++)   

printf("%c",hcd[i].cd[k]);  

    printf("\n");

}

char str[20];     

printf("请输入译文:\n");     

scanf("%s",str);     

printf("译码后为:");

Coding(HT, hcd,n,str);

}

void main(){

HuffmanTree HT;

int n,j;

printf("元素个数");scanf("%d",&n);

HuffmanCoding(HT, n);   

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值