问题 B: 算法6-13:自顶向下的赫夫曼编码

题目描述

在本题中,我们将要讨论的是自顶向下的赫夫曼编码算法。从根出发,遍历整棵赫夫曼树从而求得各个叶子结点所表示的字符串。算法的关键部分可以表示如下:

在本题中,读入n个字符所对应的权值,生成赫夫曼编码,并依次输出计算出的每一个赫夫曼编码。

 

输入

输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。

第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。

输出

共n行,每行一个字符串,表示对应字符的赫夫曼编码。

样例输入

<span style="color:#333333">8
5 29 7 8 14 23 3 11
</span>

样例输出

<span style="color:#333333">0110
10
1110
1111
110
00
0111
010
</span>

提示

 

在本题中,与上一题不同的是在求赫夫曼编码的过程中,使用了从根出发开始遍历整棵赫夫曼树的自顶向下的算法。通过这两道题目的联系,应该能够熟练的掌握赫夫曼树和赫夫曼编码的构造和使用方法了。

#define MAX_SIZE 100005
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int arr[105], n;
struct HT
{
    int weight;
    int parent, lch, rch;
    string code;
};
HT *huffTree;
string *hfCode;
string hashtable[MAX_SIZE];
void selectMinTwo(int high, int &s1, int &s2)
{
    int min = INT32_MAX;
    for (int i = 1; i <= high; i++)
    {
        if (huffTree[i].parent == 0 && min > huffTree[i].weight)
        {
            min = huffTree[i].weight;
            s1 = i;
        }
    }
    min = INT32_MAX;
    for (int i = 1; i <= high; i++)
    {
        if (huffTree[i].parent == 0 && min > huffTree[i].weight && i != s1)
        {
            min = huffTree[i].weight;
            s2 = i;
        }
    }
    if (s1 > s2)
    {
        swap(s1, s2);
    }
}
void HuffmanCoding()
{
    int m, i;
    if (n <= 1)
        return;
    m = 2 * n - 1;
    huffTree = new HT[m + 1];
    for (i = 1; i <= n; i++)
    {
        huffTree[i].weight = arr[i];
        huffTree[i].lch = huffTree[i].rch = huffTree[i].parent = 0;
    }
    for (i = n + 1; i <= m; ++i)
    {
        huffTree[i].lch = huffTree[i].rch = huffTree[i].parent = 0;
    }
    for (i = n + 1; i <= m; i++)
    {
        int s1, s2;
        selectMinTwo(i - 1, s1, s2);
        huffTree[i].weight = huffTree[s1].weight + huffTree[s2].weight;
        huffTree[i].lch = s1, huffTree[i].rch = s2;
        huffTree[s1].parent = huffTree[s2].parent = i;
    }
 
    hfCode = new string[n + 1];
    fill(hfCode,hfCode+n+1,"");
    for (i = 1; i <= m; i++)
    {
        huffTree[i].weight = 0;
    }
    int index = m;
    string codet = "";
    while(index){
        if(huffTree[index].weight == 0){
            huffTree[index].weight = 1;
            if(huffTree[index].lch!=0){
                codet = codet + '0';
                index = huffTree[index].lch;
            }else {
                hfCode[index] = codet;
            }
        }else if(huffTree[index].weight == 1){
            huffTree[index].weight = 2;
            if(huffTree[index].rch !=0){
                codet = codet + '1';
                index=huffTree[index].rch;
            }
        }else{
            index = huffTree[index].parent;
            codet = codet.substr(0,codet.length()-1);
            //huffTree[index].weight = 0;
        }
    }
}
int main()
{
    int i;
    while (cin >> n)
    {
        for (i = 1; i <= n; i++)
        {
            cin >> arr[i];
        }
        HuffmanCoding();
        for (i = 1; i <= n; i++)
        {
            cout << hfCode[i] << endl;
        }
        delete[] huffTree;
        delete[] hfCode;
    }
    return 0;
}
 
/**************************************************************
    Problem: 1761
    User: morizunzhu
    Language: C++
    Result: 正确
    Time:0 ms
    Memory:5144 kb
****************************************************************/

猜你喜欢

转载自blog.csdn.net/Morizunzhu/article/details/81489588