创建霍夫曼树,霍夫曼码的编码与解码(C++)

//字符集D = {A, B, C, D, E, F, G}
//概率分布W = {0.40, 0.30, 0.15, 0.05, 0.04, 0.03, 0.03}


#include <iostream>
#include <vector>
using namespace std; 
#define MAXSIZE 14
struct HaffNode //霍夫曼树结点
{
    double weight;
    int parent;
    int lChild;
    int rChild;
};
struct vectorEle 
{
    char data;
    vector<int>dataNode;
};
void selectMinIndex(HaffNode* arr, int i, int& minIndex01, int& minIndex02)
{
    //找到第一个最小值
    for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0) { minIndex01 = j; } }
    for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && arr[minIndex01].weight > arr[j].weight) { minIndex01 = j; } }
    //找到第二个最小值
    for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && j != minIndex01) { minIndex02 = j; } }
    for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && j != minIndex01 && arr[minIndex02].weight > arr[j].weight) { minIndex02 = j; } }
}
void createHaffmanTree(HaffNode* arr) //创建霍夫曼树
{
    cout << "请输入字符的权值:";
    for (int i = 1; i <= MAXSIZE / 2; i++)
    {
        cin >> arr[i].weight;
        arr[i].parent = arr[i].lChild = arr[i].rChild = 0;
    }

    for (int i = MAXSIZE / 2 + 1; i <= MAXSIZE - 1; i++)
    {
        int minIndex01, minIndex02;
        selectMinIndex(arr, i, minIndex01, minIndex02);
        arr[i].weight = arr[minIndex01].weight + arr[minIndex02].weight;
        arr[i].parent = 0;
        arr[i].lChild = minIndex01;
        arr[i].rChild = minIndex02;
        arr[minIndex01].parent = arr[minIndex02].parent = i;
    }
}
void createHaffmanCode(HaffNode* arr, vector<vectorEle>&v) //编霍夫曼码
{
    //编码(左分支标0,右分支标1,从叶子结点往根结点溯源)

    cout << "请输入对应的字符:";
    for (int i = 1; i <= MAXSIZE / 2; i++)
    {
        vectorEle ve;

        cin >> ve.data;
        int index = i;
        while (arr[index].parent != 0)
        {
            if (index == arr[arr[index].parent].lChild) { ve.dataNode.insert(ve.dataNode.begin(), 0); }
            else { ve.dataNode.insert(ve.dataNode.begin(), 1); }
            index = arr[index].parent;
        }

        v.push_back(ve);
    }

    //检测结果,打印各个字符的霍夫曼编码
    cout << "各字符对应的哈夫曼编码如下:" << endl;
    for (vector<vectorEle>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << it->data << ":";
        for (vector<int>::iterator vit = it->dataNode.begin(); vit != it->dataNode.end(); vit++) { cout << *vit; }
        cout << endl;
    }
}
void deHaffmanCode(HaffNode* arr, const vector<vectorEle>v) //解霍夫曼码
{
    cout << "请输入哈夫曼编码:";
    string haffmanCode;
    cin >> haffmanCode;
    vector<char>data; //存储解码结果

    int endIndex = 0; //每一次遍历哈夫曼编码后的 结束下标+1
    while (endIndex != haffmanCode.length())
    {
        int startIndex = endIndex;
        for (vector<vectorEle>::const_iterator it = v.begin(); it != v.end(); it++)
        {
            bool match = true;
            int index = startIndex;
            for (vector<int>::const_iterator vit = it->dataNode.begin(); vit != it->dataNode.end(); vit++)
            {
                if (haffmanCode[index] - '0' != *vit) { match = false; break; }
                else { index++; }
            }
            if (match) { data.push_back(it->data); endIndex = index; break; }
        }
    }

    //检测结果,打印解码后的字符
    cout << "解码结果:";
    for (vector<char>::iterator it = data.begin(); it != data.end(); it++) { cout << *it; }
    cout << endl;

}
int main() {
    HaffNode* arr = new HaffNode[MAXSIZE]; //存储霍夫曼树的一维数组
    vector<vectorEle>v; //存储字符的霍夫曼编码

    createHaffmanTree(arr);
    createHaffmanCode(arr, v);
    deHaffmanCode(arr, v);
    
    delete[] arr; //释放数组

    system("pause");
    return 0;
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值