最优前缀码

问题

在这里插入图片描述
在这里插入图片描述

解析

在这里插入图片描述
在这里插入图片描述

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

#define n 6           
#define m 2*n-1       
typedef struct{       
    double weight;    
    int parent,lchild,rchild;
}HTNode;

typedef HTNode HuffmanTree[m];

 

typedef struct{      
    int id;           
    double weight;    
}temp;

typedef struct{       
    char ch;         
    char bits[n+1];   
}CodeNode;

typedef CodeNode HuffmanCode[n];


void InitHuffmanTree(HuffmanTree T){

    for(int i=0;i<m;i++){
        T[i].lchild=-1;
        T[i].rchild=-1;
        T[i].parent=-1;
        T[i].weight=0;
    }
}

void InputWeight(HuffmanTree T){


    for(int i=0;i<n;i++){
        double x;
        scanf("%lf",&x);
        T[i].weight=x;
    }
}

bool cmp(temp a,temp b){
    return a.weight<b.weight;
}

 

void SelectMin(HuffmanTree T,int k,int *p1,int *p2){
    temp x[m];            
    int i,j;
    for(i=0,j=0;i<=k;i++){  //寻找最小和次小根节点的过程
        if(T[i].parent==-1){
            x[j].id=i;      
            x[j].weight=T[i].weight;
            j++;           
        }
    }
    sort(x,x+j,cmp);      

    *p1=x[0].id;
    *p2=x[1].id;
}

 

void CreateHuffmanTree(HuffmanTree T){
    int i,p1,p2;

    InitHuffmanTree(T);  
    InputWeight(T);       
    for(i=n;i<m;i++){
        SelectMin(T,i-1,&p1,&p2);//选择权值最小和次小的根结点,其序号分别为p1和p2
        T[p1].parent=T[p2].parent=i;
        T[i].lchild=p1;           
        T[i].rchild=p2;            
        T[i].weight=T[p1].weight+T[p2].weight;
    }
}

 

void CharSetHuffmanEncoding(HuffmanTree T,HuffmanCode H){

    int c,p;
    char cd[n+1];
    int start;
    cd[n]='\0';
    getchar();
    for(int i=0;i<n;i++){
        H[i].ch=getchar();
        start=n;
        c=i;
        while((p=T[c].parent)>=0){
            if(T[p].lchild==c)
                cd[--start]='0';
            else
                cd[--start]='1';
            c=p;
        }

        strcpy(H[i].bits,&cd[start]);
    }
}

int main(){
    HuffmanTree T;
    HuffmanCode H;
    printf("请输入%d个叶子结点的权值来建立哈夫曼树:\n",n);
    CreateHuffmanTree(T);
    printf("请输入%d个叶子结点所代表的字符:\n",n);
    CharSetHuffmanEncoding(T,H);
    printf("哈夫曼树已经建好,哈夫曼编码已经完成,输出如下:\n");
    printf("哈夫曼树:\n");
    for(int i=0;i<m;i++){
        printf("id:%d  weight:%.1lf   parent:%d",i,T[i].weight,T[i].parent);
        printf("  lchild:%d rchild:%d\n",T[i].lchild,T[i].rchild);
    }
    printf("哈夫曼编码:\n");
    double wpl=0.0;
    for(int i=0;i<n;i++){
        printf("id:%d   ch:%c  code:%s\n",i,H[i].ch,H[i].bits);
        wpl+=strlen(H[i].bits)*T[i].weight;
    }
    printf("平均码长为:%.2lf\n",wpl);
    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值