精华内容
下载资源
问答
  • 哈夫曼压缩算法

    2012-12-26 21:08:46
    哈夫曼压缩算法,使用c#编写,先统计输入字串的权重,权重越大越靠近根节点
  • vc++哈夫曼压缩算法

    2011-03-22 17:43:54
    vc++哈夫曼压缩算法 vc++哈夫曼压缩算法
  • 精讲哈夫曼压缩算法

    千次阅读 2016-01-13 09:58:35
    哈夫曼压缩算法编码是无损压缩当中最好的方法。它使用预先二进制描述来替换每个符号,长度由特殊符号出现的频率决定。常见的符号需要很少的位来表示,而不常见的符号需要很多为来表示。 哈夫曼算法在改变任何符号...

    哈夫曼压缩算法编码是无损压缩当中最好的方法。它使用预先二进制描述来替换每个符号,长度由特殊符号出现的频率决定。常见的符号需要很少的位来表示,而不常见的符号需要很多为来表示。

    哈夫曼算法在改变任何符号二进制编码引起少量密集表现方面是最佳的。然而,它并不处理符号的顺序和重复或序号的序列。

    哈夫曼压缩算法之原理

    我不打算探究哈夫曼编码的所有实际的细节,但基本的原理是为每个符号找到新的二进制表示,从而通常符号使用很少的位,不常见的符号使用较多的位。

    简短的说,这个问题的解决方案是为了查找每个符号的通用程度,我们建立一个未压缩数据的柱状图;通过递归拆分这个柱状图为两部分来创建一个二叉树,每个递归的一半应该和另一半具有同样的权(权是∑NK =1符号数k, N是分之中符号的数量,符号数k是符号k出现的次数)

    这棵树有两个目的:

    1. 编码器使用这棵树来找到每个符号最优的表示方法

    2. 解码器使用这棵树唯一的标识在压缩流中每个编码的开始和结束,其通过在读压缩数据位的时候自顶向底的遍历树,选择基于数据流中的每个独立位的分支,一旦一个到达叶子节点,解码器知道一个完整的编码已经读出来了。

    我们来看一个例子会让我们更清楚。图2.2显示了一个10个字节的未压缩的数据。

    根据符号频率,哈夫曼编码器生成哈夫曼树(图2.4)和相应的编码表示(图2.3)。


    一个10个字节的未压缩的数据

    你可以看到,常见的符号接近根,因此只要少数位来表示。于是最终的压缩数据流如图2.5所示。


    编码表示

    哈夫曼编码器生成哈夫曼树

    压缩后的数据流是24位(三个字节),原来是80位(10个字节)。当然,我应该存储哈夫曼树,这样解码器就能够解码出对应的压缩流了,这就使得该例子中的真正数据流比输入的流数据量大。这是相对较短的数据上的副作用。对于大数据量来说,上面的哈夫曼树就不占太多比例了。


    最终的压缩数据流

    解码的时候,从上到下遍历树,为压缩的流选择从左/右分支,每次碰到一个叶子节点的时候,就可以将对应的字节写到解压输出流中,然后再从根开始遍历。

    哈夫曼压缩算法之实现

    哈夫曼编码器可以在基本压缩库中找到,其是非常直接的实现。

    这个实现的基本缺陷是:

    1. 慢位流实现

    2. 相当慢的解码(比编码慢)

    3. 最大的树深度是32(编码器在任何超过32位大小的时候退出)。如果我不是搞错的话,这是不可能的,除非输出的数据大于232字节。

    另一方面,这个实现有几个优点:

    1. 哈夫曼树以一个紧密的形式每个符号要求12位(对于8位的符号)的方式存储,这意味着最大的头为384。

    2. 编码相当容易理解

    哈夫曼编码在数据有噪音的情况(不是有规律的,例如RLE)下非常好,这中情况下大多数基于字典方式的编码器都有问题。

    以上就是对哈夫曼压缩算法的简单介绍。

    展开全文
  • 哈夫曼压缩算法C语言实现——步骤,详细注释源码

    万次阅读 多人点赞 2017-06-05 14:05:09
    哈夫曼压缩算法的详细实现步骤: 1、定义哈夫曼树节点,用结构体。 2、利用C语言文件读写,统计字符个数。 3、根据字符个数创建哈夫曼树(不懂haffman数据结构的自己查下资料,我这里就不再重复了) 4、根据哈夫曼树...

    哈夫曼压缩算法的详细实现步骤:

    1、定义哈夫曼树节点,用结构体。

    2、利用C语言文件读写,统计字符个数。

    3、根据字符个数创建哈夫曼树(不懂haffman数据结构的自己查下资料,我这里就不再重复了)

    4、根据哈夫曼树为每个出现的字符编码

    5、压缩:这里涉及到位操作,用char8位来储存字符编码(压缩的关键)。

    6、解压缩:读压缩文件,在char中从左到右按位遍历哈夫曼树

    (再不懂的看源码,注释够意思了。)

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h> 
    //定义一个哈夫曼节点,它是个结构体
    struct haffNode{
    	int weight;//权重,就是这个字符出现的个数;如果这个节点是个父节点的话 ,就是两个子节点权重的和 
    	char data;//这个用来存字符本身,比如字符是'c',data='c'; 
    	struct haffNode *leftChild=NULL,*rightChild=NULL;//定义左右子节点指针 
    }; 
    char code[256][50];//用二维数组来储存字符的哈夫曼编码,其中第一维的下标表示的是这个字符的ASCII码  
    haffNode left[50];//用来储存所有的左子节点 
    haffNode right[50];//用来储存所有的右子节点 
    unsigned char saveChar = 0; //用来保存二进制文件,因为char类型是1个字节,所以每8位储存一次 ,而且用unsigned无符号型,避免符号位干扰 
    unsigned char slidChar;//定义一个字符备用,以应对可能需要的操作 
    //排序函数,第一个参数是哈夫曼的节点数组,第二个是数组的长度,这里用冒泡排序 
    void sort(haffNode* node,int length){
    	int i,j; 
    	haffNode t;
    	for(i=0; i<length-1; i++){
    		for(j=i+1; j<length-i-1;j++){
    			if(node[j].weight < node[j+1].weight){
    				t = node[j];
    				node[j] = node[j+1];
    				node[j+1] = t;
    			}
    		}
    	} 
    } 
    //构建哈夫曼树 
    void creatHaffman(haffNode *node,int length){
    	if(length==1){
    	return; //如果数组长度为1,则结束递归,下面的就不再执行 
    	}
    	sort(node,length);	//将node数组按照weight从大到小排序 
    	haffNode parent;//生成父节点,因为我们的数组从大到小排序过了,所以数组最后面的就是最小的节点 
    	left[length] = node[length-2],right[length]=node[length-1];//定义子字节,用来存数组最后的两个节点 
    	parent.weight = left[length].weight + right[length].weight;//父节点的权重等于两个子节点的 权重
    	//储存两个子节点,因为parent.leftChild是指针类型,所以赋值的时候要加& 
    	parent.leftChild= &left[length];
    	parent.rightChild = &right[length]; 
    	//将数组最后两个子节点剔除,换成父节点,然后递归创建接下来的部分 
    	node[length-2] = parent;
    	creatHaffman(node,length-1); 
    }
    //计算字符的哈夫曼编码 ,第一个参数是哈夫曼树根节点,第二个参数储存编码的字符数组,第三个参数是字符数组的长度,从0开始 
    void coding(haffNode *node,char *keepCode,int length){
    	//如果节点没有子节点,就说明它是叶节点,将编码存在code数组里 
    	if(node->leftChild == NULL || node->rightChild == NULL){
    		keepCode[length] ='\0';//给编码一个终止符,形成一个完整的字符串,方便拷贝,以防拷贝到之前的编码。 
    		strcpy(code[node->data-0],keepCode);//调用strcpy函数拷贝字符串,其中code的下标用节点的字符(data)-0得到 
    		return; 
    	}
    	keepCode[length] = '0';
    	coding(node->leftChild,keepCode,length+1);
    	keepCode[length] = '1';
    	coding(node->rightChild,keepCode,length+1);
    } 
    //解压缩  
    haffNode* unzip(haffNode *node,int flag){
    	if(flag == 0)
    	return node->leftChild;
    	if(flag == 1)
    	return node->rightChild;
    } 
    int main(){
        int count[128]={0};//用来统计字符个数,一开始清零,其中它的下标号表示这个字符的ASCII码
        char keepCode[50];//用于在生成编码的时候 临时储存编码 ,真正储存编码的地方看代码最上面的code[][]数组 
        char reder;//用来存文件中的字符 
        int fileLength=0;//用来计算原文长度 
        int zipLength=0;//用来计算压缩文长度 
        int i; 
        int num=0;//用来计算出现的字符的个数 和其它一些计数功能 
        haffNode node[100];//用来储存哈夫曼节点,这里我申请100个空间事实上不需要那么大,大概需要26+26+20(26个英文字母大小写+标点符号) 
    	FILE *fpr = fopen("E:\\input.txt","r");//读入文件,其中input.txt的路径你要自己设置,可以自己建立一个文本,写一些英文进去 
    	FILE *fpw = fopen("E:\\output1","wb");//写入文件,wb是写入二进制文件,路径设置随意,但是要符合格式,写入的时候文件自动生成。
    	FILE *fpr1= fopen("E:\\output1","rb");;//用于解压缩时读入文件 ,rb是读入二进制文件 
    	FILE *fpw1 = fopen("E:\\output3.txt","w"); //用于解压缩时写入文件 
    	//解压需要用的 
    	char op;
    	haffNode *z;
    	//读取文件 
    	while((reder=fgetc(fpr))!=EOF){//一个一个地读入字符 
    		fileLength ++;//每读进一个字原文长度+1 
    		count[reder-0]++;//reder-0可以得到字符的ASCII码,然后累加统计 
    	} 
    	//循环数组,因为ASCII表中有255个字符,所以数组中有些字符是完全没有出现过的,我们要将出现过的存在charNode数组里。 
    	for(i=0; i<128; i++){
    		if(count[i]!=0){
    			node[num].data=i;//之前说过,下标就是出现的字符的ASCII码
    			node[num].weight=count[i];//count[i]存的就是字符出现的次数
    			num++;//计数加1 
    		}
    	}
    	//构建哈夫曼树
    	creatHaffman(node,num); 
    	//计算哈夫曼编码
    	coding(&node[0],keepCode,0); 
    	//根据哈夫曼编码把原来的文本压缩储存 
    	//读取文件 
    	num=0;//计数 
    	fseek(fpr,0L,0);//因为上面已经读过文件了,fpr指针已经向下移动,所以这边使用 fseek函数将指针复原到离0(文件起始位置)0L(第0个字节)处 
    	while((reder=fgetc(fpr))!=EOF){ //一个一个地读入字符 
    		for(i=0; i<strlen(code[reder-0]); i++){
    			saveChar |= code[reder-0][i]-'0';//让saveChar和编码中的每一位进行或操作,用字符的'1'-'0',就可得到0000 0001.     
    			num++;
    			if(num == 8){
    				fwrite(&saveChar,sizeof(char),1,fpw);//每8位写入一次文件
    				zipLength++; 
    				saveChar = 0;//重新置0 
    				num=0;
    			} 
    			else{
    				saveChar = saveChar << 1	; //每做完一步,向左移一位  
    			}
    		}
    	} 
    	//如果最后剩余的编码不到8位,将其移到最左端
    	if(num != 8){
    		saveChar = saveChar<<(8-num);//移到最左端 
    		fwrite(&saveChar,sizeof(char),1,fpw);
    		zipLength++;
    	} 
    	fclose(fpr);
    	fclose(fpw);
    	//根据哈夫曼编码解压缩,主要思想是根据编码遍历哈夫曼树 
    	num=0;//计算解压缩后的文件长度 
    	z = &node[0];
    	while(fread(&reder,sizeof(char),1,fpr1)){
    		//如果解压缩的长度等于原文长度,停止解压缩。为什么多这一个条件,因为在编码压缩的时候可能出现剩余的编码不足8位的情况,不足8位不成8位后,后面的补位可能造成干扰 
    		if(fileLength == num){
    			break;
    		} 
    		op = 128;//1000 0000
    		for(i=0; i< 8; i++){
    		slidChar = reder & op;
    		reder = reder << 1;
    		slidChar = slidChar >>7;
    		z = unzip(z,slidChar-0);
    		if(z->leftChild == NULL || z->rightChild == NULL){
    			fprintf(fpw1,"%c",z->data);
    			num++;//每写进一个字符+1 
    			z = &node[0];
    		}
    	}
    	}
    	fclose(fpr1);
    	fclose(fpw1);
    	//计算压缩率	
    	printf("原文件:%dK\n",fileLength/1024+1);
    	printf("压缩完成!请查看output1:%dK\n",zipLength/1024+1); 
    	printf("解压缩完成!请查看output3.txt:\%dK\n",fileLength/1024+1); 
    	printf("压缩率:%.2f%%\n",(float)(fileLength-zipLength)/fileLength*100);	
        return 0;
        } 
        




    展开全文
  • 哈夫曼压缩算法与解压

    千次阅读 2018-06-13 21:28:49
    算法思路如下:压缩:这个实验一开始将文件中的字符串读取到一个vector中,然后通过处理vector中的字符,建立了n个节点,每个节点包括每个字符和出现的频率,然后建立2*n个哈夫曼节点,前n个哈夫曼节点和节点的内容...

    算法思路如下:压缩:这个实验一开始将文件中的字符串读取到一个vector中,然后通过处理vector中的字符,建立了n个节点,每个节点包括每个字符和出现的频率,然后建立2*n个哈夫曼节点,前n个哈夫曼节点和节点的内容相同,后面的n个节点是用于构建哈夫曼树的非叶节点,然后构建哈夫曼树,把这些节点连接起来,生成哈夫曼树,生成哈夫曼编码时,从叶节点开始时逐步向根节点延申,获得哈夫曼编码,将编码输出到compression.txt中可以看到具体的哈夫曼编码,同时将编码输出到二进制文件compression_2.dat中,然后用一个map(string,char)来存储哈夫曼编码,string为编码,char为字符。

    解压:通过从compression_2.dat文件中读取01串,存到string中,与map中的键值进行比较,如果相等,就把map的值输出带decompression中,如果不相等,继续读取01字符。直到读取结束。

    代码如下:

    #include <iostream>
    #include <Windows.h>
    #include <fstream>
    #include <vector>
    #include<stdio.h>
    #include <algorithm>
    #include <cstring>
    #include <map> 
    #include <bitset>
    using namespace std;
    typedef struct
    {
    	int weight;
    	int parent, lchild, rchild;
    }HafuNode,*HufumanTree;
    typedef struct
    {
    	char *data;
    	int *num;
    	int length;
    }TNode;
    typedef struct
    {
    	char *data;
    	char** HM;
    }Code;
    typedef char** HuffmanCode;
    void initTnode(TNode &tnod)
    {
    	tnod.data = new char[256];
    	tnod.num = new int[256];
    	if (tnod.data == NULL || tnod.num==NULL)
    	{
    		cout << "发生错误" << endl;
    		exit(1);
    	}
    	tnod.length = 0;
    }
    void initmap(map<string, char>& hafuman, HuffmanCode code, int n,TNode node,int &codelength)
    {
    	for (int i = 1; i <= n; i++)
    	{
    		string s = code[i];
    		hafuman.insert(pair<string, char>(s, node.data[i - 1]));
    		codelength = s.size()*node.num[i - 1]+ codelength;
    	}
    
    		
    }
    void Read(vector<char>& s)
    {
    	char ch;
    	ifstream infile("test.txt", ios::in);
    	if (!infile)
    	{
    		cout << "open error" << endl;
    		exit(1);
    	}
    	while (infile.peek() != EOF)
    	{
    		 infile.get(ch);
    		 s.push_back(ch);
    	}
    	infile.close();
    }
    bool find(const char ch, TNode t)
    {
    	for (int i = 0; i < t.length; i++)
    	{
    		if (t.data[i] == ch)
    		{
    			return true;
    		}
    	}
    	return false;
    }
    void TNodeCount(TNode &t, vector<char> v)
    {
    	int m = v.size(),j=0;
    	char ch;
    	for (int i = 0; i < m; i++)
    	{
    		ch = v[i];
    		if (!find(ch, t))
    		{
    			t.data[j] = ch;
    			t.num[j] = count(v.begin(), v.end(), ch);
    			t.length++;
    			j++;
    		}
    	}
    }
    void Select(HufumanTree &tree, int a, int &b, int &c)
    {
    	int min1, min2, minweight = 10000;
    	for (int i = 1; i <= a; i++)
    	{
    		if (tree[i].parent == 0)
    		{
    			if (tree[i].weight < minweight)
    			{
    				minweight = tree[i].weight;
    				min1 = i;
    			}
    		}
    	}
    	tree[min1].parent = 1;
    	minweight = 10000;
    	for (int i = 1; i <= a; i++)
    	{
    		if (tree[i].parent == 0)
    		{
    			if (tree[i].weight < minweight)
    			{
    				minweight = tree[i].weight;
    				min2 = i;
    			}
    		}
    	}
    	tree[min2].parent = 1;
    	b = min1;
    	c = min2;
    }
    void CreateHuffmanTree(HufumanTree &tree, TNode node, int n)
    {
    	if (n <= 1)
    	{
    		return;
    	}
    	int m = 2 * n - 1;
    	tree = new HafuNode[m+1];
    	for (int i = 1; i <= m; i++)//为0表示没有左右节点,父节点
    	{
    		tree[i].lchild = 0;
    		tree[i].parent = 0;
    		tree[i].rchild = 0;
    	}
    	for (int i = 1; i <= n; i++)
    	{
    		tree[i].weight = node.num[i - 1];
    	}
    	int s1, s2;
    	for (int i = n + 1; i <= m; i++)
    	{
    		Select(tree, i - 1, s1, s2);
    		tree[s1].parent = i;
    		tree[s2].parent = i;
    		tree[i].lchild = s1;
    		tree[i].rchild = s2;
    		tree[i].weight = tree[s1].weight + tree[s2].weight;
    	}
    }
    void CreatHuffmanCode(HufumanTree tree, HuffmanCode &code, int n)
    {
    	int pare, child, start;
    	code = new char *[n + 1];
    	char* cd = new char[n];
    	cd[n - 1] = '\0';
    	for (int i = 1; i <= n; i++)
    	{
    		start = n - 1;
    		child = i;
    		pare = tree[i].parent;
    		while (pare != 0)
    		{
    			start--;
    			if (child == tree[pare].lchild)
    			{
    				cd[start] = '0';
    			}
    			else
    			{
    				cd[start] = '1';
    			}
    			child = pare;
    			pare = tree[child].parent;
    		}
    		code[i] = new char[n - start];
    		strcpy(code[i], &cd[start]);
    	}
    	delete cd ;
    }
    void compression(HuffmanCode code,vector<char> v, TNode node)
    {
    	int i, j, k;
    	ofstream outfile("compression.txt", ios::out);
    	if (!outfile)
    	{
    		cerr << "open error" << endl;
    		exit(1);
    	}
    	for ( i = 0; i < v.size(); i++)
    	{
    		for ( j = 0; j < node.length; j++)
    		{
    			if(node.data[j] == v[i])
    			{
    				break;
    			}
    		}
    		for (k = 0; code[j+1][k] != '\0'; k++)
    		{
    			outfile << code[j+1][k];
    		}
    	}
    	outfile.close();
    	cout << "压缩成功!,可以到compression.txt中查看" << endl;
    	Sleep(500);
    }
    void decompression(map<string, char> hafuman,int length)
    {
    	char a[30];
    	char ch;
    	ofstream outfile("decompression.txt", ios::out);
    	ifstream infile("compression_2.dat", ios::binary);
    	if (!outfile)
    	{
    		cerr << "open error" << endl;
    		exit(1);
    	}
    	if (!infile)
    	{
    		cerr << "open error" << endl;
    		exit(1);
    	}
    	char m = 0;
    	int point = 7;
    	string s = "";
    	while (length >=0)
    	{
    		if (point == 7)
    		{
    			infile.read((char *)&m, sizeof(char));
    			length -= 8;
    		}
    
    		char ch = m;
    
    		ch &= 1 << point;
    		if (ch == 0)
    			s += '0';
    		else
    			s += '1';
    		point--;
    		if (point < 0)
    			point = 7;
    		while (hafuman.count(s) == 0)
    		{
    			if (point == 7)
    			{
    				infile.read((char *)&m, sizeof(char));
    				length -= 8;
    			}
    			char ch = m;
    
    			ch &= 1 << point;
    			if (ch == 0)
    				s += '0';
    			else
    				s += '1';
    			point--;
    			if (point < 0)
    				point = 7;
    		}
    		char t = hafuman[s];
    		outfile << t;
    		s = "";
    	}
    	cout << "解压成功!可以再decompression.txt文件中查看" << endl;
    }
    void compression_2(HuffmanCode code, vector<char> v, TNode node)
    {
    	int i, j, k;
    	ifstream infile("compression.txt", ios::in);
    	ofstream outfile("compression_2.dat", ios::binary);
    	if (!outfile)
    	{
    		cerr << "open error" << endl;
    		exit(1);
    	}
    	if (!infile)
    	{
    		cerr << "open error" << endl;
    		exit(1);
    	}
    	char a=0;
    	int point = 0;
    	for (i = 0; i < v.size(); i++)
    	{
    		for (j = 0; j < node.length; j++)
    		{
    			if (node.data[j] == v[i])
    			{
    				break;
    			}
    		}
    		
    		for (k = 0; code[j + 1][k] != '\0'; k++)
    		{
    			if (code[j + 1][k] == '0')
    				a &= ~(1 << (7-point));
    			if (code[j + 1][k] == '1')
    				a |= (1 << (7 - point));
    			point++;
    			if (point == 8)
    			{
    				outfile.write((char*)&a, sizeof(char));
    				point = 0;
    				a = 0;
    			}
    				
    		}
    	}
    	if(point!=0)
    		outfile.write((char*)&a, sizeof(char));
    	outfile.close();
    	cout << "压缩二进制文件成功!,可以到compression_2.dat中查看" << endl;
    	Sleep(500);
    }
    int main()
    {
    	vector<char> str;
    	fstream f;
    	TNode tnode;
    	initTnode(tnode);
    	int number,n;
    	HufumanTree hafutree;
    	HuffmanCode hafuCode;
    	int codelength=0;
    	map<string, char> hafuman;
    	while (1)
    	{
    		cout << "请输入选择的功能" << endl;
    		cout << "1.压缩文件(文件名为test.txt,压缩后的文件名为compression_2.dat),编码的文件名为compression.txt中" << endl;
    		cout << "2.解压文件(文件名为compression.txt),解压后的文件名为decompression.txt" << endl;
    		cin >> number;
    		switch (number)
    		{
    			case 1:
    				Read(str);
    				TNodeCount(tnode, str);
    				n = tnode.length;
    				CreateHuffmanTree(hafutree, tnode, n);
    				CreatHuffmanCode(hafutree, hafuCode, n);
    				compression(hafuCode, str, tnode);
    				compression_2(hafuCode, str, tnode);
    				initmap(hafuman, hafuCode,n,tnode,codelength);
    				system("pause");
    				break;
    			case 2:
    				decompression(hafuman,codelength);
    				system("pause");
    				break;
    		default:
    			cout << "输入错误!请重新输入";
    			system("pause");
    			break;
    		}
    
    	}
    	return 0;
    }
    



    展开全文
  • 哈夫曼树(HuffManTree)是用来压缩数据的一种数据结构,它适合压缩数据重复率较高的情况。 文本A:123456789,这串文本重复率为0,因为每个字符都是唯一的,没有重复率而言; 文本B:111222334,这串文本重复率明显...

    哈夫曼编码

    介绍

    哈夫曼树(HuffManTree)是用来压缩数据的一种数据结构,它适合压缩数据重复率较高的情况。

    文本A:123456789,这串文本重复率为0,因为每个字符都是唯一的,没有重复率而言;
    文本B:111222334,这串文本重复率明显较A高,适合用哈夫曼树压缩。

    问题与分析

    现在想把“aaaabbbccdeefffgggg”这个字符串保存到硬盘上,如果直接保存,它会占用多大空间?

    回顾一下,每个英文字母都可以用一个ASCII码表示,例如 a=97,b=98,……
    而每个ASCII码是 1 byte,所以上面的字符串一共占用 19 byte = 152 bit。

    我们站在计算机的角度再来分析一下,对于计算机而言,万物皆为0/1,人类理解的abc,在计算机里就是一串0/1
    “aaaabbbccdeefffgggg”在计算机里存储的内容就是

    a a a a b b ……

    01100001 01100001 01100001 01100001 01100010 01100010 ……

    可以发现,对于重复的字符,计算机存储了大量重复的二进制码

    所以我们可不可以换种方式,不再直接用ASCII编码的方式,而是根据各字符出现的频率编码,让出现频率高的字符编码短一点,出现频率低的字符编码长一点,这样就可以避免所有字符都是8 bit,从而减少存储空间的消耗。

    原理

    哈夫曼树正是以上述方式实现的一种解决方式,具体过程如下

    1. 统计各字符出现的频率

      a = 4
      b = 3
      c = 2
      d = 1
      e = 2
      f = 3
      g = 4

    2. ① 按照频率降序排列;
      ② 取出最后面的两个(不放回),创建一个新节点,将二者保存,再将新节点放回原序列;
      重复①②,直到只剩一个节点。(每次拿走两个,新增一个,最终一定会只剩一个)

      注意,已经取走的节点不再参与排序,即只排序最顶端的节点

      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    3. 从任意节点出发,向左走为0,向右走为1,遍历整棵树,得出各字符对应的0/1序列
      在这里插入图片描述

    4. 按照各个字符对应的新二进制编码,保存文件

      a a a a b b ……
      11 11 11 11 001 001 ……

      相比较直接保存,节省了许多空间,当数据量很大时,压缩效果越加明显。

    展开全文
  • 转-哈夫曼压缩算法

    2017-08-11 18:17:05
    我们直接来看示例,如果我们需要来压缩下面的字符串:  “beep boop beer!”  首先,我们先计算出每个字符出现的次数,我们得到下面这样一张表 : 然后,我把把这些东西放到Priority Queue中(用出现的次...
  • 利用哈夫曼算法进行文件的压缩和解压缩。 利用命令行对指定的文件进行压缩和解压缩。 能对一般的文本文件有较好的压缩能力,对其它格式文件可以进行压缩但不一定能有压缩效果。对于用此程序压缩的文件可以用此程序...
  • } } /*压缩函数 INPUT:打开源文件 OUTPUT:打开压缩文件 inByte:临时存储的读入字节 outByte:临时存储的写入字节 storage:等待被写入的信息 f:判断是否进行了压缩 大致流程为:统计频率、建立Huffman树、对...
  • 对应算法步骤1--------- */ for (i = *n; i ; i++) //创建非叶子结点,建哈夫曼树 { //在ht[0]~ht[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回 SelectMinTree(ht, i - 1, &...
  • } 实验步骤: 运行选项4进入使用说明 原理: 哈夫曼编码的思想对文件进行压缩,主要原理是通过哈夫曼编码来重新表示字符,使得出现频率高的字符编码短,出现少的字符编码长。 压缩过程: 1)统计字符种类及频度:...
  • NULL 博文链接:https://smallsmile.iteye.com/blog/777934
  • 使用哈夫曼算法实现的文件压缩(源代码+实现报告)
  • 了解huffman算法实现的步骤及过程,并附有具体的案例以及答案了解huffman算法实现的步骤及过程,并附有具体的案例以及答案,了解huffman算法实现的步骤及过程,并附有具体的案例以及答案了解huffman算法实现的步骤及...
  •  哈弗曼编码几乎是所有压缩算法的基础,其实这个算法并不复杂,简单的理解就是,如何用更短的bit来编码数据。  我们知道普通的编码都是定长的,比如常用的ASCII编码,每个字符都是8个bit: 字符 编码 ...
  • 想在linux使用哈夫曼压缩算法对图片文件进行压缩,解压!
  • 哈夫曼算法压缩文件

    千次阅读 2016-03-12 15:22:31
    今天上午上了哈夫曼算法压缩的课,我学习到了用哈夫曼算法压缩文件,可以将一个文件压缩百分之六十左右的大小。 具体原理是:文件是由一个个字节组成,而字节有自己的ASCII码值,然后用一个...哈夫曼压缩需要三个容
  • 哈夫曼压缩.zip

    2019-06-02 13:34:12
    哈夫曼压缩算法,数据结构实习,vs版本编写,
  • java哈夫曼压缩

    2013-11-27 01:06:38
    java实现的哈夫曼压缩算法,有swing界面。
  • C语言实现的huffman压缩解压缩算法
  • 哈夫曼压缩实现

    2013-11-05 23:40:41
    哈夫曼压缩算法的c++实现,你可以学习到你想学的 这也是一个经典的算法设计题
  • 哈夫曼编码压缩算法

    千次阅读 2015-04-27 21:48:11
    相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huffman二叉树 —— 一种带权重的树。
  • 这是我做的一个基于哈夫曼树思想的压缩算法程序源码,希望大家指正
  • python哈夫曼压缩与解压算法 压缩 #encoding: utf-8 from bitarray import bitarray import random import json class Node(object): """docstring for Node""" left=None right=None times=0 char = '' ...
  • 哈夫曼压缩与解压算法(可以直接运行),压缩成二进制文件,而且生成了txt文件可以查看哈夫曼编码。C++代码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 932
精华内容 372
关键字:

哈夫曼压缩算法