用哈夫曼树来写编码

该代码实现了使用C++进行哈夫曼编码的构建过程,包括字符统计、最小节点合并以及编码生成。程序首先读取输入字符串,计算每个字符的出现频率,然后基于这些频率构建哈夫曼树,并为每个字符生成对应的哈夫曼编码。
摘要由CSDN通过智能技术生成

 //实现(因为这个是课堂上写的,写得可能会有点差)

#include<iostream>
#include<string>
using namespace std;
struct zifu
{
    char a;
    int sum;
    char b[10];
};

struct tree_node
{
    //(双亲、左右孩子、数据域)
    int parent;
    int lchild;
    int rchild;
    char a;
    int quan;
    int node;
};


//初始化字符类型
zifu* init()
{
    zifu* L;
    L = new zifu [10];
    for (int i = 0; i < 10; i++)
    {
        L[i].a = '\0';
        L[i].sum = 0;
        memset(L[i].b, 0, 10);
    }
    return L;
}

void serach(tree_node tree[20], int sum, int& s1, int& s2)
{
    s1 = s2 = -1;
    for (int i = 0; i < sum; i++)
    {
        if (tree[i].parent == 0 && s1 == -1)
        {
            s1 = i; continue;
        }
        if (tree[i].parent == 0 && s2 == -1)
        {
            s2 = i;
            if(tree[s1].quan>tree[s2].quan)
            {
                int temp = s1;
                s1 = s2;
                s2 = temp;
            }
                continue;
        }
        if (tree[i].quan < tree[s2].quan&& tree[i].parent == 0)
        {
            s2 = i;
            if (tree[s1].quan > tree[s2].quan)
            {
                int temp = s1;
                s1 = s2;
                s2 = temp;
            }
        }
    }
    /*cout << s1 << endl;
    cout << s2 << endl;*/

}
void insert(char b[10], int c, char a)
{
    for (int i = c; i >0; i--)
    {
        b[i ] = b[i-1];
    }
    b[0] = a;
}

void test01()
{
    zifu* L = init();
    char a[100];
    scanf("%s", a);
    int k = 1;            //记录数据的个数
    L[0].a = a[0];

    //统计各个字符的数量
    for (int i = 0; i < strlen(a); i++)
    {
        for(int j=0;j<k;j++)
        {
            if (a[i] != L[j].a)
            {
                if(j==k-1)
                {
                    k++;
                    L[k - 1].a = a[i];
                }
            }
            if (a[i] == L[j].a)
            {
                L[j].sum++;
                break;
            }
        }
    }
    for (int i = 0; i < k; i++)
    {
        cout << L[i].a << " " << L[i].sum << endl;
    }
    cout << k << endl;
    //构建哈夫曼数--->节点包含(双亲、左右孩子、数据域)
    tree_node tree[20];
    //1、将数据建立数的节点
    for (int i = 0; i < k; i++)
    {
        tree[i].a = L[i].a;
        tree[i].lchild = tree[i].rchild = tree[i].parent = 0;
        tree[i].quan = L[i].sum;
        tree[i].node = i;
    }
    int m = k;
    int s1 = 0, s2 = 0;
    
    for (int i=0;i<2*k-1;i++)
    {
        //找到两个最小的合并成一个大的
        serach(tree, m, s1, s2);
        if (s2 == -1)
        {
            break;
        }
        // 构造大的
        tree[m].a = 0;
        tree[m].lchild = s1;
        tree[m].rchild = s2;
        tree[m].parent = 0;
        tree[m].node = m;
        tree[m].quan = tree[s1].quan + tree[s2].quan;
        tree[s1].parent = tree[s2].parent = m;
        m++;
        
        
    }
    cout << m << endl;
    //输出各个字符的编码
    for (int h = 0; h < k; h++)
    {
        int i =h;
        int j = h;
        for(;;)
        {
            int c = strlen(L[j].b);
            if (tree[tree[tree[i].parent].lchild].node == tree[i].node)
                insert(L[j].b, c,'0');
            if (tree[tree[tree[i].parent].rchild].node == tree[i].node)
                insert(L[j].b, c,'1');
                i = tree[i].parent;
                if (i == m-1)
                {
                    break;
                }
        }
    }
    for (int i = 0; i < k; i++)
        cout <<L[i].a<<":"<< L[i].b << endl;
}


int main()
{
    test01();
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值