- 代码带有注释,不详细解释,检测采用严蔚敏老师数据结构的一个范例
HuffmanCode.h
#ifndef _HUFFMANCODE_H_
#define _HUFFMANCODE_H_
#include <stdbool.h>
typedef struct {
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void HuffmanCoding(HuffmanTree *HT, HuffmanCode *HC, int *w, int n);
#endif
HuffmanCode.c
#include "HuffmanCode.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
void Select(HuffmanTree HT, int n, int *s1, int *s2);
void HuffmanCoding(HuffmanTree *HT, HuffmanCode *HC, int *w, int n) {
if (n<=1)
return;
int m = 2 * n - 1;
(*HT) = (HuffmanTree)malloc((m+1)*sizeof(HTNode));
HuffmanTree p = (*HT) + 1;
int i, s1, s2;
for (p = (*HT) + 1, i = 1; i <= n; ++i, ++p, ++w) {
(*p).weight = *w;
(*p).parent = 0;
(*p).lchild = 0;
(*p).rchild = 0;
}
for (; i <= m; ++i, ++p) {
(*p).weight = 0;
(*p).parent = 0;
(*p).lchild = 0;
(*p).rchild = 0;
}
for (i = n + 1; i <= m; ++i) {
Select((*HT), i-1, &s1, &s2);
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
(*HT)[i].lchild = s1;
(*HT)[i].rchild = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
// - - - 从叶子到根逆向求每个字符的哈夫曼编码 - - -
(*HC) = (HuffmanCode)malloc((n+1)*sizeof(char*)); //分配n个字符编码的头指针向量
char *cd = (char*)malloc(n*sizeof(char)); //分配求编码的工作空间
cd[n-1] = '\0';
for (i = 1; i <= n; ++i) {
int start = n - 1;
int c, f;
for (c = i, f = (*HT)[i].parent; f != 0; c = f, f = (*HT)[f].parent)
if ((*HT)[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
(*HC)[i] = (char*)malloc((n - start) * sizeof(char));
/* for (int j = 0; j < start; j++) {
cd++;
}*/
strcpy((*HC)[i], &cd[start]);
}
free(cd);
}
void Select(HuffmanTree HT, int n, int *s1, int *s2) {
int min = INT_MAX, semin = INT_MAX;
for (int i = 1; i <= n; ++i) {
if (HT[i].parent == 0 && HT[i].weight < min) {
min = HT[i].weight;
*s1 = i;
}
}
HT[*s1].parent = 1;
for (int i = 1; i <= n; ++i) {
if (HT[i].parent == 0 && HT[i].weight < semin) {
semin = HT[i].weight;
*s2 = i;
//HT[i].parent = 1;
}
}
if(*s1>*s2) {
int j=*s1;
*s1=*s2;
*s2=j;
}
//printf("%d\n%d\n",*s1,*s2);
}
main.c
#include <stdio.h>
#include "HuffmanCode.h"
int main () {
HuffmanTree T;
HuffmanCode C;
int w[8] = {5,29,7,8,14,23,3,11};
HuffmanCoding(&T, &C, w, 8);
for (int i = 1; i <= 8; i++) {
printf("%s\n",C[i]);
}
return 0;
}
运行示例:
运行结果: