//字符集D = {A, B, C, D, E, F, G}
//概率分布W = {0.40, 0.30, 0.15, 0.05, 0.04, 0.03, 0.03}
#include <iostream>
#include <vector>
using namespace std;
#define MAXSIZE 14
struct HaffNode //霍夫曼树结点
{
double weight;
int parent;
int lChild;
int rChild;
};
struct vectorEle
{
char data;
vector<int>dataNode;
};
void selectMinIndex(HaffNode* arr, int i, int& minIndex01, int& minIndex02)
{
//找到第一个最小值
for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0) { minIndex01 = j; } }
for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && arr[minIndex01].weight > arr[j].weight) { minIndex01 = j; } }
//找到第二个最小值
for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && j != minIndex01) { minIndex02 = j; } }
for (int j = 1; j <= i - 1; j++) { if (arr[j].parent == 0 && j != minIndex01 && arr[minIndex02].weight > arr[j].weight) { minIndex02 = j; } }
}
void createHaffmanTree(HaffNode* arr) //创建霍夫曼树
{
cout << "请输入字符的权值:";
for (int i = 1; i <= MAXSIZE / 2; i++)
{
cin >> arr[i].weight;
arr[i].parent = arr[i].lChild = arr[i].rChild = 0;
}
for (int i = MAXSIZE / 2 + 1; i <= MAXSIZE - 1; i++)
{
int minIndex01, minIndex02;
selectMinIndex(arr, i, minIndex01, minIndex02);
arr[i].weight = arr[minIndex01].weight + arr[minIndex02].weight;
arr[i].parent = 0;
arr[i].lChild = minIndex01;
arr[i].rChild = minIndex02;
arr[minIndex01].parent = arr[minIndex02].parent = i;
}
}
void createHaffmanCode(HaffNode* arr, vector<vectorEle>&v) //编霍夫曼码
{
//编码(左分支标0,右分支标1,从叶子结点往根结点溯源)
cout << "请输入对应的字符:";
for (int i = 1; i <= MAXSIZE / 2; i++)
{
vectorEle ve;
cin >> ve.data;
int index = i;
while (arr[index].parent != 0)
{
if (index == arr[arr[index].parent].lChild) { ve.dataNode.insert(ve.dataNode.begin(), 0); }
else { ve.dataNode.insert(ve.dataNode.begin(), 1); }
index = arr[index].parent;
}
v.push_back(ve);
}
//检测结果,打印各个字符的霍夫曼编码
cout << "各字符对应的哈夫曼编码如下:" << endl;
for (vector<vectorEle>::iterator it = v.begin(); it != v.end(); it++)
{
cout << it->data << ":";
for (vector<int>::iterator vit = it->dataNode.begin(); vit != it->dataNode.end(); vit++) { cout << *vit; }
cout << endl;
}
}
void deHaffmanCode(HaffNode* arr, const vector<vectorEle>v) //解霍夫曼码
{
cout << "请输入哈夫曼编码:";
string haffmanCode;
cin >> haffmanCode;
vector<char>data; //存储解码结果
int endIndex = 0; //每一次遍历哈夫曼编码后的 结束下标+1
while (endIndex != haffmanCode.length())
{
int startIndex = endIndex;
for (vector<vectorEle>::const_iterator it = v.begin(); it != v.end(); it++)
{
bool match = true;
int index = startIndex;
for (vector<int>::const_iterator vit = it->dataNode.begin(); vit != it->dataNode.end(); vit++)
{
if (haffmanCode[index] - '0' != *vit) { match = false; break; }
else { index++; }
}
if (match) { data.push_back(it->data); endIndex = index; break; }
}
}
//检测结果,打印解码后的字符
cout << "解码结果:";
for (vector<char>::iterator it = data.begin(); it != data.end(); it++) { cout << *it; }
cout << endl;
}
int main() {
HaffNode* arr = new HaffNode[MAXSIZE]; //存储霍夫曼树的一维数组
vector<vectorEle>v; //存储字符的霍夫曼编码
createHaffmanTree(arr);
createHaffmanCode(arr, v);
deHaffmanCode(arr, v);
delete[] arr; //释放数组
system("pause");
return 0;
}