Huffman树与Huffman编码(C语言实现)

1、Huffman树结构定义

#ifndef _huffman_tree_h
#define _huffman_tree_h

typedef struct huffman_tree_node
{
	float weight;
	int lchild, rchild, parent;
}huffman_tree_node, * huffman_tree;

typedef struct huffman_code
{
	char ch;
	char * code;
}huffman_code;


void create_huffman_tree( huffman_tree * root, float weight[], int n );

void huffman_encode( huffman_tree root, huffman_code * codes );

#endif

2、构造Huffman树

void create_huffman_tree( huffman_tree * root, float weight[], int n )
{
	huffman_tree_node * p = NULL;
	int s1, s2;	// index
	int i, n_nodes = 0;
	if( n < 1 )
		return;
	n_nodes = 2 * n - 1;
	p = ( huffman_tree_node * )malloc( sizeof( huffman_tree_node ) * n_nodes );
	assert( p != NULL );
	
	for( i = 0; i < n_nodes; ++i )
	{
		p[i].weight = i < n ? weight[i] : 0;
		p[i].lchild = p[i].rchild = p[i].parent = NULL;
	}

	for( i = n; i < n_nodes; ++i )
	{
		sel_2_min( *root, weight, i - 1, &s1, &s2 );
		p[s1].parent = p[s2].parent = i;
		p[i].lchild = s1;
		p[i].rchild = s2;
		p[i].weight = p[s1].weight + p[s2].weight;
	}
	*root = p;
}

其中函数sel_2_min的功能为选出数组w中最小的父指针为空的两个元素所在索引,比较高效的求解方案是用最小堆。

3、Huffman编码

typedef struct huffman_code
{
	char ch;
	char * code;
}huffman_code;

从每个叶节点上溯,得到编码的0-1序列

// 计算每个叶节点的编码,约定左分支编码为'0',右分支编码为'1'
void huffman_encode( huffman_tree root, huffman_code hcode[], int n )
{
	int i, j = 0, k, id_par;
	huffman_tree_node * p = root;
	char * code = ( char * )malloc( sizeof( char ) * n );  
	memset( code, '\0', sizeof( char) * n );

	hcode = ( huffman_code * )malloc( sizeof( huffman_code ) * n );
	assert( hcode != NULL );
	for( i = 0; i < n; ++i )
	{
		hcode[i].code = ( char * )malloc( sizeof( char ) * n );
		memset( hcode[i].code, 0, sizeof( char ) * n );
		hcode[i].ch = root[i].weight;
	}
	
	for( i = 0; i < n; ++i )
	{
		k = n - 1;
		code[k] = '\0';
		j = i;
		while( p[j].parent != 0 )
		{
			id_par = p[j].parent;
			code[--k] = p[id_par].lchild == j ? '0' : '1';
			j = id_par;
		}
		strcpy( hcode[i].code, &code[k] );
	}
}

你可能感兴趣的:(Data,Structure)