Huffman编码

16 篇文章 1 订阅
10 篇文章 0 订阅
#include <iostream>
using namespace std;
#define MAX 100000

typedef struct {
    int parent;
    int lchild;
    int rchild;
    int weight;//权值
    char value;//需要编的码
    char* code;
}HuffmanNode;

typedef struct{
    char* code;
    int len;
}Hcode;

//创建haffman树
void  huffmanTree(HuffmanNode Node[], int n)
{
    int m1, m2;//两个最小权值点
    int x1, x2;//计算最小权值点时,记录该节点在数组中的序号 
    //初始化整个树
    for (int i = 0; i< 2 * n - 1; i++)
    {
        Node[i].parent = -1;
        Node[i].lchild = -1;
        Node[i].rchild = -1;
        Node[i].weight = 0;//权值 
    }
    //输入n个叶子节点的权值
    for (int i = 0; i<n; i++)
    {
        printf("Please input weight of leaf node 频率: and 值:\n", i);
        cin >> Node[i].weight >> Node[i].value;
    }
    //构建树
    for (int i = 0; i < n - 1; i++)//两个节点变成一个节点,最后要剩余一个节点,所以是 n - 1
    {
        m1 = m2 = MAX;//给最小权值初始化一个很大的数
        x1 = x2 = 0;
        for (int j = 0; j<n + i; j++)
        {
            if (Node[j].weight < m1 && Node[j].parent == -1)//出现了最小权值的情况
            {
                m2 = m1;
                m1 = Node[j].weight;
                x2 = x1;
                x1 = j;//记录当前最小权值的Node 在数组中的序号
            }
            else if (Node[j].weight < m2 && Node[j].parent == -1)//出现第二小权值的情况
            {
                m2 = Node[j].weight;
                x2 = j;
            }
        }
        Node[n + i].weight = Node[x1].weight + Node[x2].weight;
        Node[n + i].lchild = x1;
        Node[n + i].rchild = x2;
        //改变子节点的parent 为当前创建的节点
        Node[x1].parent = n + i;
        Node[x2].parent = n + i;

    }
}

//编码
void codeHuffman(HuffmanNode* node, int n)
{
    Hcode tempCode;
    int parent, child;
    tempCode.code = new char[n];
    for (int i = 0; i < n; i++)
    {
        tempCode.len = n;
        parent = node[i].parent;
        child = i;
        while (parent != -1)//没有父类就跳出循环
        {
            // 若当前节点是父节点的左孩子,则编码为0
            if (node[parent].lchild == child)
                tempCode.code[--tempCode.len] = '0';
            else if (node[parent].rchild == child)
                tempCode.code[--tempCode.len] = '1';
            child = parent;
            parent = node[parent].parent;
        }
        int len = n - tempCode.len;
        node[i].code = new char[len + 1];
        memcpy(node[i].code, tempCode.code + tempCode.len, len);
        node[i].code[len] = '\0';
    }
    delete[] tempCode.code;
}
void print(HuffmanNode* node, int n)
{
    for (int i = 0; i < n; i++)
        cout << node[i].value << "\t编码:" << node[i].code << endl;
}
int main()
{
    int n;
    while (1)
    {
        cout << "要创建几个节点" << endl;
        cin >> n;
        HuffmanNode* Node = new HuffmanNode[2 * n - 1];
        huffmanTree(Node, n);
        codeHuffman(Node, n);
        print(Node, n);
    }
    system("pause");
}
/*
6
1 a
2 b
3 c
4 d
5 e
6 f
----------------------------------------
a       编码:1110
b       编码:1111
c       编码:110
d       编码:00
e       编码:01
f       编码:10
----------------------------------------
6
45 a
13 b
12 c
16 d
9 e
5 f
a       编码:0
b       编码:101
c       编码:100
d       编码:111
e       编码:1101
f       编码:1100
*/

弄的简单,第一次搞Huffman。网上看到一些比较复杂的,还要用 “最小堆”,我就没搞那么深了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值