严蔚敏教材上的Huffman coding 稍微有点改动 // Huffman 编码 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _HuffmanNode { int weight; int parent,left,right; // 为什么要用unsigned呢? }HuffmanNode,*HuffmanTree; typedef char** HuffmanCode; void seekTwo(HuffmanTree root, int n, int& s1, int& s2) { // 在现有的结点中寻找两个最小的结点并把其i值返回 int i=1; int min=0x7fff; s1=0; for (i=2; i<=n; ++i) { if(root[i].parent) continue; // 已经有双亲结点的排除在外 if(min>root[i].weight) {min=root[i].weight;s1=i;} } min=0x7fff; s2=0; for (i=1; i<=n; ++i) { if(i == s1 || root[i].parent) continue; // 上个s1选过的不能重复选 if(min>root[i].weight) {min=root[i].weight;s2=i;} } } HuffmanCode createHuffmanTree(HuffmanTree& root, int* w, int n) { // int* w 中是各种权值 int m = 2*n-1; // m 是全部结点个数 root = (HuffmanTree)calloc(m+1,sizeof(HuffmanNode)); // 0号结点不用 int i=1,j=1; int s1=0,s2=0; int &ps1=s1,&ps2=s2; for(i=1; i<=n; ++i) {root[i].weight = w[i];root[i].left=0;root[i].parent=0;root[i].right=0;} // 权值赋给各节点 for (i; i<=m; ++i) {root[i].left = root[i].parent = root[i].right = root[i].weight = 0; } for (i=n+1; i<m; ++i) { seekTwo(root, i-1, ps1, ps2); root[i].weight = root[ps1].weight+root[ps2].weight; root[i].parent = 0; root[i].left = ps1; root[i].right = ps2; root[ps1].parent = root[ps2].parent = i; } // // 从叶子到根逆向求huffman编码 HuffmanCode thisCode = (HuffmanCode)calloc(n+1,sizeof(char*)); // 0号结点还是不用 char* workSpace = (char*)calloc(n,sizeof(char)); // 树的层次肯定不会 > n,这回使用0号结点 workSpace[n-1] = '/0'; for (j=1; j<=n; ++j) { s1 = n-1; s2 = j; while (1) { s2 = root[s2].parent; if(!s2) break; if(root[s2].left == j) workSpace[--s1] = '0'; else workSpace[--s1] = '1'; } thisCode[j] = (char*)calloc(n-s1,sizeof(char)); strcpy(thisCode[j],&workSpace[s1]); } free(workSpace); return thisCode; } int main() { int w[11] = {0,1,2,3,4,5,6,7,8,9,10}; int i=1; HuffmanTree root = NULL; HuffmanCode code; code = createHuffmanTree(root, w, 10); while (i < 10) { ++i; puts(code[i]); } return 0; }