【数据结构基础】哈夫曼编码

来源:互联网 发布:java解析pdf文件内容 编辑:程序博客网 时间:2024/05/18 00:39

描述:
根据任意给定的一组权值,构造一棵哈夫曼树。具体要求如下:
① 权值的个数以及每个权值由运行时由键盘输入。
② 构造完哈夫曼树后,输出每个权值的哈夫曼编码。
③ 输出哈夫曼树的带权路径长度WPL。

code

#include<stdio.h>#include<stdlib.h>#define N 20typedef struct {    char ch;    int weight;    int lchild, rchild, parent;}Htnode;typedef struct{    char *code;    int length;}CodeType;void Huftree_WPL(int n,Htnode huftree[]);//选择排序法 找1~n+i-1中parent不等于-1,且权值最小的两个结点void Select(Htnode huftree[], int len, int *s1, int *s2) {     int i = 1, j, min1, min2;    while (i <= len) {//找到*s1         if (i <= len && huftree[i].parent == -1) {            min1 = i;            for (j = i; j <= len; j++) {                if (huftree[min1].weight >= huftree[j].weight && huftree[j].parent == -1) {                    min1 = j;                }            }            *s1 = min1;            break;        }        else {            i++;        }    }    i = 1;    while (i <= len) {//找到*s2         if (i <= len && huftree[i].parent == -1 && i != min1) {            min2 = i;            for (j = i; j <= len; j++) {                if (huftree[min2].weight >= huftree[j].weight && huftree[j].parent == -1 && huftree[j].weight >huftree[*s1].weight) {                    min2 = j;                }            }            *s2 = min2;            break;        }        else {            i++;        }    }}//建立哈夫曼树void Hufcoding(Htnode huftree[], int w[], int n,CodeType cd[]) {    int i, m, sum;    int c,k,f,j;    char temp[N];    m = n * 2 - 1;    for (i = 1; i <= n; i++) {        huftree[i].weight = w[i - 1];        huftree[i].parent = -1;        huftree[i].lchild = -1;        huftree[i].rchild = -1;    }    for (i = n + 1; i <= m; i++) {        huftree[i].weight = -1;        huftree[i].lchild = -1;        huftree[i].rchild = -1;        huftree[i].parent = -1;    }    //初始化哈夫曼树     for (i = 1; i <= m; i++) {        printf("huftree[%d].weight=%d\t huftree[%d].lchild=%d\t huftree[%d].rchild=%d\n ", i, huftree[i].weight, i, huftree[i].lchild, i, huftree[i].rchild);    }    //生成哈夫曼树     for (i = 1; i <= n - 1; i++) {        int s1, s2;        Select(huftree, n + i - 1, &s1, &s2);        sum = huftree[s1].weight + huftree[s2].weight;        huftree[s1].parent = n + i;        huftree[s2].parent = n + i;        huftree[n + i].lchild = s1;        huftree[n + i].rchild = s2;        huftree[n + i].weight = sum;    }    for (i = 1; i <= m; i++) {        printf("huftree[%d].weight=%d \t huftree[%d].lchild=%d \t huftree[%d].rchild=%d\t huftree[%d].parent=%d\n", i, huftree[i].weight, i, huftree[i].lchild, i, huftree[i].rchild,i,huftree[i].parent);    }//  哈夫曼编码     for(i=1;i<=n;i++){        c=0;        cd[i].length=0;        for(k=i,f=huftree[i].parent;f!=-1;k=f,f=huftree[f].parent){            if(huftree[f].lchild==k){                temp[c]='0';                c++;                cd[i].length++;            }            else{                temp[c]='1';                c++;                cd[i].length++;            }        }        cd[i].code=(char*)malloc(c+1);        cd[i].code[c]='\0';        c--;        k=0;        while(c>=0){            cd[i].code[k++]=temp[c--];        }     }    for(i=1;i<=n;i++){        for(j=0;j<cd[i].length;j++){            printf("%c",cd[i].code[j]);        }        printf("\n");               }    Huftree_WPL(n,huftree);     }void Huftree_WPL(int n,Htnode huftree[]){    int i,WPL=0;    for(i=n+1;i<=2*n-1;i++){        WPL+=huftree[i].weight;    }    printf("\n%d\n",WPL);}int main(void) {    Htnode huftree[2 * N];    int len,i;    int w[N];    CodeType cd[2*N];    while(~scanf("%d",&len)){        for(i=0;i<len;i++){            scanf("%d",&w[i]);        }        Hufcoding(huftree, w,len,cd);    }    return 0;}

初始化哈夫曼树

生成哈夫曼树与哈夫曼编码及WPL

0 0