1 //最优二叉树
2 #include <iostream>
3 #include <iomanip>
4 using namespace std;
5
6 //定义结点类型
7 //【weight | lchid | rchild | parent】
8 //为了判定一个结点是否已加入到要建立的哈夫曼树中
9 //可通过parent域的值来确定.
10 //初始时parent = -1,当结点加入到树中时,该结点parent的值
11 //为其父亲结点在数组Huffman中的序号.
12 template<typename T>
13 struct HuffNode {
14 T weight; //权值
15 int parent; //指向父节点的指针域(结点元素的下标)
16 int lch; //左指针域
17 int rch; //右指针域
18 };
19
20 //哈夫曼树的构造算法
21 template<typename T>
22 HuffNode<T> *HuffmanTree(int n, const T& sign) //生成最优二叉树
23 {
24 const int MAX_VALUE = 100000;
25 int i, j, min1, min2, x1, x2; //min1为最小值, min2为次小值, x1位最小值下标, x2位次小值下标
26 HuffNode<T> *ht = new HuffNode<T>[2 * n - 1]; //一个含有n个叶子结点的最优二叉树,总共有2*n-1个结点
27 HuffNode<T> *huffNode = ht;
28 for (i = 0; i < 2 * n - 1; i++) //最优二叉树结点数组初始化
29 {
30 huffNode[i].weight = 0; //权值都设为0
31 huffNode[i].parent = -1; //父节点,左右孩子结点
32 huffNode[i].lch = -1;
33 huffNode[i].rch = -1; //都设置为-1,-1代表空
34 }
35 for (i = 0; i < n; i++) //依次输入n个叶子结点的权值
36 cin >> huffNode[i].weight;
37
38 for (i = 0; i < n - 1; i++)
39 {
40 min1 = min2 = MAX_VALUE;
41 // x1, x2 用来保存找到的两个最小结点在数组中的位置
42 x1 = x2 = 0;
43 for (j = 0; j < n + i; j++) //因为外循环每循环一次,实际结点个数增加到n+i个
44 {
45 if (huffNode[j].weight < min1 && huffNode[j].parent == -1)
46 {
47 min2 = min1; //存在权值小于min1, 则min1赋值给次小值
48 x2 = x1; //次小值下标改变
49 min1 = huffNode[j].weight; //当前权值赋值给最小值
50 x1 = j; //并保存最小值下标
51 }
52 else if (huffNode[j].weight < min2 && huffNode[j].parent == -1)
53 {
54 min2 = huffNode[j].weight; //当前值赋值给次小值
55 x2 = j; //保存次小值下标
56 }
57 }
58 //将找出的两个子树合并成一颗子树
59 //对找到的两个最小结点的父指针域进行赋值
60 huffNode[x1].parent = n + i;
61 huffNode[x2].parent = n + i;
62 //新合成树位置上的权值
63 huffNode[n + i].weight = huffNode[x1].weight + huffNode[x2].weight;
64 //两个最小结点的父结点的左右孩子域进行操作
65 huffNode[n + i].lch = x1;
66 huffNode[n + i].rch = x2;
67 }
68 return ht;
69 }
70
71 template<typename T>
72 void ShowHTree(HuffNode<T> *HT, int nodeNum)
73 {
74 HuffNode<T> *p = HT;
75 int k;
76 cout << "k" << "\t\t" << "Weight" << "\t\t" << "Parent"
77 << "\t\t" << "Lchild" << "\t\t" << "Rchild" << endl;
78 for (k = 0; k < 2 * nodeNum - 1; k++)
79 {
80 cout << k << "\t\t" << (p + k)->weight << "\t\t"
81 << (p + k)->parent << "\t\t"
82 << (p + k)->lch << "\t\t" << (p + k)->rch << endl;
83 }
84 }
85
86 int main()
87 {
88 int n;
89 HuffNode<int> *huffNode;
90 int sign = 0; //标志为权值的类型
91
92 cout << "请输入叶子结点个数: " << endl;
93 cin >> n;
94 huffNode = HuffmanTree(n, sign);
95 ShowHTree(huffNode, n);
96
97 system("pause");
98
99 return 0;
100 }