C || 哈夫曼树及哈夫曼编码的实现

  • 代码带有注释,不详细解释,检测采用严蔚敏老师数据结构的一个范例

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;
}

运行示例:

在这里插入图片描述

在这里插入图片描述

运行结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/perry0528/article/details/82754816