Huffman树

#include<iostream>
#include< algorithm >
using namespace std;
struct MinTuple
{
    int x;
    int y;
};
struct HNode
{
    int weight;
    int parent;
    int LChild;
    int RChild;
};
struct HCode
{
    char data;
    string code;
};
class Huffman
{
private:
    HNode* HTree;
    HCode* HCodeTable;
    int N;
    void code(int i, string newcode);
    
public:
    void CreateHTree(int a[], int n, char name[]);
    void CreateCodeTable();
    void Encode(char* s, char* d);
    void Decode(char* s, char* d);
    ~Huffman();
};
MinTuple SelectMin(HNode *s ,int start,int end)
{
    /*
    整体来看,我对自己写的这份取小代码还是很满意的,因为这里利用到了
    Huffman树的构建过程的特点,就是已经使用过的数据的双亲节点会不再是-1
    整体来讲问题不打,还有那两个赋值过程也比较聪明先赋值小的,如果不满足再看次小的*/
    /*可以从chatgpt上学到很多
    */
    MinTuple minimum = { -1,-1 };
    for (int j = start; j < end; j++)
    {
        if (s[j].parent==-1)
        {
            if (minimum.x == -1 || s[j].weight < s[minimum.x].weight)
            {
                minimum.y = minimum.x;
                minimum.x = j;
            }
            else if (minimum.y == -1 || s[j].weight < s[minimum.y].weight)
                minimum.y = j;
        }
    }
    return minimum;
}
void Huffman::CreateHTree(int a[], int n, char name[])
{
    N = n;
    HCodeTable = new HCode[N];
    HTree = new HNode[2 * N - 1];
    for (int i = 0; i < N; i++)
    {
        HTree[i].weight = a[i];
        HTree[i].LChild = HTree[i].RChild = HTree[i].parent = -1;
        HCodeTable[i].data = name[i];
    }
    //思考:目前  我需要从HTree的顺序表中每次挑选两个最小值,但是不能重复挑选
    //怎么去实现呢?而且需要将获得的新值加入进去,并且将使用过的删去
    //可以看他的双亲是否存在
    MinTuple m;
    for (int i = n; i < 2 * N; i++)
    {
        m=SelectMin(HTree, 0, i);//自行实现 从1~i中选出权值最小的两个点
        HTree[m.x].parent = HTree[m.y].parent = i;
        HTree[i].weight = HTree[m.x].weight + HTree[m.y].weight;
        HTree[i].LChild = m.x;
        HTree[i].RChild = m.y;
        HTree[i].parent = -1;
    }
}
void Huffman::code(int i, string newcode)
{
    if (HTree[i].LChild == -1)
    {
        HCodeTable[i].code = newcode;
        return;
    }
    code(HTree[i].LChild, newcode + "0");
    code(HTree[i].RChild, newcode + "1");
    
}
void Huffman::CreateCodeTable()
{
    code(2 * N - 2, "");
}
void Huffman::Decode(char* s, char* d)
{
    while (*s != '\0')
    {
        int parent = 2 * N - 2;
        while (HTree[parent].LChild != -1)
        {
            if (*s == '0')
            {
                parent = HTree[parent].LChild;
            }
            else
            {
                parent = HTree[parent].RChild;
            }
            s++;
        }
        *d = HCodeTable[parent].data;
        d++;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值