Huffman编码的实现

Description
由键盘输入一组整数,作为权值序列,求赫夫曼编码并输出。
Input
输入为两行数据,第一行是一个整数,作为输入权值的个数(<=10),第二行为权值序列。
Output
输出为权值序列对应的赫夫曼编码,每个编码输出一行
Sample Input
4
4 3 2 1
Sample Output
4:0
3:10
2:110
1:111

#include<bits/stdc++.h>
using namespace std;
#define MIN 0x7fffffff
int arr[10000];
int n;
typedef struct {
    unsigned int weight;//权重
    unsigned int parent,lchild,rchild;//父亲节点,左孩子节点,右孩子节点
}HTNode,*HuffmanTree;

typedef char* *HuffmanCode;

void Select(HuffmanTree &HT,int n,int &min1,int &min2){//选择最小的且父亲节点为0的2个节点
    unsigned int mini=MIN;
    for(int i=1;i<=n;i++){
        if(HT[i].parent==0){
            if(HT[i].weight<mini){//找最小权重的节点
                min1=i;
                mini=HT[i].weight;
            }
        }
    }
    mini=MIN;
    for(int i=1;i<=n;i++){
        if(i==min1) continue;
        if(HT[i].parent==0){//找第2个权重最小的节点
            if(HT[i].weight<mini){
                min2=i;
                mini=HT[i].weight;
            }
        }
    }
    if((min2<min1)){//大小排序
        int temp;
        temp = min1;
        min1 = min2;
        min2 = temp;
    }
}


void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n){//哈夫曼树的创建与编码

    if(n <= 1) return;//节点个数为1或0直接返回
    int m;
    m=2*n-1;//树的总的节点
    HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));//创建一棵HT树
    int i;
    for(i=1;i<=n;i++){//先初始化n个节点
        HT[i].weight = arr[i-1];
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }
    for(;i<=m;i++){//初始化剩下的节点
        HT[i].weight = 0;
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }
    for(int i=n+1;i<=m;i++){
        int s1,s2;
        Select(HT,i-1,s1,s2);
        HT[s1].parent = i;
        HT[s2].parent = i;
        HT[i].weight = HT[s1].weight+HT[s2].weight;
        HT[i].lchild = s1;
        HT[i].rchild = s2;
    }

    HC = (HuffmanCode)malloc((n+1) * sizeof(char *));//开始树的编码
    char *ch;
    ch = (char *)malloc(n * sizeof(char));
    ch[n-1]='\0';
    for(int i=1;i<=n;++i){
        int k=n-1;
        for(int j=i,f=HT[i].parent;f!=0;j=f,f=HT[f].parent){//编码
            if(HT[f].lchild==j)
                ch[--k]='0';//左为0
            else
                ch[--k]='1';//右为1
        }
        HC[i] = (char *)malloc((n-k) * sizeof(char));
        strcpy(HC[i],&ch[k]);
    }
    free(ch);//回收
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }
    HuffmanTree HT;
    HuffmanCode HC;
    HuffmanCoding(HT,HC,n);
    for(int i=1;i<=n;i++){
        printf("%d:%s\n",arr[i-1],HC[i]);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值