贪心算法之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; } }