#include <stdlib.h> #include <stdio.h> #include <string.h> #include <conio.h> #pragma warning(disable:4996) typedef struct HuffmanTree { int weight;//权值 int parent;//父节点 int left;//左子树 int right;//右子树 }; typedef char *HuffmanCode;//Huffmancode编码 //从1-x个节点选择parent节点为0,权重最小的两个节点 void SelectNode(HuffmanTree *ht, int n, int *bt1, int *bt2){ int i; HuffmanTree *ht1, *ht2, *t; ht1 = ht2 = NULL;//初始化两个节点为空 for (i = 1; i <= n; ++i)//循环处理1-n个节点(包括叶节点和非叶节点) { if (!ht[i].parent)//父节点为空(节点的parent为0) { if (ht1 == NULL)//节点指针1为空 { ht1 = ht + i;//指向第i个节点 continue;//继续循环 } if (ht2 == NULL) { ht2 = ht + i; if (ht1->weight > ht2->weight)//比较两个值的权重,使ht1指向权值大的 { t = ht2; ht2 = ht1; ht1 = t; } continue;//继续循环 } if (ht1 && ht2)//若两个值都有效 { if (ht[i].weight <= ht1->weight)//第i个节点权重小于ht1指向的节点 { ht2 = ht1;//ht2保存ht1,因为这时ht1指向的节点成为第2小的 ht1 = ht + i; } else if (ht[i].weight < ht2->weight)//若第i个节点权重小于ht2指向的权重 { ht2 = ht + i; } } } } if (ht1 > ht2)//增加比较,使二叉树左侧为叶节点 { *bt2 = ht1 - ht; *bt1 = ht2 - ht; } else { *bt1 = ht1 - ht; *bt2 = ht2 - ht; } } void CreateTree(HuffmanTree *ht, int n, int *w){ int i, m = 2 * n - 1;//总的节点总数 int bt1, bt2;//二叉树节点序与 if (n <= 1)//只有一个节点就无法创建 { return; } for (i = 0; i <= n; ++i)//初始化节点 { ht[i].weight = w[i - 1]; ht[i].parent = 0; ht[i].left = 0; ht[i].right = 0; } for (; i <= m; ++i)//初始化后序节点 { ht[i].weight = 0; ht[i].parent = 0; ht[i].left = 0; ht[i].right = 0; } for (i = n + 1; i <= m; ++i)//逐个计算非叶节点,创建Huffman树 { SelectNode(ht, i - 1, &bt1, &bt2); ht[bt1].parent = i; ht[bt2].parent = i; ht[i].left = bt1; ht[i].right = bt2; ht[i].weight = ht[bt1].weight + ht[bt2].weight; } } // void HuffmanCoding(HuffmanTree *ht, int n, HuffmanCode *hc){ char *cd; int start, i; int current, parent; cd = (char*)malloc(sizeof(char)*n);//用来临时存放一个字符编码的结果 cd[n - 1] = '