#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define MAXNUM 10
#define MAXBIT 10
#define MINWEIGHT 1000000
typedef struct
{
char value; // 输入结点代号,如A, B, C...
int parent; /* 父子关系用下标值进行关联 */
int lchild;
int rchild;
int weight; // 自身权重
}HTNODE;
typedef struct
{
char bit[MAXBIT]; // 存储编码
}HTCODE;
/******************************************************************************************/
void Init(int &n, HTNODE *HTNode)
{
cout << "Input the Number of Object, n = "; cin >> n;
for(int i = 0; i < n; i++)
{
HTNode[i].value = 65 + i; // 默认代号A, B, C...
HTNode[i].parent = -1;
HTNode[i].lchild = -1;
HTNode[i].rchild = -1;
cout << "weight[" << i << "] = ";
cin >> HTNode[i].weight;
}
int m = 2 * n - 1;
for(int i = n; i < m; i++)
{
HTNode[i].value = '*'; // 合成结点代号
HTNode[i].parent = -1;
HTNode[i].lchild = -1;
HTNode[i].rchild = -1;
HTNode[i].weight = 0;
}
}
void Select(int &fstSmallest, int &sndSmallest, HTNODE *HTNode, int i)
{
fstSmallest = -1;
sndSmallest = -1;
int fstSWeight = MINWEIGHT;
int sndSWeight = MINWEIGHT;
for(int k = 0; k < i; k++)
{
if(HTNode[k].parent == -1)
{
if(HTNode[k].weight <= fstSWeight)
{
sndSmallest = fstSmallest;
sndSWeight = fstSWeight;
fstSmallest = k;
fstSWeight = HTNode[k].weight;
}
else if(HTNode[k].weight>fstSWeight && HTNode[k].weight<sndSWeight)
{
sndSmallest = k;
sndSWeight = HTNode[k].weight;
}
}
}
}
void BuildHuffmanTree(int n, HTNODE *HTNode)
{
int m = 2 * n - 1; // 可计算出哈夫曼树结点总数
int fstSmallest, sndSmallest; // 分别标记下标值
for(int i = n; i < m; i++)
{
Select(fstSmallest, sndSmallest, HTNode, i);
HTNode[fstSmallest].parent = i;
HTNode[sndSmallest].parent = i;
HTNode[i].lchild = fstSmallest;
HTNode[i].rchild = sndSmallest;
HTNode[i].weight = HTNode[fstSmallest].weight + HTNode[sndSmallest].weight;
}
}
void PrintHuffmanTree(int n, HTNODE *HTNode)
{
int m = 2 * n - 1;
for(int i = 0; i < m; i++)
{
cout << "\ni = " << i;
printf(" value = %c", HTNode[i].value);
printf(" parent = %2d", HTNode[i].parent);
printf(" lchild = %2d", HTNode[i].lchild);
printf(" rchild = %2d", HTNode[i].rchild);
printf(" weight = %2d", HTNode[i].weight);
cout << endl;
}
}
void HuffmanCoding(int n, HTNODE *HTNode, HTCODE *HTCode)
{
int j, start;
char Tbit[MAXBIT];
for(int i = 0; i < n; i++) /* 编码i结点 */
{
start = MAXBIT-1;
int temp_child = i; // 临时孩子
int temp_parent = HTNode[i].parent; // 临时父亲
while(temp_parent != -1)
{
cout << "temp_child = " << temp_child; // Debug 编码过程
cout << " temp_parent = " << temp_parent << endl; // Debug 编码过程
if(HTNode[temp_parent].lchild == temp_child)
Tbit[--start] = '0';
else Tbit[--start] = '1';
temp_child = temp_parent;
temp_parent = HTNode[temp_child].parent;
}
strcpy(HTCode[i].bit, &Tbit[start]);
cout << "bit = " << HTCode[i].bit << endl; // Debug 编码过程
}
}
void HuffmanDecoding(int n, HTNODE *HTNode)
{
int it, flag = 1;
int m = 2 * n - 1;
char str[MAXBIT], *p;
printf("\nInput the String, str = ");
scanf("%s", str); p = str;
for(int i = 0; i < m; i++) // 先定位到根节点
if(HTNode[i].parent == -1)
{ it = i; break; }
while(*p != '\0')
{
if(HTNode[it].lchild==-1 && HTNode[it].rchild==-1) // 编码串过长
{ flag = -1; break; }
if(p[0] == '0')
it = HTNode[it].lchild;
else it = HTNode[it].rchild;
p++;
}
if(HTNode[it].lchild!=-1 && HTNode[it].rchild!=-1) // 编码串过短
{ flag = -1; }
if(flag == -1) printf("Input String is Error!\n");
else printf("Decoding Result is: %c\n", HTNode[it].value);
}
/******************************************************************************************/
int main()
{
int n;
HTNODE HTNode[MAXNUM]; // MAXNUM表示哈夫曼树结点数上限
HTCODE HTCode[MAXNUM];
Init(n, HTNode);
BuildHuffmanTree(n, HTNode);
PrintHuffmanTree(n, HTNode);
HuffmanCoding(n, HTNode, HTCode);
HuffmanDecoding(n, HTNode);
return 0;
}
![]()