题目描述 给定n个字符的权值(权值均是大于0的正整数),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC。 注意:在构造赫夫曼树HT时,序号小的权值放在左边,不是权值小的放左边!(序号:与权值输入的顺序相对应,序号由小到大) 输入 先输入权值的个数n(n>1)。 然后依次输入n个权值(权值均是大于0的正整数) 输出 与输入的n个权值相对应,依次输出对应的编码。 编码时,左孩子分支编码为0,右孩子分支编码为1。 样例输入 Copy 8 5 29 7 8 14 23 3 11 样例输出 Copy 0110 10 1110 1111 110 00 0111 010
#include<stdio.h> #include<string.h> #define maxsize 100000 struct fff { int start; int len[maxsize]; int weight; }code[100],cd; struct tree { int weight; int parent; int lchild; int rchild; }T[100]; int a[300]; int main() { int n,k,i,j,m,m1,m2,x1,x2,pare,child; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&k); T[i].weight=k; T[i].lchild=-1; T[i].rchild=-1; T[i].parent=-1; } m=2*n-1; for(i=n;i<m;i++) { T[i].lchild=-1; T[i].rchild=-1; T[i].parent=-1; T[i].weight=0; } for(i=0;i<n-1;i++) { m1=m2=1000000000;//记录权值 x1=x2=0;//记录 节点所在位置 for(j=0;j<n+i;j++) { if(T[j].weight<m1&&T[j].parent==-1) { m2=m1; x2=x1; m1=T[j].weight; x1=j; } else if(T[j].weight<m2&&T[j].parent==-1) { m2=T[j].weight; x2=j; } } T[x1].parent=n+i; T[x2].parent=n+i; T[n+i].weight=T[x1].weight+T[x2].weight; if(x1<x2) { T[n+i].lchild=x1; T[n+i].rchild=x2; } else { T[n+i].lchild=x2; T[n+i].rchild=x1; } } for(i=0;i<n;i++) { cd.start=n-1; child=i; pare=T[child].parent; while(pare!=-1) { if(T[pare].lchild==child) cd.len[cd.start]=0; else cd.len[cd.start]=1; cd.start--; child=pare; pare=T[child].parent; } for(j=cd.start+1;j<n;j++) { code[i].len[j]=cd.len[j]; } code[i].start=cd.start+1; code[i].weight=T[i].weight; } for(i=0;i<n;i++) { for (j=code[i].start; j < n; j++) { printf ("%d", code[i].len[j]); } printf("\n"); } return 0; }