c语言实现哈夫曼编码

哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。

1951年, 哈夫曼和他在 MIT 信息论的同学需要选择是完成学期报告还是期末 考试。导师Robert M. Fano给他们的学期报告的题目是,寻找最有效的 二进制编码。由于无法证明哪个已有编码是最有效的, 哈夫曼放弃对已有编码的研究,转向新的探索,最终发现了基于有序频率 二叉树编码的想法,并很快证明了这个方法是最有效的。
由于这个算法,学生终于青出于蓝,超过了他那曾经和 信息论创立者 香农共同研究过类似编码的导师。 哈夫曼使用自底向上的方法构建 二叉树,避免了次优算法Shannon-Fano编码的最大弊端──自顶向下构建树

以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损耗压缩。

/*

我要说明一下,下面代码不是我写的,代码出自清华大学朱老师作品,我贴出来学学,整理一下自己收藏的资料。

*/

#include 
#include 
#define M 8
typedef struct node *link;
struct node { int f; link l, r; };
link NODE(int f, link l, link r)
{
	link t = malloc(sizeof *t);
	t->f = f; t->l = l; t->r = r;
	return t;
}
link hh[M], *h = hh-1;
int N;
void swap(int i, int j)
{
	link tmp = h[i]; h[i] = h[j]; h[j] = tmp;
}
void sift_down(int k, int n)
{
	int j;
	while (2*k<=n) {
		j = 2*k;
		if (j+1<=n && h[j+1]->f < h[j]->f) j++;
		if (h[k]->f < h[j]->f) break;
		swap(k, j); k = j;
	}
}
void sift_up(int k)
{
	int j;
	while (k>1) {
		j = k/2;
		if (h[j]->f < h[k]->f) break;
		swap(k, j); k = j;
	}
}
link delMin()
{
	swap(1, N--);
	sift_down(1, N);
	return h[N+1];
}
void insert(link t)
{
	h[++N] = t;
	sift_up(N);
}
void build_heap()
{
	int i;
	N = M;
	for (i=N/2; i>=1; i--) sift_down(i, N);
}
link create_huffman_tree(int a[])
{
	int i;
	for (i=1; i<=M; i++) h[i] = NODE(a[i-1], NULL, NULL);
	build_heap();
	while (N>1) {
		link t1 = delMin();
		link t2 = delMin();
		insert(NODE(t1->f + t2->f, t1, t2));
	}
	return delMin();
}
void pprint(link t)
{
	if (t) {
		printf("(");
		printf("%d", t->f);
		pprint(t->l);
		pprint(t->r);
		printf(")");
	} else printf("()");
}
int main()
{
	int a[] = { 5, 29, 7, 8, 14, 23, 3, 11 };
	link root = create_huffman_tree(a);
	printf("\\tree"); pprint(root); printf("\n");
	return 0;
}


你可能感兴趣的:(算法和数据结构)