#include <iostream>
#include <iomanip>
using namespace std;
typedef struct {
int weight;//权值
int parent, lchild, rchild;//双亲结点和左右孩子结点
}HTNode, * HuffmanTree;
void Select(HuffmanTree& HT, int n, int& s1, int& s2);//每次选择出权值最小的两个结点,用s1 s2返回以用来合并新结点
void CreateHuffmanTree(HuffmanTree& HT, int* w, int n);//建立哈夫曼树,结点存在与数组w中,结点个数为n
void DisplayHuffmanTree(HuffmanTree HT, int n);
void Select(HuffmanTree& HT, int n, int& s1, int& s2) {
int min = 0;//临时变量,用于存储权值最小的元素
for (int i = 0; i < n; i++) {//第一轮循环,寻找一个无父母的结点
if (HT[i].parent == -1) {
min = i; break;
}
}
for (int i = min + 1; i < n; i++) {//第二轮循环,遍历min之后的所有结点,将权值最小的结点存入min
if (HT[i].parent == -1)
if (HT[i].weight < HT[min].weight)
min = i;
}
s1 = min;//找到了第一个最小结点
//重复上述过程,但要确保所找到元素非s1
for (int i = 0; i < n; i++) {//第一轮循环,寻找一个无父母的结点
if (HT[i].parent == -1 && i!=s1) {
min = i; break;
}
}
for (int i = min + 1; i < n; i++) {//第二轮循环,遍历min之后的所有结点,将权值最小的结点存入min
if (HT[i].parent == -1)
if (HT[i].weight < HT[min].weight && i!=s1)
min = i;
}
s2 = min;//找到了第二个最小结点
}
void CreateHuffmanTree(HuffmanTree& HT, int* w, int n) {
if (n <= 1)return;//如果结点为1个或不存在则直接完成建立
int m = 2 * n - 1;//根据公式,总结点个数为2n-1个
HT = new HTNode[m];//分配m个空间用来建立哈夫曼树
if (!HT)exit(0);
for (int i = 0; i < n; i++) {//前n个结点用来存储初始的所有叶子结点
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = w[i];
}
for (int i = n; i < m; i++) {//后面的结点用来存储哈夫曼树的非叶子结点,先进行初始化
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = 0;
}
for (int i = n; i < m; i++) {
int s1, s2;
Select(HT, i, s1, s2);//从0-i-1一共i个结点中选出最小的s1和s2
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void DisplayHuffmanTree(HuffmanTree HT, int n) {
int m = 2 * n - 1;
cout << "weight" << " " << "lchild" << " " << "rchild" << endl;
for (int i = 0; i < m; i++)
{
cout << setw(4) << HT[i].weight << setw(7) << HT[i].lchild << setw(7) << HT[i].rchild << endl;
}
}
int main()
{
HuffmanTree HT;
cout << "请输入叶子结点的个数(<=100):" << endl;
int i, n;
cin >> n;
int* w = new int[n];
cout << "请依次输入个结点的权值(为正整型值):" << endl;
for (i = 0; i < n; i++)
cin >> w[i];
CreateHuffmanTree(HT, w, n);
DisplayHuffmanTree(HT, n);
return 0;
}
实验样例