#include <iostream>
#include<iomanip>
using namespace std;
#define NODE_NUM 16
#define MAXVAL 32767
typedef struct
{
int weight;
int parent, lchild,rchild;
}HuffmanTree;
typedef struct {
int bit[8];
int start;
}HCodeType;
HuffmanTree HuffNode[NODE_NUM];
HCodeType HuffCode[8];
int n;
void CreateHuffmanTree()
{
int min1, min2;
int p1, p2;
cout << "输入叶子结点个数" << endl;
cin >> n;
if (2*n>NODE_NUM)
{
cout << "原本预设的叶子结点个数宏不够大";
}
for (int i = 0; i < 2 * n-1; i++)
{
HuffNode[i].weight = 0;
HuffNode[i].parent = 0;
HuffNode[i].lchild = 0;
HuffNode[i].rchild = 0;
}
cout << "输入带权结点" << endl;
for (int i=0;i<n;i++)
{
cin >> HuffNode[i].weight;
}
for (int i=n;i<2*n-1;i++)
{
min1 = min2 = MAXVAL;
p1 = p2 = 0;
for (int j=0;j<i;j++)
{
if (HuffNode[j].parent==0)
{
if (HuffNode[j].weight<min1)
{
min2 = min1;
min1 = HuffNode[j].weight;
p2 = p1;
p1 = j;
}
else if (HuffNode[j].weight<min2)
{
min2 = HuffNode[j].weight;
p2 = j;
}
}
}
HuffNode[p1].parent = HuffNode[p2].parent = i+1;
HuffNode[i].lchild = p1+1;
HuffNode[i].rchild = p2+1;
HuffNode[i].weight = HuffNode[p1].weight + HuffNode[p2].weight;
}
}
void PrintHuffTree()
{
int i;
cout << endl;
cout << "哈夫曼树各项数据如下表所示:" << endl;
cout << "结点i weight parent lchid rchild" << endl;
for (i = 0; i < 2 * n - 1; i++)
cout << i + 1 << setw(8) << HuffNode[i].weight << setw(8) << HuffNode[i].parent << setw(8) << HuffNode[i].lchild << setw(8) << HuffNode[i].rchild <<endl;
cout << endl;
}
void CreateHuffCode()
{
HCodeType cd;
int c, p;
for (int i = 0; i <n; i++)
{
cd.start = n;
c = i+1;
p = HuffNode[i].parent;
while (p)
{
cd.start--;
if (HuffNode[p-1].lchild == c)
cd.bit[cd.start] = 0;
else
cd.bit[cd.start] = 1;
c = p;
p = HuffNode[p-1].parent;
}
for (int j = cd.start; j < n; j++)
HuffCode[i].bit[j] = cd.bit[j];
HuffCode[i].start = cd.start;
}
}
void PrintHuffcode(void) {
int i, j;
cout << "每个叶子结点的哈夫曼编码为:" << endl;
for (i = 0; i <n; i++)
{
for (j = HuffCode[i].start; j < n; j++)
cout << HuffCode[i].bit[j];
cout << endl;
}
}
int main()
{
CreateHuffmanTree();
PrintHuffTree();
CreateHuffCode();
PrintHuffcode();
return 0;
}