霍夫曼编码实现

原创 2015年11月20日 11:10:34

仅供日后参考,价值不定。

问题描述:

只考虑英文字母(不区分大小写)和空格,计算每个字符出现的频率,给出霍夫曼编码。

实现思路:

1.丛文件中读取文本,同时记录每个字符的频率,并初始化树

2.根据初始化的树建立霍夫曼树

3.根据霍夫曼树进行编码

4.输出

要编码的字符串:

FAST is an algorithm proposed originally by rosten and drummond for identifying interest points in an image.
An interest point in an image is a pixel which has a well defined position and can be robustly detected.
Interest points have high local information content and they should be ideally repeatable between different images.
Interest point detection has applications in image matching object recognition tracking etc.
Since establishing a match can be understood (THIS IS UPPER CASE) as classifying pairs of points as being a match or not.
A classifier that relies on these hamming distances will work best when their distributions are most separated.
As we will see in section this is of course what happens with recognition rates being higher in the first pairs of the wall sequence than in the subsequent ones.
We have introduced the brief descriptor that relies on a relatively small numberof intensity difference tests to represent an image patch as a binary string. Not only is construction and matching for this descriptor much faster than forother state of the art ones.
It also tends to yield higher recognition rates as long as invariance to large in plane rotations is not a requirement.

代码:

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int node_num = 0;//树的叶子节点数
int tree_array_len = 2 * node_num -1;//节点总数
#define MAX_CODE_LEN 100
/*霍夫曼树结构*/
typedef struct HuffTreeNode{
	int weight;//权重
	char c;
	int lchild,rchild,parent;
}HuffTree;
/*霍夫曼编码结构*/
typedef struct Code{
	char code[MAX_CODE_LEN];
	char ch;
	int start;
}HuffCode;
/*函数声明*/
void Read_Freq(char *filename,HuffTree *T);
void CreateHuffTree(HuffTree *T);
void CreateHuffCode(HuffTree *T,HuffCode *C);
void PrintCode_Single(HuffCode *C);

