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 }