哈弗曼编码

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define MAXNUM 10
#define MAXBIT 10
#define MINWEIGHT 1000000

typedef struct
{
    char value;                          // 输入结点代号,如A, B, C...
     int  parent;                        /* 父子关系用下标值进行关联 */
    int  lchild;
    int  rchild;
    int  weight;                         // 自身权重
}HTNODE;
typedef struct
{
    char bit[MAXBIT];                    // 存储编码
}HTCODE;
/******************************************************************************************/

void Init(int &n, HTNODE *HTNode)
{
    cout << "Input the Number of Object, n = "; cin >> n;
    for(int i = 0; i < n; i++)
    {
        HTNode[i].value = 65 + i;                        // 默认代号A, B, C...
        HTNode[i].parent = -1;
        HTNode[i].lchild = -1;
        HTNode[i].rchild = -1;
        cout << "weight[" << i << "] = ";
        cin >> HTNode[i].weight;
    }
    int m = 2 * n - 1;
    for(int i = n; i < m; i++)
    {
        HTNode[i].value = '*';                           // 合成结点代号
        HTNode[i].parent = -1;
        HTNode[i].lchild = -1;
        HTNode[i].rchild = -1;
        HTNode[i].weight = 0;
    }
}
void Select(int &fstSmallest, int &sndSmallest, HTNODE *HTNode, int i)
{
    fstSmallest = -1;
    sndSmallest = -1;
    int fstSWeight = MINWEIGHT;
    int sndSWeight = MINWEIGHT;
    for(int k = 0; k < i; k++)
    {
        if(HTNode[k].parent == -1)
        {
            if(HTNode[k].weight <= fstSWeight)
            {
                sndSmallest = fstSmallest;
                sndSWeight = fstSWeight;
                fstSmallest = k;
                fstSWeight = HTNode[k].weight;
            }
            else if(HTNode[k].weight>fstSWeight && HTNode[k].weight<sndSWeight)
            {
                sndSmallest = k;
                sndSWeight = HTNode[k].weight;
            }
        }
    }
}
void BuildHuffmanTree(int n, HTNODE *HTNode)
{
    int m = 2 * n - 1;                                // 可计算出哈夫曼树结点总数
    int fstSmallest, sndSmallest;                     // 分别标记下标值
    for(int i = n; i < m; i++)
    {
        Select(fstSmallest, sndSmallest, HTNode, i);
        HTNode[fstSmallest].parent = i;
        HTNode[sndSmallest].parent = i;
        HTNode[i].lchild = fstSmallest;
        HTNode[i].rchild = sndSmallest;
        HTNode[i].weight = HTNode[fstSmallest].weight + HTNode[sndSmallest].weight;
    }
}
void PrintHuffmanTree(int n, HTNODE *HTNode)
{
    int m = 2 * n - 1;
    for(int i = 0; i < m; i++)
    {
        cout << "\ni = " << i;
        printf("  value = %c", HTNode[i].value);
        printf("  parent = %2d", HTNode[i].parent);
        printf("  lchild = %2d", HTNode[i].lchild);
        printf("  rchild = %2d", HTNode[i].rchild);
        printf("  weight = %2d", HTNode[i].weight);
        cout << endl;
    }
}
void HuffmanCoding(int n, HTNODE *HTNode, HTCODE *HTCode)
{
    int j, start;
    char Tbit[MAXBIT];
    for(int i = 0; i < n; i++)                                   /* 编码i结点 */
    {
        start = MAXBIT-1;
        int temp_child = i;                                      // 临时孩子
        int temp_parent = HTNode[i].parent;                      // 临时父亲
        while(temp_parent != -1)
        {
            cout << "temp_child = " << temp_child;               // Debug 编码过程
            cout << "  temp_parent = " << temp_parent << endl;   // Debug 编码过程
            if(HTNode[temp_parent].lchild == temp_child)
                Tbit[--start] = '0';
            else Tbit[--start] = '1';
            temp_child = temp_parent;
            temp_parent = HTNode[temp_child].parent;
        }
        strcpy(HTCode[i].bit, &Tbit[start]);
        cout << "bit = " << HTCode[i].bit << endl;               // Debug 编码过程
    }
}
void HuffmanDecoding(int n, HTNODE *HTNode)
{
    int it, flag = 1;
    int m = 2 * n - 1;
    char str[MAXBIT], *p;
    printf("\nInput the String, str = ");
    scanf("%s", str); p = str;

    for(int i = 0; i < m; i++)                                   // 先定位到根节点
        if(HTNode[i].parent == -1)
        { it = i; break; }
    while(*p != '\0')
    {
        if(HTNode[it].lchild==-1 && HTNode[it].rchild==-1)       // 编码串过长
        { flag = -1; break; }
        if(p[0] == '0')
            it = HTNode[it].lchild;
        else it = HTNode[it].rchild;
        p++;
    }
    if(HTNode[it].lchild!=-1 && HTNode[it].rchild!=-1)           // 编码串过短
    { flag = -1; }
    if(flag == -1) printf("Input String is Error!\n");
    else printf("Decoding Result is: %c\n", HTNode[it].value);
}
/******************************************************************************************/

int main()
{
    int n;
    HTNODE HTNode[MAXNUM];                     // MAXNUM表示哈夫曼树结点数上限
    HTCODE HTCode[MAXNUM];
    Init(n, HTNode);
    BuildHuffmanTree(n, HTNode);
    PrintHuffmanTree(n, HTNode);
    HuffmanCoding(n, HTNode, HTCode);
    HuffmanDecoding(n, HTNode);
    return 0;
}

 

 

posted on 2015-07-16 10:57  huashunli  阅读(155)  评论(0编辑  收藏  举报

导航