//不断更新中
//哈夫曼编码:
//哈夫曼编码用于数据压缩,根据权值使用不等长的编码替代等长编码
struct HNode {
unsigned int weight;
unsigned int parent;
unsigned int LChild;
unsigned int RChild;
};
struct HCode {
char data;
char code[100];
};
class Huffman {
private:
HNode* HTree;
HCode* HCodeTable;
public:
void CreateHTree(int a[], int n);
void CreateCodeTable(char b[], int n);
void Encode(char* s, char* d);
void Decode(char* s, char* d);
~Huffman();
};
void Huffman::CreateHTree(int a[], int n) {
HTree = new HNode[2 * n - 1];
for (int i = 0; i < n; i++) {
HTree[i].weight = a[i];
HTree[i].LChild = -1;
HTree[i].RChild = -1;
HTree[i].parent = -1;
}
int x, y;
for (int i = n; i < 2 * n - 1; i++) {
SelectMin(x, y, 0, 1);
HTree[x].parent = HTree[y].parent = i;
HTree[i].weight = HTree[x].weight + HTree[y].weight;
HTree[i].LChild = x;
HTree[i].RChild = y;
HTree[i].parent = -1;
}
}
void Huffman::CreateCodeTable(char b[], int n) {
HCodeTable = new HCode[n];
for (int i = 0; i < n; i++)
{
HCodeTable[i].data = b[i];
int child = i;
int parent = HTree[i].parent;
int k = 0;
while (parent != -1) {
if (child == HTree[parent].LChild) {
HCodeTable[i].code[k] = '0';
}
else {
HCodeTable[i].code[k] = '1';
}
k++;
child = parent;
parent = HTree[child].parent;
}
HCodeTable[i].code[k] = '\0';
Reverse(HCodeTable[i].code);
}
}
void Huffman::Decode(char* s, char* d) {
while (*s != '\0') {
int parent = 2 * n - 1 - 1;
while (HTree[parent].LChild != -1) {
if (*s == '0') {
parent = HTree[parent].LChild;
}
else {
parent = HTree[parent].RChild;
}
s++;
}
*d = HCodeTable[parent].data;
d++;
}
}