#include <stdio.h> #include <malloc.h> #include <string.h> typedef unsigned int u32; typedef int status; #define OK 1 #define ERROR 0 #define N 4 #define UINT_MAX 65535 /* huffman 算法用数组来表示树,设置父节点目的是用于从叶子节点到根编码 */ struct htnode { u32 weight; #if 0 struct htnode *lchild; struct htnode *rchild; sturct htnode *father; #endif int lchild; int rchild; int father; }; void select(struct htnode *HT , int n, int *s1, int *s2) { int i; u32 weight = UINT_MAX; for (i = 1; i <= n; i++) { if ((HT[i].father == 0) && (HT[i].weight < weight)) { weight = HT[i].weight; (*s1) = i; } } weight = UINT_MAX; for (i = 1; i <= n; i++) { if (i == (*s1)) { continue; } if ((HT[i].father == 0) && (HT[i].weight < weight)) { weight = HT[i].weight; (*s2) = i; } } } /* 申请n+1个空间,实际上只用了n个。第0个不用是为了保持阅读代码清晰简便 */ status huffman_code(struct htnode **HT, char ***hc, int *w, int n) { int i; int m; int s1,s2; int c,f; char *cd; int start; m = 2 * n - 1; (*HT) = (struct htnode*)malloc(sizeof(struct htnode) * (m + 1)); if (!(*HT)) { printf("%s: malloc failed\n", __FUNCTION__); return ERROR; } for (i = 1; i <= n; i++) { (*HT)[i].weight = w[i]; (*HT)[i].lchild = 0; (*HT)[i].rchild = 0; (*HT)[i].father = 0; } for (i = n + 1; i <= m; i++) { (*HT)[i].weight = 0; (*HT)[i].lchild = 0; (*HT)[i].rchild = 0; (*HT)[i].father = 0; } for (i = n + 1; i <= m; i++) { select(*HT, i - 1 , &s1, &s2); printf("s1 = %d, s2 = %d\n", s1, s2); (*HT)[s1].father = i; (*HT)[s2].father = i; /* 此处不要写成w[s1] + w[s2]了 */ (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight; (*HT)[i].lchild = s1; (*HT)[i].rchild = s2; } *hc = (char**) malloc(sizeof(char *) * (n + 1)); if (!(*hc)) { printf("%s: malloc failed\n", __FUNCTION__); return ERROR; } /* n个节点的编码长度最多为n-1,但留一个给'\0'作字符串结束 */ cd = (char*)malloc(sizeof(char) * (n - 1 + 1)); cd[n-1] = '\0'; for (i = 1; i <= n; i++) { start = n-1; for (c = i,f = (*HT)[c].father; f != 0; c = f,f = (*HT)[c].father) { if ((*HT)[f].lchild == c) { cd[--start] = '0'; } else { cd[--start] = '1'; } } /* 多留一个字节给'\0'使用 */ (*hc)[i] = (char *)malloc(sizeof(char) * (n - 1 - start + 1));
if (!(*hc)[i]) { printf("%s: malloc failed\n", __FUNCTION__); return ERROR; } strcpy((*hc)[i], &cd[start]); } } void print_code(char **HC, int *w, int n) { int i; for (i = 1; i <= n; i++) { printf("the %d char(weight(%d))'s code is %s\n", i, w[i], HC[i]); } } int main(void) { struct htnode *HT; char **HC; int n = N; int w[N+1] = {-1, 3, 5, 2, 7}; huffman_code(&HT, &HC, w, n); print_code(HC, w, n); }