贪心算法之Huffman

Huffman编码,权重越大,离根节点越大。所以就是不断的选取两个最小的树,然后组成一颗新树,加入集合,然后去除已选的两棵树。不断的循环,直到最后的树的集合只剩下一棵,则构建完成,最后输出Huffman编码即可。

具体代码如下:

#include <iostream>

using namespace std;

#define MAXLEAF 30
#define MAXNODE MAXLEAF*2-1
#define MAXWEIGHT 10000

typedef struct {
    double weight;
    int parent;
    int lchild;
    int rchild;
    char value;
} HNodeType;

typedef struct {
    int bit[MAXLEAF];
    int start;
} HCodeType;

HNodeType huffNode[MAXNODE]; //节点数组
HCodeType huffCode[MAXLEAF]; //编码数组

void HuffmanTree(HNodeType node[MAXNODE], int n); //构建哈夫曼树

void HuffmanCode(HCodeType code[MAXLEAF], int n);

int main() {
    int n;
    cout << "请输入共有多少字符:";
    cin >> n;
    HuffmanTree(huffNode, n);
    HuffmanCode(huffCode, n);
    for(int i = 0; i < n; i++){
        cout<<huffNode[i].value<<"的Huffman编码:";
        for(int j = huffCode[i].start + 1; j < n; j++){
            cout<<huffCode[i].bit[j];
        }
        cout<<endl;
    }
}

void HuffmanCode(HCodeType code[MAXLEAF], int n) {
    HCodeType temp;
    int c, p;
    for(int i = 0; i < n; i++){
        cout<<"开始计算第"<<i<<"个Huffman..."<<endl;
        temp.start = n-1;
        c = i;
        p = huffNode[c].parent;
        while(p != -1){
            if(huffNode[p].lchild == c)
                temp.bit[temp.start] = 0;
            else
                temp.bit[temp.start] = 1;
            temp.start--;
            c = p;
            p = huffNode[c].parent;
        }
        for(int j = temp.start+1; j < n; j++){
            huffCode[i].bit[j] = temp.bit[j];
        }
        huffCode[i].start = temp.start;
    }
}

void HuffmanTree(HNodeType node[MAXNODE], int n) {

    for (int i = 0; i < 2 * n - 1; i++) {//初始化节点
        huffNode[i].weight = 0;
        huffNode[i].parent = -1;
        huffNode[i].lchild = -1;
        huffNode[i].rchild = -1;
    }
    cout << "请输入节点的值和权重:" << endl;
    for (int i = 0; i < n; i++) {
        cin >> huffNode[i].value >> huffNode[i].weight;
    }
    cout << "开始构造哈夫曼树。。。" << endl;
    for (int i = 0; i < n - 1; i++) {//执行n-1词合并
        //找到最小的两个值
        double w1 = MAXWEIGHT;
        double w2 = MAXWEIGHT;
        int x1 = -1;
        int x2 = -1;
        for (int j = 0; j < n + i; j++) {//合并一次增加一个节点,所以合并第i次增加i个节点
            if(huffNode[j].weight < w1 && huffNode[j].parent == -1){
                //权重小且无双亲节点
                x2 = x1;
                w2 = w1;
                x1 = j;
                w1 = huffNode[j].weight;
            }else if(huffNode[j].weight < w2 && huffNode[j].parent == -1){
                //右节点
                x2 = j;
                w2 = huffNode[j].weight;
            }
        }
        //初始化新增加的节点
        huffNode[n+i].weight = huffNode[x1].weight + huffNode[x2].weight;
        huffNode[n+i].lchild = x1;
        huffNode[n+i].rchild = x2;
        huffNode[x1].parent = n+i;
        huffNode[x2].parent = n+i;
    }
}
原文地址:https://www.cnblogs.com/gpf951101/p/9129382.html