.h文件
#ifndef HUFFMANTREE_H
#define HUFFMANTREE_H
class HuffmanTree{
private:
typedef struct HTNode
{
int data;
int weight;
int lson, rson, father;
}HTNode;
HTNode * Huffman_tree;
int n, m; // n: charTotal, m: nodeTotal
char ** huffman_code; // 声明一个指向每个叶子Huffman编码字符数组的指针数组
public:
/**
* 构造函数
@name HuffmanTree(const char* str)
@param arg1 需要进行哈夫曼编码的字符串
@return
注意: 要求树的左孩子为权制较小的编码,左孩子的二进制编号为0
*/
HuffmanTree(const char* str);
/**
* 析构函数
@name ~HuffmanTree()
@param
@return
*/
~HuffmanTree();
/**
* 获得哈夫曼树关于字符C的编码
@name int getcode(char)
@param arg1 需要获取编码的字符
@return 哈夫曼树下C的编码
*/
char* getcode(char c);
/**
* 获得哈夫曼树的WPL
@name int getWPL()
@param
@return 哈夫曼树的WPL
*/
int getWPL();
void select(int n, int& a, int& b);
void createHuffmanCode();
};
#endif
.cpp文件(实现)
#include "Huffman.h"
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
HuffmanTree::HuffmanTree(const char* str){
n = m = 0;
const int N = 128;
int g[N] = {};
for (int i = 0; str[i]; i ++)
{
if(!g[str[i] - 1]) n ++;
g[str[i] - 1] ++;
}
m = (n << 1) - 1;
Huffman_tree = new HTNode[m + 1];
for (int i = 0, j = 1; i < N; i ++)
{
if(g[i]){
Huffman_tree[j ++] = {i + 1, g[i]};
}
}
for (int i = n + 1; i <= m; i ++)
{
int a, b;
select(i - 1, a, b);
Huffman_tree[i].lson = a, Huffman_tree[i].rson = b;
Huffman_tree[i].weight = Huffman_tree[a].weight + Huffman_tree[b].weight;
Huffman_tree[i].father = 0;
Huffman_tree[a].father = Huffman_tree[b].father = i;
}
createHuffmanCode();
}
HuffmanTree::~HuffmanTree(){
delete [] Huffman_tree;
delete [] huffman_code;
}
void HuffmanTree::select(int n, int& a, int& b){
int mina = INT_MAX;
int minb = INT_MAX;
for (int i = 1; i <= n; i ++)
{
if(Huffman_tree[i].father) continue;
int w = Huffman_tree[i].weight;
if(w < mina){
minb = mina;
b = a;
mina = w;
a = i;
}
else if(w < minb){
minb = w;
b = i;
}
}
}
void HuffmanTree::createHuffmanCode()
{
huffman_code = new char* [n + 1];
char* cd = new char[n];
cd[n - 1] = '\0';
for (int i = 1; i <= n; i ++)
{
int st = n - 1;
int ii = i;
while(ii != m)
{
int f = Huffman_tree[ii].father;
if(Huffman_tree[f].lson == ii) cd[-- st] = '0';
else cd[-- st] = '1';
ii = f;
}
huffman_code[i] = new char[n - st + 1];
strcpy(huffman_code[i], &cd[st]);
}
delete [] cd;
}
char* HuffmanTree::getcode(char c){
int cc = c;
int i = 1;
for (; i <= n; i ++) if(cc == Huffman_tree[i].data) break;
return huffman_code[i];
}
int HuffmanTree::getWPL(){
int res = 0;
for (int i = 1; i <= n; i ++)
{
int k = i;
int cnt = 0;
while(k != m)
{
cnt ++;
k = Huffman_tree[k].father;
}
res += cnt * Huffman_tree[i].weight;
}
return res;
}
.main测试文件
#include <iostream>
#include <cstdio>
#include <cstring>
#include "Huffman.h"
using namespace std;
int main()
{
HuffmanTree hf("aaaaaaaabbbbccd");
if(strcmp(hf.getcode('a'), "1") == 0) cout << "pass check point 1!" << endl;
if(strcmp(hf.getcode('b'), "01") == 0) cout << "pass check point 2!" << endl;
if(strcmp(hf.getcode('c'), "001") == 0) cout << "pass check point 3!" << endl;
if(strcmp(hf.getcode('d'), "000") == 0) cout << "pass check point 4!" << endl;
if(hf.getWPL() == 25) cout << "pass check point 5!" << endl;
HuffmanTree tr("abcdabcabbddefffffgggggggggggggggggggg");
printf("a : %s\n", tr.getcode('a'));
printf("b : %s\n", tr.getcode('b'));
printf("c : %s\n", tr.getcode('c'));
printf("d : %s\n", tr.getcode('d'));
printf("e : %s\n", tr.getcode('e'));
printf("f : %s\n", tr.getcode('f'));
printf("g : %s\n", tr.getcode('g'));
cout << tr.getWPL() << endl;
return 0;
}
测试效果: