* 对给定的一组权值,实现HuffMan编码,时间复杂度1/2n^2
* 第一步:由已知的n个权值形成哈夫曼的初态
* 第二步:建立哈夫曼结点数组。依次对前面已建立的结点作如下处理
* 1. 选择两个权值最小且无双亲的权
* 2. 根据选出来的两个权构造新的哈夫曼结点,修改两个点父亲结点为新建的节点
* 第三步:对哈夫曼树进行哈夫曼编码:从权结点逆序到根节点写出01编码,
然后再次逆序(正序)存储到哈夫曼编码数组中
1
#include<iostream>
2
#include<iomanip>
3
4
using std::endl;
5
using std::cout;
6
using std::setw;
7
8
const int maxlen = 10; //HuffMan编码最大长度
9
const int MAX = 100; //比任何权重大的一个数
10
11
struct HuffNode
12

{
13
int weight;
14
int parent;
15
int lchild;
16
int rchild;
17
};
18
19
struct HuffCode
20

{
21
int bit[maxlen]; //HuffMan 编码
22
int length; //HuffMan 编码长度
23
int weight;
24
};
25
26
void Huffman(int weight[], int n, HuffNode hn[], HuffCode hc[])
27

{
28
int i,j,l,r; //l,r分别代表新建的节点所用到的两个结点
29
int min1,min2; //存储每次选择的最小的两个权
30
31
for(i = 0; i != 2*n - 1; ++i) //create Huffman Node,step 1
32
{
33
if(i < n) hn[i].weight= weight[i];
34
else hn[i].weight = 0;
35
hn[i].parent = 0;
36
hn[i].lchild = hn[i].rchild = -1;
37
}
38
for(i = 0; i != n-1; ++i) //create Huffman Node, step 2
39
{
40
min1 = min2 = MAX;
41
l = r = 0;
42
/**//* 下面的一段程序本来是想直接通过输入值确定min1,min2的初始值的,因为像上面那个MAX,不知如何给。
43
但是这个代码错了,因为n+i-1,n+i-2不能保证其parent=0,还没想到其他方法
44
min1 = hn[n+i-1].weight;
45
min2 = hn[n+i-2].weight;
46
l = n+i-1;
47
r = n+i-2;
48
if(min1 > min2)
49
{
50
int temp = min1;
51
min1 = min2;
52
min2 = temp;
53
int t = l;
54
l = r;
55
r = t;
56
}
57
*/
58
//find two minimum data
59
for(j = 0; j != n+i; j++)
60
{
61
if(hn[j].weight < min1 && hn[j].parent == 0)
62
{
63
min2 = min1;
64
min1 = hn[j].weight;
65
r = l;
66
l = j;
67
}
68
else if(hn[j].weight < min2 && hn[j].parent == 0)
69
{
70
min2 = hn[j].weight;
71
r = j;
72
}
73
else ;
74
}
75
76
//create a new Huffman Node
77
hn[n+i].weight = min1+min2;
78
hn[l].parent = n+i;
79
hn[r].parent = n+i;
80
hn[n+i].lchild = l;
81
hn[n+i].rchild = r;
82
}
83
84
int temp[maxlen]; //在此逆序存储Huffman编码
85
86
for(i = 0; i != n; ++i)
87
{
88
j = 0;
89
int child = i;
90
int parent = hn[i].parent;
91
while(hn[child].parent != 0) //逆序存储
92
{
93
if(hn[parent].lchild == child) temp[j++] = 0;
94
else temp[j++] = 1;
95
child = parent;
96
parent = hn[parent].parent;
97
}
98
99
//正序存储到HuffCode中
100
int k=0;
101
hc[i].length = j;
102
hc[i].weight = weight[i];
103
while(j) hc[i].bit[k++] = temp[--j];
104
}
105
106
}
107
108
const int N = 7;
109
110
int main()
111

{
112
int a[N] =
{4,2,6,8,3,2,1};
113
HuffNode *hn = new HuffNode[2*N-1];
114
HuffCode *hc = new HuffCode[N];
115
116
Huffman(a,N,hn,hc);
117
118
for(int i=0; i < 2*N -1; ++i)
119
{
120
cout << setw(3) << hn[i].weight << setw(3) << hn[i].parent << setw(3) << hn[i].lchild << setw(3) << hn[i].rchild <<endl;
121
}
122
for(int j=0; j != N; ++j)
123
{
124
cout << "weight = " << hc[j].weight << ", code = ";
125
for(int k = 0; k != hc[j].length; ++k) cout << hc[j].bit[k];
126
cout << endl;
127
}
128
return 0;
129
}