您的位置:首页 > 理论基础 > 数据结构算法

数据结构之构造哈夫曼树及哈夫曼编码

2013-12-15 10:54 429 查看
一、实验目的

1、了解哈夫曼树的概念,掌握哈夫曼树的存贮结构和构造方法。

2、掌握哈夫曼树构造的算法,掌握哈夫曼树编码的形成及特点。

二. 实验内容与要求

1.设计哈夫曼树的存贮结构。

2. 自行设计若干个字符信息及权值,根据哈夫曼树的构造方法,建立一棵二叉树。

3. 根据建立的哈夫曼树,对其中字符信息进行哈夫曼编码,并输出其编码。

4. 实现提示:

首先定义哈夫曼树的存贮结构,再建立一棵哈夫曼树。最后根据哈夫曼树的编码规则,对其编码。

要求有相应的交互信息。

#include <stdio.h>

#include <string.h>

#define N 50 //叶子节点数

#define M 2*N-1 //树中节点总数

typedef struct

{

char data[5];
//节点值

int weight;
//权重

int parent;
//双亲节点

int lchild;
//左孩子节点

int rchild;
//右孩子节点

} HTNode;

typedef struct

{

char cd
;
//存放哈夫曼码

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++)
//所有节点的相关域置初值-1

ht[i].parent=ht[i].lchild=ht[i].rchild=-1;

for (i=n;i<2*n-1;i++)
//构造哈夫曼树

{

min1=min2=32767;
//lnode和rnode为最小权重的两个节点位置

lnode=rnode=-1;

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

if (ht[k].parent==-1)
//只在尚未构造二叉树的节点中查找

{

if (ht[k].weight<min1)

{

min2=min1;rnode=lnode;

min1=ht[k].weight;lnode=k;

}

else if (ht[k].weight<min2)

{

min2=ht[k].weight;rnode=k;

}

}

ht[lnode].parent=i;ht[rnode].parent=i;

ht[i].weight=ht[lnode].weight+ht[rnode].weight;

ht[i].lchild=lnode;ht[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("输出哈夫曼编码:");

printf("\n");

for (i=0;i<n;i++)

{

j=0;

printf(" %s:\t",ht[i].data);

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

{

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

j++;

}

m+=ht[i].weight;

sum+=ht[i].weight*j;

printf("\n");

}

printf("平均长度=%g\n",1.0*sum/m);

}

void main()

{

int n=15,i,j;

char *str[]={"The","of","a","to","and","in","that","he","is","at","on","for","His","are","be"};

int fnum[]={1192,677,541,518,462,450,242,195,190,181,174,157,138,124,123};

HTNode ht[M];

HCode hcd
;

{

printf("\n\n********************************************************");

printf("\n\n********************************************************");

printf("\n*** 哈弗曼树的操作 ***\n\n");

printf("*** 请选择: ***\n\n");

printf("*** 1:哈夫曼树的字符信息 ***\n\n");

printf("*** 2:哈夫曼树对应权值 ***\n\n");

printf("*** 3:哈夫曼编码及平均长度: ***\n\n");

printf("*** 0:退出 ***");

printf("\n\n********************************************************");

printf("\n\n********************************************************");

}

while(1)

{

printf("\n选择进行的操作");

do

{

scanf("%d",&j);

if(j<0||j>3)

printf("输入错误,请重新输入\n");

}while(j<0||j>3);

switch(j)

{ case 1: printf("哈夫曼树的字符信息:The,of,a,to,and,in,that,he,is,at,on,for,His,are,be");

printf("\n");

break;

case 2:

printf("哈夫曼树对应的权值:1192,677,541,518,462,450,242,195,190,181,174,157,138,124,123");

printf("\n");

break;

case 3: for (i=0;i<n;i++)

{

strcpy(ht[i].data,str[i]);

ht[i].weight=fnum[i];

}

CreateHT(ht,n);

CreateHCode(ht,hcd,n);

DispHCode(ht,hcd,n);

printf("\n");

break;

case 0: break;

default:

printf("输入错误,请重新输入:");

break;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: