Huffman编码实现

来自于/*小甲鱼数据结构与算法视频讲解*/
//decode(); 函数为自己编写
//对字符进行哈弗曼编码,由于计算机用8bits存储一个char字符,so,一共可以有256种字符,但ASCII码表中只有128个字符。在本程序中用char code[256];存储各个字符编码的结果,其实也可以用128位,即char code[128].因为:总共有128个字符,建立哈弗曼树时,树最多有128层,这意味着最底层的叶子节点的编码位数为127.所以定义code[128]刚刚好存储编码结果(c风格字符串最后还有一个'\0'结尾标识)。
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">//
/******main.cpp******/
/

#include <stdio.h>
#include <stdlib.h>
#include "huffman.h"
#include "queue.h"

void main()
{
	htTree* codeTree=buildTree("I love FishC.com!");
	hlTable* codeTable=buildTable(codeTree);
	encode(codeTable,"I love FishC.com!");
	decode(codeTree,"100011001110010000101011010010100000101011111011111101100101101110");
}


 

</pre><pre name="code" class="cpp">/
/******queue.h******/
/

#include "huffman.h"

#define TYPE htNode*
#define MAX_SZ 256

typedef struct _pQueueNode{
	TYPE val; 
	unsigned int priority;
	struct _pQueueNode *next;
} pQueueNode;

typedef struct _pQueue{
	unsigned int size;
	pQueueNode *first;
} pQueue;

void initPQueue(pQueue **queue);
void addPQueue(pQueue **queue,TYPE val,unsigned int priority);
TYPE getPQueue(pQueue **queue);

///
/******huffman.h******/
///


#ifndef _HUFFMAN_H
#define _HUFFMAN_H

typedef struct _htNode{
	char symbol;
	struct _htNode *left,*right;
} htNode;

typedef struct _htTree{
	htNode *root;
} htTree;

typedef struct _hlNode{
	char symbol;
	char *code;
	struct _hlNode *next;
}hlNode;

typedef struct _hlTable{
	hlNode *first;
	hlNode *last;
}hlTable;

htTree* buildTree(char* inputString);
hlTable* buildTable(htTree *huffmanTree);
void encode(hlTable *table,char *stringToEncode);
void decode(htTree *tree,char *stringToDecode);
void traverseTree(htNode *treeNode,hlTable **table,int j,char code[256]);
#endif

/
/******queue.cpp******/
/


#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

void initPQueue(pQueue **queue)
{
	(*queue)->first=NULL;
	(*queue)->size=0;
	return;
}

void addPQueue(pQueue **queue,TYPE val,unsigned int priority)
{
	if((*queue)->size==MAX_SZ)
	{
		printf("\nQueue is full!\n");
		return;
	}
	pQueueNode *aux=(pQueueNode*)malloc(sizeof(pQueueNode));
	if(!aux)  return;
	aux->priority=priority;
	aux->val=val;
	if((*queue)->size==0 || (*queue)->first==NULL)
	{
		aux->next=NULL;
		(*queue)->first=aux;
		(*queue)->size=1;
	}
	else
	{
		if(priority<=(*queue)->first->priority)
		{
			aux->next=(*queue)->first;
			(*queue)->first=aux;
			(*queue)->size++;
			return;
		}
		else
		{
			pQueueNode *iterator=(*queue)->first;
			while(iterator->next!=NULL)
			{
				if(priority<=iterator->next->priority)
				{
					aux->next=iterator->next;
					iterator->next=aux;
					(*queue)->size++;
					return;
				}
				iterator=iterator->next;
			}
			if(iterator->next==NULL)
			{
				aux->next=NULL;
				iterator->next=aux;
				(*queue)->size++;
				return;
			}
		}
	}
}

TYPE getPQueue(pQueue **queue)
{
	TYPE returnValue;
	if((*queue)->size>0)
	{
		returnValue=(*queue)->first->val;
		(*queue)->first=(*queue)->first->next;
		(*queue)->size--;
	}
	else
		printf("\nQueue is empty!\n");
	return returnValue;
}


