1. 程式人生 > >基本的哈夫曼編碼演算法的實現

基本的哈夫曼編碼演算法的實現

huffman.h檔案

#include<stdio.h>

typedef int bool;
#define false 0
#define true 1
typedef struct _CharNode{
	int count;
	char name;
	int weight;
	bool flag;
	struct _CharNode *left;
	struct _CharNode *right;
}CharNode,*PcharNode;

PcharNode Huffman(PcharNode *C, int size);
PcharNode extract_min(PcharNode *Q);

huffman.c檔案
#include<stdio.h>
#include<string.h>
#include"huffman.h"
#include<malloc.h>

int countNum = 0;
int iter = 0;

void Swap(PcharNode *Q,int pos,int largest)
{
	PcharNode tmp = Q[pos];
	Q[pos] = Q[largest];
	Q[largest] = tmp;
}

int LeftPos(int pos)
{
	return 2 * pos + 1;
}

int RightPos(int pos)
{
	return 2 * pos + 2;
}

int Parent(int pos)
{
	return (pos - 1) / 2;
}

void max_heapify(PcharNode *Q,int pos)
{
	int left = LeftPos(pos);
	int right = RightPos(pos);
	int largest = pos;
	if(left < countNum && Q[pos]->count > Q[left]->count)
	{
		largest = left;
	}
	else
	{
		largest = pos;
	}
	if(right < countNum && Q[largest]->count > Q[right]->count)
	{
		largest = right;
	}	
	if(largest != pos)
	{
		Swap(Q,pos,largest);
		max_heapify(Q,largest);
	}
}

void heap_increase_key(PcharNode *Q,PcharNode node)
{
	int pos = countNum - 1;
	Q[pos] = node;
	while(pos >= 0 && Q[Parent(pos)]->count > Q[pos]->count)
	{
		Swap(Q,pos,Parent(pos));
		pos = Parent(pos);
	}
}

void max_heap_insert(PcharNode *Q,PcharNode node)
{
	countNum++;
	heap_increase_key(Q,node);
}

PcharNode extract_min(PcharNode *Q)
{
	PcharNode node = Q[0];
	Q[0] = Q[--countNum];
	max_heapify(Q,0);
	return node;
}

PcharNode Huffman(PcharNode *C,int size)
{
	int count = size;
	PcharNode *Q = C;
	int i;
	for(i = 0; i <= count - 2; i++)
	{
		PcharNode node = malloc(sizeof(CharNode));	
		memset(node,0,sizeof(CharNode));
		node->flag = false;
 		node->left = extract_min(Q);
		node->left->weight = 0;
		printf("this count is %d \n",node->left->count);
		node->right = extract_min(Q);
		node->right->weight = 1;
		printf("this count is %d \n",node->right->count);
		int z = node->left->count + node->right->count;
		node->count = z;
		max_heap_insert(Q,node);
	}

	return extract_min(Q);
}
	
void visitTree(PcharNode root,PcharNode Q,int *a)
{
	if(root != Q)
	{
		a[iter++] = Q->weight;
	}
	if(Q->flag == true)
	{
		int i;
		printf("%c ---> ",Q->name);
		for(i = 0; i < iter; i++)
		{
			printf("%d",a[i]);
		}
		printf("\n");
		iter--;
		return;
	}
	
	visitTree(root,Q->left,a);
	visitTree(root,Q->right,a);
	iter--;
}
void main(void)
{
	PcharNode *Q = malloc(sizeof(PcharNode) * 6);

	PcharNode node1 = malloc(sizeof(CharNode));
	node1->count = 5;
	node1->name = 'f';
	node1->flag = true;
	
	max_heap_insert(Q,node1);
		
	PcharNode node2 = malloc(sizeof(CharNode));
	node2->count = 9;
	node2->name = 'e';
	node2->flag = true;
	max_heap_insert(Q,node2);

	PcharNode node3 = malloc(sizeof(CharNode));
	node3->count = 12; 
	node3->name = 'c';
	node3->flag = true;
	max_heap_insert(Q,node3);

	PcharNode node4 = malloc(sizeof(CharNode));
	node4->count = 13;
	node4->name = 'b';
	node4->flag = true;
	max_heap_insert(Q,node4);

	PcharNode node5 = malloc(sizeof(CharNode));
	node5->count = 16;
	node5->name = 'd';
	node5->flag = true;
	max_heap_insert(Q,node5);

	PcharNode node6 = malloc(sizeof(CharNode));
	node6->count = 45; 
	node6->name = 'a';
	node6->flag = true;
	max_heap_insert(Q,node6);
	
	PcharNode root = Huffman(Q,countNum);
	PcharNode tmp = root;	
	printf("root->count = %d\n", root->count);
	//printf("root->left->count = %d\n",root->left->count);
		
	int a[10] = {-1};
	visitTree(root,tmp,a);
}

    主要思想是1、選擇最小出現頻率的兩個字符合併成一個2、建立huffman數。