哈夫曼树的应用与实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*哈夫曼树的应用和实现

(1)根据输入的字符和相应的权值建立哈夫曼树,并输出已建的相应内容作

为检查;

(2)用哈夫曼树实现前缀编码,并输出各字符的编码串;

(3)输入一组二进制报文,进行译码,并输出译文。*/

#include

#include

#include

#include

#define N 1000 //定义结点数最大值

#define M 2*N-1

#define maxval 10000.0 //定义float的最大值

typedef struct //定义哈夫曼树类型

{

char data;

float weight;

int lchild,rchild,parent;

}hufmtree;

hufmtree tree[M];

typedef struct //定义哈夫曼树编码类型

{

char bits[N];

int start;

char data;

}codetype;

codetype code[N];

void HUFFMAN(hufmtree t[]);

void HUFFMANCODE(codetype code[],hufmtree t[]);

void HUFFMANDECODE(codetype code[],hufmtree t[]);

void OUTTREE(hufmtree t[]);

static int n,m; //定义静态全局变量n储存需要的结点数

//m为构建哈夫曼树后的总结点数

//菜单的建立

void main()

{

int x,flag1=0;

printf("\t\t\t哈夫曼树的应用和实现\n");

while(1)

{

printf("——————————————————————————————————\n");

printf("菜单:1 建立哈夫曼树 2 哈夫曼树编码 3 输入电文译码0 退出使用\n");

printf("——————————————————————————————————\n");

printf("请选择操作:\n");

scanf("%d",&x);

switch(x)

{

case 1:

HUFFMAN(tree);

break;

case 2:

HUFFMANCODE(code,tree);

break;

case 3:

HUFFMANDECODE(code,tree);

break;

case 0:

flag1=1; //输入号为0时使flag1=1

break;

default:

printf("输入的选择有误!请重新输入!\n");

break;

}

if(flag1) break; //表明选择了退出操作故跳出循环

}

printf("Thank You!\n");

}

//哈夫曼树的构建

void HUFFMAN(hufmtree t[])

{

int i,j,p1,p2;

char ch;

float small1,small2,f;

printf("请输入叶子结点数:\n");

scanf("%d",&n);

m=2*n-1;

for(i=0;i

{

tree[i].parent=0;

tree[i].lchild=0;

tree[i].rchild=0;

tree[i].data='0';

tree[i].weight=0.0;

}

for(i=0;i

{

getchar(); //getchar 吃掉回车

printf("请输入第%d个结点的字符和权重(空格隔开):\n",i);

scanf("%c %f",&ch,&f); //输入结点字符和权重

tree[i].data=ch;

tree[i].weight=f;

}

for(i=n;i

{

p1=0;p2=0; //预置最小次小权值的下标为0

small1=maxval; //预置最小次小权值为float型最大值

small2=maxval;

for(j=i-1;j>=0;j--) //循环找出最小、次小权值和下标

if(tree[j].parent==0)

if((tree[j].weight-small1)<0.0001) //float精度,当两者之差小于0.0001认为相等

{

small2=small1; //小于当前最小权值,更新最小权值和次小权值以及位置

small1=tree[j].weight;

p2=p1;

p1=j;

}

else

if((tree[j].weight-small2)<0.0001) //小于当前次小权值,更新次小权值和位置

{

small2=tree[j].weight;

p2=j;

}

tree[p1].parent=i; //修改最小、次小结点的双亲为新生成的结点

tree[p2].parent=i;

tree[i].lchild=p1; //新结点的左右孩子指向最小次小值的结点

相关文档
最新文档