int main(){
	HuffTree *T;
	HuffCode *C;
	T = (HuffTree *)malloc(sizeof(HuffTreeNode)*100);
	printf("Frequence:\n");
	Read_Freq("E:\\test1.txt",T);
	C = (HuffCode *)malloc(sizeof(HuffCode)*node_num);
	CreateHuffTree(T);
	CreateHuffCode(T,C);
	printf("character encodings:\n");
	PrintCode_Single(C);
	free(T);
	free(C);
	return 0;
}
/*函数实现*/
void Read_Freq(char *filename,HuffTree *T){
	FILE *fp;
	if((fp = fopen(filename,"r"))==NULL){
		printf("Cannot Open File\n");
		exit(0);
	}
	char ch;
	int weight[28] = {0};//26个字母和一个空格
	ch = fgetc(fp);
	while(EOF != ch){
		if(isupper(ch)){
			ch += 32;
			ch -= 'a';
			weight[ch]++;
		}else if(islower(ch)){
			ch -= 'a';
			weight[ch]++;
		}else if(' '==ch){
			weight[26]++;
		}else{
			ch = fgetc(fp);
			continue;
		}
		ch = fgetc(fp);
	}
	/*读到树里去*/
	int k = 0;
	for(int i=0;i<26;i++){
		if(weight[i]>0){
			T[k].c = 'a' + i;
			T[k].weight = weight[i];
			T[k].lchild = T[k].rchild = -1;
			T[k].parent = 0;
			++k;
			printf("char : %c\t freq: %d\n",'a'+i,weight[i]);
			node_num ++;//记录字符的个数
		}
	}
	/*空格处理*/
	if(weight[26]>0){
	T[k].c = ' ';
	T[k].weight = weight[26];
	T[k].lchild = T[k].rchild = -1;
	T[k].parent = 0;
	k++;
	node_num ++;
	printf("char : %c\t freq: %d\n",' ',weight[26]);
	}
	fclose(fp);
}
void CreateHuffTree(HuffTree *T){
	int Max = 10000;//权值的最大可能值
	int i,j,p1,p2;//p1,p2指向s1,s2所指向的下标
	int s1,s2;//s1,s2指向权值最小的两个结点
	tree_array_len = 2 * node_num -1;
	for(i=node_num;i<tree_array_len;i++){
		T[i].parent = 0;
		T[i].lchild = T[i].rchild = -1;
		T[i].weight = 0;
	}
	for(i=node_num;i<tree_array_len;i++){
		p1=0;p2=0;
		s1=Max;s2=Max;   
		for(j=0;j<i;j++){   //选出两个权值最小的根结点
			if(T[j].parent==0){
				if(T[j].weight<s1)
				{
					s2=s1;  //改变最小权、次小权及对应的位置
					s1=T[j].weight;
					p2=p1;
					p1=j;
				}
				else{
					if(T[j].weight<s2)
					{
						s2=T[j].weight;  //改变次小权及位置
						p2=j;
					}
				}
			}
		}
		T[p1].parent=i;
		T[p2].parent=i;
		T[i].lchild=p1;  //最小权根结点是新结点的左孩子
		T[i].rchild=p2;  //次小权根结点是新结点的右孩子
		T[i].weight=T[p1].weight+T[p2].weight;
	}
}
void CreateHuffCode(HuffTree *T,HuffCode *C){
	int i,c,p;
	HuffCode code;   
	for(i=0;i<node_num;i++)
	{
		code.start=node_num;
		code.ch=T[i].c;
		c=i;       //从叶结点出发向上回溯
		p=T[i].parent;   //p是T[i]的双亲
		while(p!=0)//没到根节点
		{
			code.start--;
			if(T[p].lchild==c){
				code.code[code.start]='0';   //T[i]是左子树,代码'0'
			}else{
				code.code[code.start]='1';   //T[i]是右子树,代码'1'
			}
			c=p;
			p=T[p].parent;
		}
		C[i]=code;    //编码存入C[i]
	}
}
void PrintCode_Single(HuffCode *C){
	for(int i=0;i<node_num;i++){
		printf("char: %c\t\t encode: ",C[i].ch);
		for(int j=C[i].start;j<node_num;j++){
			printf("%c",C[i].code[j]);
		}
		printf("\n");
	}
}
void GetCode(char ch,HuffCode *C,int &count){
	count = 0;
	for(int i=0;i<node_num;i++){
		if(ch==C[i].ch){
			for(int j=C[i].start;j<node_num;j++){
				printf("%c",C[i].code[j]);
				count++;
			}
			return ;
		}
	}
}

运行结果:

频率 编码:





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

相关文章推荐

霍夫曼编码实现

仅供日后参考,价值不定。 问题描述: 只考虑英文字母(不区分大小写)和空格,计算每个字符出现的频率,给出霍夫曼编码。 实现思路: 1.丛文件中读取文本,同时记录每个字符的频率,并初始化树 2...

霍夫曼树与霍夫曼编码

HUFFMAN树的定义: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度(WPL)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)。 wpl的计算:如...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

霍夫曼树和霍夫曼编码

霍夫曼编码是最基本的压缩编码方法。 介绍霍夫曼树首先清楚几个

霍夫曼编码

霍夫曼编码是可变字长编码(VLC)的一种。 Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就称Huffman编码。 ...

霍夫曼编码

相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huf...

霍夫曼编码

给定一个文本中出现的一组字符C,每个字符有其出现频率freq,想构造字符的最优二进制表示,即用来编码整个文本的二进制位最少 定长编码:每个字符用相同长度的二进制位数进行编码,则每个字符的长度...

霍夫曼编码

看了算法导论关于霍夫曼编码的内容,然后做了实现,可能并不是很好,写得比较复杂。//heap.h #ifndef HEAP_H #define HEAP_H #include #include ...

霍夫曼编码

前言忽然因为一些问题想研究下编码方式,就观察下这个东西。发现有些东西还是挺有意思的。如果没研究过通讯,确实不用一理解,比如异前置编码之类的东西,并且信息熵确实很高。记录下这次的思路。正文霍夫曼编码是一...

霍夫曼编码

霍夫曼编码

霍夫曼编码

#include #include #include #define N 10 typedef struct s { char ch,parent; int weight;     s...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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