问题 H : 算法6 - 12:自底向上的赫夫曼编码

 

目录

 代码



 代码

#include<bits/stdc++.h>
using namespace std;
typedef char* HuffmanCode;
const int MAXN = 110;
typedef struct {
    int weight;
    int lchild, rchild, parent;
}HuffmanNode, * HuffmanTree;

void seletMin(HuffmanTree HT, int n, int& s1, int& s2) {
    int min = INT32_MAX;
    for (int i = 1; i <= n; ++i) {
        if (HT[i].parent == 0 && min > HT[i].weight) {
            min = HT[i].weight;
            s1 = i;
        }
    }
    min = INT32_MAX;
    for (int j = 1; j <= n; ++j) {
        if (HT[j].parent == 0 && min > HT[j].weight && j != s1) {
            min = HT[j].weight;
            s2 = j;
        }
    }

    if (s1 > s2) {
        swap(s1, s2);
    }
}
void HuffmanCoding(HuffmanTree& HT, HuffmanCode*& HC, int w[], int n) {
    if (n <= 1) return;
    int m = 2 * n - 1;
    //0号单元未用
    HT = new HuffmanNode[m + 1];

    for (int i = 1; i <= n; ++i) {
        HT[i].weight = w[i];
        HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
    }

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


    for (int i = n + 1; i <= m; ++i)//建立哈夫曼树
    {
        int s1, s2;
        //在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1,s2
        seletMin(HT, i - 1, s1, s2);
        HT[s1].parent = HT[s2].parent = i;
        HT[i].lchild = s1;
        HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;

    }
    HC = new HuffmanCode[n + 1];
    char* cd = new char[n];//分配编码工作空间

    cd[n - 1] = '\0';//编码结束符

    for (int i = 1; i <= n; ++i)//逐个字符求哈夫曼编码
    {
        int star = n - 1;//编码结束位置
        for (int c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
        {
            //从叶结点到根逆向求编码
            if (HT[f].lchild == c) {
                cd[--star] = '0';
            }
            else {
                cd[--star] = '1';
            }
        }
        //为第i个字符串编码分配空间
        HC[i] = new char[n - star];
        //从cd复制编码(串)到HC
        strcpy(HC[i], cd + star);
    }
    delete[]cd;//释放工作空间
}

int main() {
    HuffmanTree HT;
    HuffmanCode* HC;
    int n;
    int data[MAXN];

    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &data[i]);
        }

        HuffmanCoding(HT, HC, data, n);

        for (int j = 1; j <= n; ++j) {
            //printf("%s\n", HC[j]);
            std::cout << HC[j] << std::endl;
        }

        delete(HT);
        delete(HC);
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值