#include<iostream>
#include<algorithm>
using namespace std;
typedef int WeightType;
typedef char ElementType;
/*哈夫曼树的定义*/
typedef struct HuffmanNode *PtrToHuffmanNode;
struct HuffmanNode{
ElementType Element = '0';//存储编码的字母:0表示不是叶结点
int Weight;//储存哈夫曼树结点的频率值
PtrToHuffmanNode Left = NULL;//指向左孩子的指针
PtrToHuffmanNode Right = NULL;//指向右孩子的指针
};
typedef PtrToHuffmanNode Huffman;//哈夫曼树
/*最小堆定义*/
typedef struct HeapNode *Heap;
struct HeapNode{
Huffman HuffArr; //用来存储哈夫曼树指针的数组
int Size; //堆中当前元素个数
int Capacity; //堆的最大容量
};
typedef Heap MinHeap; //最小堆
#define MINDATA 0 //该值需要小于堆中所有可能元素的值
#define MAXSIZE 640 //最大堆结点=最大哈夫曼树结点+1
/*编码结果结构体定义*/
struct CodeResult{
ElementType Element;
WeightType Weight;
string code;
int Ncode = 0;
}AllCodeResult[MAXSIZE];
int IndexC=0;
bool IsFull(MinHeap MinH)
{
return (MinH->Size == MinH->Capacity);
}
bool IsEmpty(MinHeap MinH)
{
return (MinH->Size == 0);
}
MinHeap Create(int MaxSize)
{
MinHeap MinH = new HeapNode;
MinH->HuffArr = new HuffmanNode [MaxSize + 1];
MinH->Size = 0;
MinH->Capacity = MaxSize;
MinH->HuffArr[0].Weight = MINDATA;
return MinH;
}
void Insert(MinHeap MinH, HuffmanNode Huff)
{
int i = 0;
if(IsFull(MinH)){
cout << "MinHeap is full" <<endl;
return;
}
i = ++MinH->Size;
for(; MinH->HuffArr[i/2].Weight > Huff.Weight; i/=2){
MinH->HuffArr[i] = MinH->HuffArr[i/2];
}
MinH->HuffArr[i] = Huff;
}
Huffman DeleteMin(MinHeap MinH)
{
int Parent, Child;
Huffman MinHuffman;
HuffmanNode temp;
if(IsEmpty(MinH)){
cout << "MinHeap is empty!" << endl;
return NULL;
}
MinHuffman = new HuffmanNode;
*MinHuffman = MinH->HuffArr[1];
temp = MinH->HuffArr[MinH->Size--];
for(Parent = 1; Parent*2 <= MinH->Size; Parent = Child){
Child = Parent * 2;
if((Child != MinH->Size) && \
(MinH->HuffArr[Child].Weight > MinH->HuffArr[Child+1].Weight))
++Child;
if(temp.Weight <= MinH->HuffArr[Child].Weight) break;
else
MinH->HuffArr[Parent] = MinH->HuffArr[Child];
}
MinH->HuffArr[Parent] = temp;
return MinHuffman;
}
Huffman BuildHuffman(MinHeap MinH)
{
Huffman NewHuffman;
int N = MinH->Size;
for(int i=1; i<N; i++)
{
NewHuffman = new HuffmanNode;
NewHuffman->Left = DeleteMin(MinH);
NewHuffman->Right = DeleteMin(MinH);
NewHuffman->Weight = NewHuffman->Left->Weight + NewHuffman->Right->Weight;
Insert(MinH, *NewHuffman);
}
NewHuffman = DeleteMin(MinH);
return NewHuffman;
}
void EnCode(Huffman HuffRoot, string code[], int i)
{
//递归出口:找到叶结点,其Element是要求的字母
if(HuffRoot->Left == NULL && HuffRoot->Right == NULL){
string CurrCode = code[0];
AllCodeResult[IndexC].Ncode = 1;
for(int n=1; n<i; n++){
CurrCode += code[n];
AllCodeResult[IndexC].Ncode += 1;
}
AllCodeResult[IndexC].code = CurrCode;
AllCodeResult[IndexC].Element = HuffRoot->Element;
AllCodeResult[IndexC].Weight = HuffRoot->Weight;
IndexC += 1;
return;
}
code[i] = "0";
EnCode(HuffRoot->Left, code, i+1);
code[i] = "1";
EnCode(HuffRoot->Right, code, i+1);
}
int main()
{
int N, M, AllBitNum;;
MinHeap MinH;
HuffmanNode Huff;
Huffman HuffmanRoot;
//初始化最小堆
MinH = Create(MAXSIZE);
//输入字符个数
cin >> N;
ElementType AllElement[N];
WeightType AllWeight[N];//字符对应的频率值数组
/*举例
WeightType AllWeight[N] = {1,1,1,3,3,6,6};
ElementType AllElement[N] = {'A','B','C','D','E','F','G'};
*/
//通过输入构建最小堆-实现对字符频率值的排序
for(int i=0; i<N; i++){
cin >> AllElement[i]; //读取输入字符
cin >> AllWeight[i]; //读取输入字符的频率值
Huff.Element = AllElement[i];
Huff.Weight = AllWeight[i];
Insert(MinH, Huff); //将其哈夫曼结点插入到最小堆
}
//根据最小堆构建哈夫曼树
HuffmanRoot = BuildHuffman(MinH);
string code[N];
//获得哈夫曼编码
EnCode(HuffmanRoot, code, 0);
for(int i=0; i<N; i++){
cout << AllCodeResult[i].Element << " ";
cout << AllCodeResult[i].code <<endl;
}
return 0;
}