/******huffman.cpp******/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "huffman.h"
#include "queue.h"

htTree* buildTree(char* inputString)
{
	int* probability=(int*)malloc(256*sizeof(int));
	int i;
	for(i=0;i<256;++i)
		probability[i]=0;
	for(i=0;inputString[i]!='\0';++i)
		probability[(unsigned char)inputString[i]]++;
	pQueue *huffmanQueue=(pQueue*)malloc(sizeof(pQueue));
	initPQueue(&huffmanQueue);
	for(i=0;i<256;++i)
	{
		if(probability[i]!=0)
		{
			htNode *aux=(htNode*)malloc(sizeof(htNode));
			aux->left=NULL;
			aux->right=NULL;
			aux->symbol=(char)i;
			addPQueue(&huffmanQueue,aux,probability[i]);
		}
	}

	free(probability);

	while(huffmanQueue->size!=1)
	{
		int priority=huffmanQueue->first->priority;
		priority+=huffmanQueue->first->next->priority;
		htNode *left=getPQueue(&huffmanQueue);
		htNode *right=getPQueue(&huffmanQueue);
		htNode *newNode=(htNode*)malloc(sizeof(htNode));
		if(!newNode)  return NULL;
		newNode->left=left;
		newNode->right=right;
		addPQueue(&huffmanQueue,newNode,priority);
	}

	htTree *tree=(htTree*)malloc(sizeof(htTree));
	if(!tree)  return NULL;
	tree->root=getPQueue(&huffmanQueue);
	return tree;
}

hlTable* buildTable(htTree *huffmanTree)
{
	hlTable *table=(hlTable*)malloc(sizeof(hlTable));
	if(!table)  return NULL;
	table->first=NULL;
	table->last=NULL;

	char code[256];
	int j=0;
	traverseTree(huffmanTree->root,&table,j,code);
	return table;
}

void traverseTree(htNode *treeNode,hlTable **table,int j,char code[256])
{
	if(treeNode->left==NULL && treeNode->right==NULL)
	{
		code[j]='\0';
		hlNode *aux=(hlNode*)malloc(sizeof(hlNode));
		aux->code=(char*)malloc(sizeof(char)*(strlen(code)+1));
		strcpy(aux->code,code);
		aux->symbol=treeNode->symbol;
		aux->next=NULL;
		if((*table)->first==NULL)
		{
			(*table)->first=aux; 
			(*table)->last=aux;
		}
		else
		{
			(*table)->last->next=aux;
			(*table)->last=aux; 
		}
	}
	if(treeNode->left!=NULL)
	{
		code[j]='0';
		traverseTree(treeNode->left,table,j+1,code);
	}
	if(treeNode->right!=NULL)
	{
		code[j]='1';
		traverseTree(treeNode->right,table,j+1,code);
	}
}

void encode(hlTable *table,char *stringToEncode)
{
	hlNode *traversal;
	int i;
	printf("Encoding.......\n\nInput string: \n%s\n\nEncoded string: \n",stringToEncode);
	for(i=0;stringToEncode[i]!='\0';++i)
	{
		traversal=table->first;
		while(traversal->symbol!=stringToEncode[i])
			traversal=traversal->next;
		printf("%s",traversal->code);
	}
	printf("\n");
}

void decode(htTree *tree,char *stringToDecode)
{
	htNode *t=tree->root;
	if(!t)  return;
	int i;
	for(i=0;stringToDecode[i]!='\0';++i)
	{
		if(stringToDecode[i]=='0')
		{
			t=t->left;
			if(t->left==NULL && t->right==NULL)
			{
				printf("%c",t->symbol);
				t=tree->root;
			}
		}
		else if(stringToDecode[i]=='1')
		{
			t=t->right;
			if(t->left==NULL && t->right==NULL)
			{
				printf("%c",t->symbol);
				t=tree->root;
			}
		}
	}
}

程序执行结果:


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值