Huffman树及编码的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tommenx/article/details/70127744

Huffman树及编码的实现

定义

Huffman树又称最优树,是一类带权路径长度最短的树,而Huffman编码是基于Huffman树生成的一种前缀编码,保证了可变编码的平均编码最短。

生成方法

  1. 首先,假设有n个权值,则整个Huffman树的结点有2n-1个,未填充的节点有n-1个
  2. 从n个权值中挑选两个权值最小的结点构成一棵树的叶子节点,生成的树的根节点的权值为两个叶子节点的和,n++;
  3. 重复上述步骤,直到所节点都有权重。(即循环n-1次)

这里写图片描述

Huffman代码如下

#include <iostream>
#include <string>
using namespace std;
struct HuffmanNode{
    int weight;
    int parent,lchild,rchild;
};
void createHuffmanTree(HuffmanNode *& node, int *w, int n); 
void selectNode(HuffmanNode *node, int & s1, int &s2, int n);
int main(){
    HuffmanNode *node;
    int w[] = { 5, 29, 7, 8, 14, 23, 3, 11 };
    createHuffmanTree(node, w, 8);
    system("pause");
    return 0;
}


void createHuffmanTree(HuffmanNode *& node, int *w, int n){
    int i;
    int s1, s2;//两个权重最小的Node
    int s = 2 * n - 1;//节点总数
    node = new HuffmanNode[s + 1];//获取相应的空间大小
    memset(node, 0, (s + 1)*sizeof(HuffmanNode));
    for (i = 1; i <= n; i++){
        node[i].weight = *w++;
    }
    for (i = n + 1; i <= s; i++){
        selectNode(node, s1, s2, i-1);
        node[i].weight = node[s1].weight + node[s2].weight;
        node[i].lchild = s1;
        node[i].rchild = s2;
        node[s1].parent = i;
        node[s2].parent = i;
    }


    //对huffmanTree 进行编码


    int start, c, f;
    char **res = (char**)malloc((n + 1)*sizeof(char*));
    char *cd = (char*)malloc(n*sizeof(char));
    cd[n - 1] = '\0';
    for (int i = 1; i <= n; i++){
        start = n - 1;//code最长有n-1位
        for (c = i, f = node[i].parent; f != 0; c = f, f = node[f].parent){
            if (node[f].lchild == c)
                cd[--start] = '0';
            else
                cd[--start] = '1';
        }
        res[i] = (char*)malloc((n - start)*sizeof(char));
        strcpy_s(res[i],n-start, &cd[start]);
    }

    for (int i = 1; i <= n; i++){
        cout << res[i] << endl;
    }


}

void selectNode(HuffmanNode *node, int & s1, int &s2,int n){
    s1 = 0;
    s2 = 0;
    int i;
    int min = INT_MAX;

    for (i = 1; i <= n; i++){
        if (node[i].parent == 0){
            min = node[i].weight;
            break;
        }
    }

    for (i = 1; i <= n; i++){
        if (node[i].parent == 0 && node[i].weight <= min){
            min = node[i].weight;
            s1 = i;
        }
    }
    min = INT_MAX;
    for (i = 1; i <= n; i++){
        if (node[i].parent == 0 && node[i].weight < min){
            if (i == s1)
                continue;
            min = node[i].weight;
            s2 = i;
        }
    }
}

以上的测试用例

w={5,29,7,8,14,23,3,11}

对应的结果表格如下

No weight parent lchild rchild
1 5 9 0 0
2 29 14 0 0
3 7 10 0 0
4 8 10 0 0
5 14 12 0 0
6 23 13 0 0
7 3 9 0 0
8 11 11 0 0
9 8 11 1 7
10 5 12 3 4
11 15 13 8 9
12 29 14 5 10
13 42 15 6 11
14 58 15 2 12
15 100 0 13 14
阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页