哈弗曼数的应用

问题 A: DS_6.13 给定权值,哈弗曼编码、译码(by Yan)
时间限制: 20 Sec 内存限制: 256 MB
提交: 4 解决: 4
[提交][状态][讨论版]
题目描述
假设某通信报文的字符集由A,B,C,D,E,F这6个字符组成,它们在报文中出现的频度(频度均为整数值)。
(1)构造一棵哈弗曼树,依次给出各字符编码结果。
(2)给字符串进行编码。
(3)给编码串进行译码。

规定:
构建哈弗曼树时:左子树根结点权值小于等于右子树根结点权值。
生成编码时:左分支标0,右分支标1。

输入
第一行:依次输入6个整数,依次代表A,B,C,D,E,F的频度,用空格隔开。
第二行:待编码的字符串
第三行:待译码的编码串
输出
前6行依次输出各个字符及其对应编码,格式为【字符:编码】(冒号均为英文符号)
第7行:编码串
第8行:译码串
样例输入
3 4 10 8 6 5
BEE
0010000100111101
样例输出
A:000
B:001
C:10
D:01
E:111
F:110
001111111
BADBED

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 6
#define M 2*N-1
#define MAXINT 32767
#define ch 30
#define NUM 100
typedef char numcode[NUM];
typedef char charcode[ch];
typedef char* HuffmanCode[N] ;
typedef struct{
    int weight;
    int parent;
    int lchild;
    int rchild; 
}HTNode,HuffmanTree[M]; 



void select(HuffmanTree ht,int pos,int *s1,int *s2);

void CrtHuffmanTree(HuffmanTree ht,int w[],int n){
    int i,s1,s2,m;
    m=2*n-1;
    for(i=0;i<n;i++){
        ht[i].weight=w[i];ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    for(i=n;i<m;i++){
        ht[i].weight=0;ht[i].parent=-1;
        ht[i].lchild=-1;ht[i].rchild=-1;
    }
    /*选择 合并*/
    for(i=n;i<m;i++) {
        select(ht,i-1,&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 select(HuffmanTree ht,int pos,int *s1,int *s2){
    int i,j,m1,m2;/*m1存放最小权值,s1是m1在数组的下标*/
    m1=m2=MAXINT;/*m2存放次小权值,s2是m2在数组的下标*/ 
    for(j=0;j<=pos;j++) {
        if(ht[j].weight<m1&&ht[j].parent==-1){
            m2=m1;*s2=*s1;
            *s1=j;m1=ht[j].weight;
        }
        else if(ht[j].weight<m2&&ht[j].parent==-1){
            m2=ht[j].weight;
            *s2=j;
        }
    }
    /*if(*s1>*s2){//使s1小于s2
        i=*s1;*s1=*s2;*s2=i;        
    }*/
}

void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n){
    char *cd;int start,c,p,i;
    cd=(char*)malloc(n*sizeof(char));
    cd[n-1]='\0';   
    for(i=0;i<n;i++){
        start=n-1;c=i;
        p=ht[i].parent;
        while(p!=-1){
            --start;
            if(ht[p].lchild==c) cd[start]='0';
            else    cd[start]='1';
            c=p;p=ht[p].parent;
        }
        hc[i]=(char*)malloc((n-start)*sizeof(char));        
        //printf("%s\n",&cd[start]);
        strcpy(hc[i],&cd[start]);

    }
    free(cd);
}

void printcode(char s[],HuffmanCode hc){
    //printf("\n----%s----\n",hc[0]);
    for(int i=0;i<N;i++){
        printf("%c:",s[i]);
        printf("%s\n",hc[i]);

    }
}
void chartocode(charcode c,char s[],HuffmanCode hc){
    char *p=c;  
    while(*p!='\0'){    
        for(int j=0;j<N;j++){
            if(*p==s[j])
                printf("%s",hc[j]);
        }
        p++;
    }
    printf("\n");   
}
void  numtochar(numcode ns,HuffmanTree ht,char s[]){
    char *p=ns;int key;HTNode g;
    while(*p!='\0'){
        g=ht[M-1];
        //printf("\nht[M-1]=%d\n",g.weight);                
        while(g.lchild!=-1&&g.rchild!=-1&&(*p!='\0')){
            switch(*p){              
            case '0':key=g.lchild;g=ht[g.lchild];break;
            case '1':key=g.rchild;g=ht[g.rchild];break;
            }
            p++;
            //printf("P++=%c\n",*p);
        }
        printf("%c",s[key]);


    }
}
int main(){ 
    HuffmanTree ht;HuffmanCode hc;charcode c;numcode ns;
    char s[N]={'A','B','C','D','E','F'};
    int  w[N];

    for(int i=0;i<N;i++){
        scanf("%d",&w[i]) ;
    } 
    scanf("%s",&c);
    scanf("%s",&ns);
//  printf("\n") ;
//  for(int i=0;i<N;i++){
//      printf("%d",w[i]) ;
//  } 
//  printf("\n") ;

    CrtHuffmanTree(ht,w,6);


    CrtHuffmanCode(ht,hc,6);
    printcode(s,hc);
    chartocode(c,s,hc); 

    numtochar(ns,ht,s);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值