哈夫曼编码的C语言实现

原创 2017年01月02日 22:44:08

代码来自于《小甲鱼C++快速入门》

主程序main.cpp

#include "stdafx.h"
#include <stdlib.h>
#include "huffman.h"
int main()
{
	htTree *codeTree = buildTree("I love wwwwwwwwwFishC.com!");//建立哈夫曼树
	hlTable *codeTable = buildTable(codeTree);//建立编码表
	encode(codeTable,"I love FishC.com!");//对输入的字符串进行编码
	decode(codeTree,"0011111000111");//解码
	system("pause");
	return 0;
}

两个头文件:

huffman.h:定义了哈夫曼树和编码表的结构

#pragma once
#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 *str);
hlTable *buildTable(htTree *huffmanTree);
void encode(hlTable *table, char *stringToEncode);
void decode(htTree *tree, char *stringToDecode);
#endif


queue.h:定义了有序队列的结构,将字符按优先级排列,即频率从小到大排列,val是树节点,直接由队列建立起哈夫曼树

#pragma once
#ifndef _PQUEUE_H
#define _PQUEUE_H
#include "huffman.h"
#define MAX_SZ 256
#define TYPE htNode *

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 getQueue(pQueue **queue);
#endif

两个cpp文件实现两个头文件声明的函数:

huffman.cpp

#include "stdafx.h"
#include "queue.h"
#include "huffman.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
htTree *buildTree(char *str)
{
	int *probability = (int *)malloc(sizeof(int) * 256);
	//初始化
	for (int i = 0; i < 256; i++)
	{
		probability[i] = 0;
	}
	//统计待编码的字符串各个字符出现的次数
	for (int j = 0; str[j] != '\0'; j++)
	{
		probability[str[j]]++;
	}

	//定义队列的头指针
	pQueue *huffmanQueue;
	initPQueue(&huffmanQueue);
	//填充队列
	for (int k = 0; k < 256; k++)
	{
		if (probability[k] != 0)
		{
			htNode *aux = (htNode *)malloc(sizeof(htNode));
			aux->left = NULL;
			aux->right = NULL;
			aux->symbol = (char)k;
			addPQueue(&huffmanQueue, aux, probability[k]);
		}
	}
	free(probability);
	//生成哈夫曼树
	while (huffmanQueue->size != 1)
	{
		unsigned int newPriority = huffmanQueue->first->priority + huffmanQueue->first->next->priority;
		htNode *aux = (htNode *)malloc(sizeof(htNode));
		aux->left = getQueue(&huffmanQueue);
		aux->right = getQueue(&huffmanQueue);
		addPQueue(&huffmanQueue, aux, newPriority);
	}
	htTree *tree = (htTree *)malloc(sizeof(htTree));
	tree->root = getQueue(&huffmanQueue);
	return tree;
}

void traverseTree(htNode *treeNode,hlTable **table,int k,char code[256])
{
	if (treeNode->left == NULL&&treeNode->right == NULL)
	{
		code[k] = '\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[k] = '0';
		traverseTree(treeNode->left,table,k+1,code);
	}
	if (treeNode->right != NULL)
	{
		code[k] = '1';
		traverseTree(treeNode->right, table, k + 1, code);
	}
}

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

	char code[256];
	int k = 0;

	traverseTree(huffmanTree->root,&table,k,code);
	return table;
}
void encode(hlTable *table, char *stringToEncode)
{
	hlNode *traversal;
	printf("Encoding......\n\nInput string:\n%s\n\nEncoded string :\n",stringToEncode);
	for (int 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 *traversal = tree->root;

	printf("\n\nDecoding......\n\nInput string: \n%s\n\nDecoded string: \n",stringToDecode);
	for (int i = 0; stringToDecode[i] != '\0'; i++)
	{
		if (traversal->left == NULL&&traversal->right == NULL)
		{
			printf("%c", traversal->symbol);
			traversal = tree->root;
		}
		if (stringToDecode[i] == '0')
			traversal = traversal->left;
		else if (stringToDecode[i] == '1')
			traversal = traversal->right;
		else
		{
			printf("The input string is not coded correctly!\n");
			return;
		}
	}
	printf("\n\n");
	return;
}

queue.cpp:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
void initPQueue(pQueue **queue)
{
	*queue = (pQueue *)malloc(sizeof(pQueue));
	(*queue)->first = NULL;
	(*queue)->size = 0;
	return;
}
void addPQueue(pQueue **queue, TYPE val, unsigned int priority)
{
	if ((*queue)->size == MAX_SZ)
	{
		printf("\n Queue is full. \n");
		return;
	}
	pQueueNode *aux = (pQueueNode *)malloc(sizeof(pQueueNode));
	aux->priority = priority;
	aux->val = val;
	if ((*queue)->size == 0||(*queue)->first==NULL)
	{
		aux->next = NULL;
		(*queue)->first = aux;
		(*queue)->size = 1;
		return;
	}
	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 getQueue(pQueue **queue)
{
	TYPE returnValue;
	if ((*queue)->size > 0)
	{
		returnValue = (*queue)->first->val;
		(*queue)->first = (*queue)->first->next;
		(*queue)->size--;
	}
	else
	{
		returnValue = NULL;
		printf("\n Queue is empty \n");
	}
	
	return returnValue;
}
运行结果:



版权声明:本文为博主原创文章,未经博主允许不得转载。

哈夫曼树与哈夫曼编码(C语言代码实现)

在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN)树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码。 首先介绍...

霍夫曼树及霍夫曼编码的C语言实现

从周五开始学习霍夫曼树,一直到今天终于完成,期间遇到了各种各样的棘手的问题,通过一遍遍在纸上分析每一步的具体状态得以解决。现在对学习霍夫曼树的过程加以记录首先介绍霍夫曼树霍夫曼树(Huffman Tr...

C语言-数据结构-哈夫曼编码-Huffman-源代码

1. 目标 读取一段字符,生成哈夫曼编码,并输出。如下所示: 2. 代码结构 2.1 统计各个字符出现的次数,并排序; 2.2 根据生成的哈夫曼树,生成哈夫曼编...

贪心算法之哈夫曼编码(C语言实现)

如题问题描述:现有一个文本文件,其中包含的字符数据出现的次数各不相同,先要求对该文本中包含的字符进行编码,使文本占用的位数更小。问题分析:我们知道文件的存储都是以二进制数表示的,如:字符c可以表示为0...
  • W_ILU
  • W_ILU
  • 2016年03月19日 15:03
  • 3325

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C语言实现哈夫曼树、编码、解码及问题总结

一、准备知识 1、Huffman树 Huffman树是一类带权路径长度WPL最短的二叉树,中文名叫哈夫曼树或最优二叉树。 相关概念: 结点的路径长度:从根结点到该结点的路径上分支的数目。 树的路径长度...

C语言实现哈夫曼编码与译码

在电报通讯中,电文是以二进制的0、1序列传送的。字符集中的字符的使用频率是不同的(比如e和t的使用较之q和z要频繁得多),哈夫曼编码可以使得编码的总长最短,从而相同的位长可以传送更多的信息。   ...

哈夫曼树 C语言实现

哈夫曼树 C语言实现 分类: Data structure & Algorithm2013-12-06 23:10 180人阅读 评论(0) 收藏 举报 哈夫曼树哈夫曼编码 目录(?)[...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:哈夫曼编码的C语言实现
举报原因:
原因补充:

(最多只允许输入30个字)