#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct
{
char data; /*字符*/
int weight; /* 结点的权值*/
int parent; /* 双亲的下标*/
int LChild; /* 左孩子结点的下标*/
int RChild; /* 右孩子结点的下标*/
} HTNode, *HuffmanTree; /* HuffmanTree 是一个结构数组类型,0 号单元不 用。 */ //int Hnode int* HUffmanTree
queue<int> qu;
void Mysort(HTNode*HT,int num,int &s1,int &s2,int loop_num){
int arr[num] = {0}; // arr[num-1] arr[num-2] arr[0] arr[num]
int i = 0;
while(!qu.empty()){
arr[i++] = qu.front();
qu.pop();
} //arr[1] arr[2] arr[3] arr[4] arr[5] arr[6]
// 使用快速排序对数组进行排序
sort(arr, arr + num);
// 将排序后的数字重新添加到队列中
i = 0;
for(;i<num;i++){
qu.push(arr[i]);
}
for(int k=1;k<=2;k++){
int min = qu.front();
qu.pop(); //这里可以看出 num 每一次进Mysort函数都会减1,弹出2次,再push一次,size就会减小.(队列qu是全局变量,所以函数里面也会改变)
//int min_2 = qu.front();
for(int j=1;j<=loop_num;j++){ //loop_num表示现在树中所有的节点数量,min表示队列中存在的最小值,而非整个树中
if(min == HT[j].weight){//HT[loop_size].weight HT[7].weight
if(k == 1){
s1 = j;
break;
}
//是为了防止最小值中出现min_1 = min_2的,作业中便存在这种情况
else if(k == 2 && s1 == j){
continue;
}
else if(k == 2 && s1 != j){
s2 = j;
break;
}
}
}
}
}
void CreateHuffmanTree(HuffmanTree HT,int n,int m){
int s1 = 1,s2 = 1;
//所有结点的初始化
for(int i=1;i<=m;i++){
HT[i].LChild = 0; HT[i].RChild = 0;HT[i].parent = 0;
}
//初始化char(data)-可有可无
cout<<"依次输入每一个结点的字符"<<endl;
for(int i=1;i<=n;i++){
cin>>HT[i].data;
}
//初始化权值
cout<<"依次输入每一个结点的权值"<<endl;
for(int i=1;i<=n;i++){
cin>>HT[i].weight;
qu.push(HT[i].weight);
}
int i = n + 1;//n表示最开始有n个叶子节点
int loop_num = n;
int size = qu.size();
for(;i<=m;i++){//m表示整个哈夫曼树有m个节点,m=2*n-1
Mysort(HT,size,s1,s2,loop_num++);//loop_num的作用是 每次计算出新的双亲节点后 总节点数量.
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;
qu.push(HT[i].weight);
size = qu.size();//应结合Mysort函数中的内容,size每次循环都会减1,二路归并思想
}//HT[9].weight HT[10].weight HT[11].weight HT[12].weight HT[13].weight
}
void DispHuffmanTree(HuffmanTree HT,int index){
cout<<"哈夫曼树如下:"<<endl;
cout<<"weight"<<'\t'<<"lchild"<<'\t'<<"rchild"<<'\t'<<"parent"<<endl;
for(int i=1;i<=index;i++){
cout<<HT[i].weight<<'\t'<<HT[i].LChild<<'\t'<<HT[i].RChild<<'\t'<<HT[i].parent<<endl;
}
cout<<"带权路径长度WPL:" <<endl;
cout<<HT[index].weight;
}
int main(){
int n = 6;
int m = 2*n-1;
HuffmanTree HT=new HTNode[m+1];
CreateHuffmanTree(HT,n,m);
DispHuffmanTree(HT,m);
}