霍夫曼编码实现

原创 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 ;
		}
	}
}

运行结果:

频率 编码:





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

HashMap的实现机制、实现自己的HashMap

在数据结构中,数组列表插入删除不方便,链表查找效率不高。而HashMap拥有了这两者的优点。HashMap本质上是由数组+链表组成的结构。源码分析注意:此部分参考自[https://dzone.com...
  • joson793847469
  • joson793847469
  • 2016年10月04日 09:22
  • 889

关于set想说的(一)之Set的实现类及必要的方法

最近看到了《Thinking in Java》的第17章 容器深入探究,17.6 Set和存储顺序。自己写了写测试代码,加深下理解。主要设计toString()方法(主要是为了方便打印),equals...
  • fan2012huan
  • fan2012huan
  • 2016年03月23日 10:46
  • 1736

Map集合及其实现类

Map 接口 ----|HashMap -------------extends Map ----|Hashtable -------------imp...
  • zhou920786312
  • zhou920786312
  • 2017年04月04日 14:49
  • 410

三子棋的实现的实现的实现

三子棋的实现三子棋是一个简单的游戏,特别适合编程新手练习,这里我们就简单介绍一下c语言实现三子棋的过程。—————————————————我是下划线——————————————首先我们将函数分为两大部...
  • Cyrus_wen
  • Cyrus_wen
  • 2017年12月02日 19:09
  • 48

printf内部实现

通过printf的简易实现,熟悉变长参数表
  • dudubird90
  • dudubird90
  • 2015年09月16日 15:26
  • 2356

C++笔试题 String类的实现

这个在面试或笔试的时候常问到或考到。 已知类String的原型为: class String { public:      String(const char *str = NULL);// 普通...
  • caoshangpa
  • caoshangpa
  • 2016年05月29日 09:12
  • 3905

乐观锁的两种实现方式

什么场景下需要使用锁? 在多节点部署或者多线程执行时,同一个时间可能有多个线程更新相同数据,产生冲突,这就是并发问题。这样的情况下会出现以下问题: 更新丢失:一个事务更新数据后,被另一个更新数据的...
  • lxy344x
  • lxy344x
  • 2017年08月01日 23:25
  • 1378

java,什么是序列化,怎么实现序列化

转自:http://zhidao.baidu.com/question/202556575.html?qbl=relate_question_0&word=%CA%B2%C3%B4%CA%C7java...
  • zhangzhangjava
  • zhangzhangjava
  • 2016年04月12日 17:33
  • 3258

【STL】 vector 模拟实现

上一篇博客说了一下list的使用,其实vector用法基本上和list是一样的,所以此篇博客就只模拟实现以下vector。vector你可以把它理解成一个顺序表或者数组。只是STL里的vector是由...
  • pointer_y
  • pointer_y
  • 2016年09月23日 19:55
  • 664

malloc实现原理

本文大致讲解一下Linux下malloc的底层实现原理。 首先malloc肯定是从堆中分配内存,而堆又在用户空间中占据什么位置?通过下面这张图可以看出来: 很明显是32位系统,寻址空间是4...
  • xieyihua1994
  • xieyihua1994
  • 2016年10月03日 10:52
  • 507
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:霍夫曼编码实现
举报原因:
原因补充:

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