节点数和权重值数组用顺序表实现哈夫曼树的代码

鉴于网上寻找代码交作业,对于大一学生没有对口方案,因为太高端而难以糊弄过去

于是我写了这个顺序表的实现,非常简单,需要输入节点数和权重值即可,而且还会输出各个叶子节点的编码(当然你可以删去)

#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);
    int Tracing(int);
public:Huffman(int n);
    void CreateHTree(int *a, int n, char name[]);
    void CreateCodeTable();
    void OutPutCode();
    void Decode(char* s, char* d);
    int tot();
};
void Huffman::OutPutCode()
{
    for (int i = 0; i < N; i++)
    {
        cout <<HTree[i].weight<<' ' << HCodeTable[i].code << endl;
    }
}
Huffman::Huffman(int n)
{
    HTree = new HNode;
    HCodeTable = new HCode;
    N = n;
}
int Huffman::Tracing(int a)
{
    int i = 0;
    while (HTree[a].parent != -1)
    {
        a = HTree[a].parent;
        i++;
    }
    return i;
}
int Huffman::tot()
{
    int num = 0;
    for (int i = 0; i < N; i++)
    {
        num += HTree[i].weight * Tracing(i);
    }
    return num;
}

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-1; 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++;
    }
}

int main()
{
    
    int b = 0;
    cin >> b;Huffman a(b);
    int c[100];
    for (int i = 0; i < b; i++)
    {
        cin >> c[i];
    }
    char d[] = {0};
    a.CreateHTree(c, b, d);
    cout << a.tot();
    cout << endl;
    a.CreateCodeTable();
    a.OutPutCode();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值