#include <iostream>
using namespace std;
#define MAX 100000
typedef struct {
int parent;
int lchild;
int rchild;
int weight;//权值
char value;//需要编的码
char* code;
}HuffmanNode;
typedef struct{
char* code;
int len;
}Hcode;
//创建haffman树
void huffmanTree(HuffmanNode Node[], int n)
{
int m1, m2;//两个最小权值点
int x1, x2;//计算最小权值点时,记录该节点在数组中的序号
//初始化整个树
for (int i = 0; i< 2 * n - 1; i++)
{
Node[i].parent = -1;
Node[i].lchild = -1;
Node[i].rchild = -1;
Node[i].weight = 0;//权值
}
//输入n个叶子节点的权值
for (int i = 0; i<n; i++)
{
printf("Please input weight of leaf node 频率: and 值:\n", i);
cin >> Node[i].weight >> Node[i].value;
}
//构建树
for (int i = 0; i < n - 1; i++)//两个节点变成一个节点,最后要剩余一个节点,所以是 n - 1
{
m1 = m2 = MAX;//给最小权值初始化一个很大的数
x1 = x2 = 0;
for (int j = 0; j<n + i; j++)
{
if (Node[j].weight < m1 && Node[j].parent == -1)//出现了最小权值的情况
{
m2 = m1;
m1 = Node[j].weight;
x2 = x1;
x1 = j;//记录当前最小权值的Node 在数组中的序号
}
else if (Node[j].weight < m2 && Node[j].parent == -1)//出现第二小权值的情况
{
m2 = Node[j].weight;
x2 = j;
}
}
Node[n + i].weight = Node[x1].weight + Node[x2].weight;
Node[n + i].lchild = x1;
Node[n + i].rchild = x2;
//改变子节点的parent 为当前创建的节点
Node[x1].parent = n + i;
Node[x2].parent = n + i;
}
}
//编码
void codeHuffman(HuffmanNode* node, int n)
{
Hcode tempCode;
int parent, child;
tempCode.code = new char[n];
for (int i = 0; i < n; i++)
{
tempCode.len = n;
parent = node[i].parent;
child = i;
while (parent != -1)//没有父类就跳出循环
{
// 若当前节点是父节点的左孩子,则编码为0
if (node[parent].lchild == child)
tempCode.code[--tempCode.len] = '0';
else if (node[parent].rchild == child)
tempCode.code[--tempCode.len] = '1';
child = parent;
parent = node[parent].parent;
}
int len = n - tempCode.len;
node[i].code = new char[len + 1];
memcpy(node[i].code, tempCode.code + tempCode.len, len);
node[i].code[len] = '\0';
}
delete[] tempCode.code;
}
void print(HuffmanNode* node, int n)
{
for (int i = 0; i < n; i++)
cout << node[i].value << "\t编码:" << node[i].code << endl;
}
int main()
{
int n;
while (1)
{
cout << "要创建几个节点" << endl;
cin >> n;
HuffmanNode* Node = new HuffmanNode[2 * n - 1];
huffmanTree(Node, n);
codeHuffman(Node, n);
print(Node, n);
}
system("pause");
}
/*
6
1 a
2 b
3 c
4 d
5 e
6 f
----------------------------------------
a 编码:1110
b 编码:1111
c 编码:110
d 编码:00
e 编码:01
f 编码:10
----------------------------------------
6
45 a
13 b
12 c
16 d
9 e
5 f
a 编码:0
b 编码:101
c 编码:100
d 编码:111
e 编码:1101
f 编码:1100
*/
弄的简单,第一次搞Huffman。网上看到一些比较复杂的,还要用 “最小堆”,我就没搞那么深了。