[实验内容]1、建立哈夫曼树;2、哈夫曼编码、解码。 【实验测试数据】 #include "stdio.h" #include "stdlib.h" #include "string.h" typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/ /*哈夫曼树类型定义*/ typedef struct { char letter; int weight; /*结点的权值*/ int parent; /*双亲的下标*/ int LChild; /*左孩子结点的下标*/ int RChild; /*右孩子结点的下标*/ }HTNode,*HuffmanTree;/*HuffmanTree是结构数组类型*/ /*在1~i-1范围内选择两个parent为0且weight最小的结点,其序号分别赋给s1、s2返回*/ void select(HuffmanTree *ht,int n, int *s1, int *s2) { int i; int min; for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { min = i; i = n+1; } } for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { if((*ht)[i].weight < (*ht)[min].weight) min = i; } } *s1 = min; for(i=1; i<=n; i++) { if((*ht)[i].parent == 0 && i!=(*s1)) { min = i; i = n+1; } } for(i=1; i<=n; i++) { if((*ht)[i].parent == 0 && i!=(*s1)) { if((*ht)[i].weight < (*ht)[min].weight) min = i; } } *s2 = min; } /*创建哈夫曼树算法*/ void CrtHuffmanTree(HuffmanTree *ht,int w[50],int n) {/*构建哈夫曼树ht[M+1],w[]存放n个权值*/ int i,m; int s1,s2; m=2*n-1; *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0号单元未使用*/ for(i=1;i<=n;i++) { (*ht)[i].letter=i+64; (*ht)[i].weight = w[i]; (*ht)[i].LChild = 0; (*ht)[i].parent = 0; (*ht)[i].RChild = 0;/*1~n号单元存放非页结点,初始化*/ } for(i=n+1;i<=m;i++) { (*ht)[i].weight = 0; (*ht)[i].LChild = 0; (*ht)[i].parent = 0; (*ht)[i].RChild = 0; } for(i=n+1;i<=m;i++) { select(ht,i-1,&s1,&s2); /*在1~i-1范围内选择两个parent为0且weight最小的结点,其序号分别赋给s1、s2返回*/ (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight; (*ht)[s1].parent=i; (*ht)[s2].parent=i; (*ht)[i].LChild=s1; (*ht)[i].RChild=s2; } } /*输出哈夫曼树*/ void outputHuffman(HuffmanTree ht, int m) { if(m!=0) { printf("%d ", ht[m].weight); outputHuffman(ht,ht[m].LChild); outputHuffman(ht,ht[m].RChild); } } /*哈夫曼编码算法*/ void CrtHuffmanCode(HuffmanTree *ht,HuffmanCode *hc,int n) /*从叶子结点到根,逆向求解每个叶子结点对应的哈夫曼编码*/ { char *cd; int i; int c; int start; int p; hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); /*分配n个编码的头指针*/ cd=(char*)malloc((n+1)*sizeof(char));/*分配当前编码的工作空间*/ cd[n-1]='\0';/*从左向右逐位存放编码,首先存放编码结束符*/ for(i=1;i<=n;i++) /*求n个叶子结点对应的哈夫曼编码*/ { start=n-1; /*初始化编码起始指针*/ c=i; p=(*ht)[i].parent; while(p!=0) { if( (*ht)[p].LChild == c) cd[--start]='0'; /*左分支标0*/ else cd[--start]='1'; /*右分支标1*/ c=p; p=(*ht)[p].parent; /*从叶子到根结点求编码*/ hc[i]=(char *)malloc((n-start)*sizeof(char)); /*为第i个编码分配空间*/ strcpy(hc[i],&cd[start]); } } free(cd); for(i=1;i<=n-1;i++) printf("letter:%c %d编码为%s\n",i+64,(*ht)[i].weight,hc[i]); printf("letter:%c %d编码为%s\n",0,(*ht)[i].weight,hc[i]); } /*主函数*/ void main() { HuffmanTree ht; HuffmanCode hc; int *w; int i,n; /*the number of elements; */ int wei; /* the weight of a element; */ int m; printf("input the total number of the Huffman Tree:" ); scanf("%d",&n); w=(int *)malloc((n+1)*sizeof(int)); for(i=1;i<=n;i++) { if(i<=n-1) printf("input the %c element's weight:",i+64); else printf("input the %c element's weight:",0); fflush(stdin); scanf("%d",&wei); w[i]=wei; } CrtHuffmanTree(&ht,w,n); m = 2*n-1; outputHuffman(ht,m); printf("\n"); CrtHuffmanCode(&ht,&hc,n); } 来源:https://www.cnblogs.com/5un5hine/archive/2009/12/07/2049336.html 标签 哈夫曼树