Huffman编码

huffman.h


#pragma once
#include"stdafx.h"

typedef struct _htNode
{
	char symbol;
	struct _htNode *lchild;
	struct _htNode *rchild;
}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* strs);
hlTable* buildTable(htTree* codeTree);
void encode(hlTable* codeTable, char*str);
void decode(htTree*codeTree, char *code);
void traversing(htNode* codeNode, hlTable *table, int level, char code[]);
char* codeChar(hlTable* codeTable, char str);



queue.h

优先队列:按权重由小到大排序


#pragma once
#include"huffman.h"
#define TYPE htNode*
#define MAX_SIZE 256

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

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

void initQueue(pQueue**queue);
void addQueue(pQueue**queue,TYPE val,unsigned int priority);
TYPE getPQueue(pQueue**);



queue.cpp

#include"stdafx.h"
#include"queue.h"

void initQueue(pQueue**queue){
	*queue = new pQueue;
	(*queue)->first = NULL;
	(*queue)->size = 0;
}
void addQueue(pQueue**queue, TYPE val, unsigned int priority){
	if ((*queue)->size == MAX_SIZE)
	{
		printf("队列已满");
		return;
	}
	//创建一个pQueueNode
	pQueueNode * pNode = new pQueueNode;
	pNode->next = NULL;
	pNode->priority = priority;
	pNode->val = val;
	//按优先级插入
	//对空,直接插入
	if ((*queue)->size == 0||(*queue)->first == NULL)
	{
		(*queue)->first = pNode;
		(*queue)->size = 1;
		pNode->next = NULL;
	}
	else{
		//如果对首元素的优先级大于当前插入的节点,直接插在对首即可
		if ((*queue)->first->priority >= priority)
		{
			pNode->next = (*queue)->first;
			(*queue)->first = pNode;
			(*queue)->size++;
		}
		else
		{
			pQueueNode *iterator = (*queue)->first;
			while (iterator->next != NULL && iterator->next->priority < priority)
			{
				iterator = iterator->next;
			}
			//如果遍历到了对尾,直接插入
			if (!iterator->next)
			{
				iterator->next = pNode;
				(*queue)->size++;
				pNode->next = NULL;
			}
			else
			{
				pNode->next = iterator->next;
				iterator->next = pNode;
				(*queue)->size++;
			}
		}
	}
}
TYPE getPQueue(pQueue**queue){
	TYPE result = NULL;
	if (!(*queue)->size)
	{
		printf("队列为空...");
		//return;
	}
	else
	{
		result = (*queue)->first->val;
		(*queue)->size--;
		(*queue)->first = (*queue)->first->next;
	}
	return result;
}


huffman.cpp




#include"stdafx.h"
#include"huffman.h"
#include<string.h>
#include"queue.h"
//建立huffman树
char code[256];

htTree* buildTree(char* strs){
	pQueue * queue = NULL;
	initQueue(&queue);
	//统计字符出现次数,建立频率表
	unsigned int probility[MAX_SIZE];
	//初始化频率表
	for (int i = 0; i < MAX_SIZE; i++){
		probility[i] = 0;
	}
	//根据字符的AScii码值对应数组的下标,累加次数
	for (unsigned int i = 0; strs[i]!='\0'; i++){
		if (strs[i]!='\0')
		{
			probility[(unsigned int)strs[i]]++;
		}
	}
	//优先队列填充数据
	for (int i = 0; i < MAX_SIZE; i++){
		if (probility[i] != 0)
		{
			htNode* htnode = new htNode;
			htnode->lchild = NULL;
			htnode->rchild = NULL;
			htnode->symbol = i;
			addQueue(&queue, htnode, probility[i]);
		}
	}
	//delete[]probility;
	pQueueNode *iterator = queue->first;
	while (queue->size >1)
	{
		//huffman树节点
		htNode* hufNode = new htNode;
		unsigned int priority = queue->first->priority + queue->first->next->priority;
		hufNode->lchild = getPQueue(&queue);
		hufNode->rchild = getPQueue(&queue);
		addQueue(&queue, hufNode, priority);
		
	}
	htTree * tree = new htTree;
	tree->root = getPQueue(&queue);
	return tree;
}
hlTable* buildTable(htTree* codeTree){
	hlTable * codeTable = new hlTable;
	codeTable->first = NULL;
	codeTable->last = NULL;
	traversing(codeTree->root, codeTable, 1, code);
	return codeTable;
}
void encode(hlTable* codeTable, char*str){
	for (size_t i = 0;str[i]!='\0'; i++)
	{
		printf("%s", codeChar(codeTable, str[i]));
	}
}
void decode(htTree*codeTree, char *code){
	htNode* ptr = codeTree->root;
	for (size_t i = 0;  code[i]!='\0'; i++)
	{
		if (ptr->lchild == NULL && ptr->rchild == NULL)
		{
			printf("%c", ptr->symbol);
			ptr = codeTree->root;
		}
		if (code[i] == '0')
		{
			ptr = ptr->lchild;
		}
		if (code[i] == '1')
		{
			ptr = ptr->rchild;
		}
	}
	if (ptr->lchild ==NULL && ptr->rchild ==NULL)
	{
		printf("%c", ptr->symbol);
	}
}

void traversing(htNode* codeNode,hlTable *table,int level,char code[]){
	if (codeNode->lchild == NULL && codeNode->rchild == NULL)
	{
		code[level - 1] = '\0';
		printf("该节点是%c,编码是%s\n",codeNode->symbol,code);
		hlNode *hl = new hlNode;
		hl->code = new char[level];
		strcpy(hl->code, code);
		//strcpy(hl->code, code);
		hl->symbol = codeNode->symbol;
		if (table->first ==NULL || table->last == NULL)
		{
			table->first = hl;
			table->last = hl;
		}
		else
		{
			table->last->next = hl;
			hl->next = NULL;
			table->last = hl;
		}
		
	}
	else
	{
		if (codeNode->lchild)
		{
			code[level - 1] = '0';
			traversing(codeNode->lchild, table, level + 1, code);
		}
		if (codeNode->rchild)
		{
			code[level - 1] = '1';
			traversing(codeNode->rchild, table, level + 1, code);
		}
	}
}

char* codeChar(hlTable* codeTable, char str){
	hlNode* ptr = codeTable->first;
	while (ptr!=NULL)
	{
		if (ptr->symbol == str)
		{
			return ptr->code;
		}
		ptr = ptr->next;
	}
	return NULL;
}


主程序



#include "stdafx.h"
#include"huffman.h"
#include<stdlib.h>
#include<iostream>
#include<fstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
	htTree* codeTree = buildTree("Never put off what you can do today until tomorrow");
	//traversing(htNode* codeNode,hlTable *table,int level,char code[])
	hlTable * codeTable = buildTable(codeTree);
	encode(codeTable, "what you can do today");
	printf("\n");
	decode(codeTree, "111101010110001101001000111000010011101000101011001110001111000011011100010110110110001000101011100001010111011110111111");
	system("pause");
	return 0;
}









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值