A. Huffman编码不适合图像压缩么,为什么。有相关的资料么。能给我看看不QQ504278770
下面是我从网上搜索到的资料,希望对你有帮助。
1.哈夫曼图像压缩算法引言
随着网络与多媒体技术的兴起,人们需要存储和传输的数据越来越多,数据量越来越大,以前带宽有限的传输网络和容量有限的存储介质难以满足用户的需求。
特别是声音、图像和视频等媒体在人们的日常生活和工作中的地位日益突出,这个问题越发显得严重和迫切。如今,数据压缩技术早已是多媒体领域中的关键技术之一。
Huffman(哈夫曼)算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明Huffman算法在无损压缩算法中是最优的。Huffman原理简单,实现起来也不困难,在现在的主流压缩软件得到了广泛的应用。对应用程序、重要资料等绝对不允许信息丢失的压缩场合,Huffman算法是非常好的选择。
2.哈夫曼图像压缩算法原理
Huffman编码是1952年由Huffman提出的对统计独立信源能达到最小平均码长的编码方法。这一年,他发表了着名论文“A Method for the Construction of Minimum Rendancy Codes”,即最短冗余码的构造方法.之后,Huffman编码及其一些改进方法一直是数据压缩领域的研究热点之一。
Huffman码是一种变长码,其基本思想是:先统计图像(已经数字化)中各灰度出现的概率,出现概率较大的赋以较短的码字,而出现概率较小的则赋以较长的码字。我们可以用下面的框图来表示Huffman编码的过程:
在整个编码过程中,统计图像各灰度级出现的概率和编码这两步都很简单,关键的是Huffman树的构造。不但编码的时候需要用到这颗树,解码的时候也必须有这颗树才能完成解码工作,因此,Huffman树还得完整的传输到解码端。
Huffman树的构造可以按照下面图2的流程图来完成。首先对统计出来的概率从小到大进行排序,然后将最小的两个概率相加;到这儿的时候,先把已经加过的两个概率作为树的两个节点,并把他们从概率队列中删除;然后把相加所得的新概率加入到队列中,对这个新队列进行排序。
如此反复,直到最后两个概率相加为1的时候停止。这样,Huffman树就建立起来了。
3. 哈夫曼图像压缩算法软件实现
这儿,我们以Turbo C为例来说明软件实现Huffman图像压缩算法的一些关键技术。
为了叙述方便,我们不妨假设处理的图像的灰度级变化范围从0到255,即具有256个灰度级。我们先来统计输入图像的概率,实际上是要统计各个灰度级在整幅图像中出现的次数。为此,我们先定义一个具有256个元素的数组。
然后对输入图像信号进行扫描,每出现一个灰度,就把它存入实现定义好的一个数组中的相应元素中(让这个元素的值自增1)。最后,通过读取数组中各元素的值就可以求出各个灰度出现的频数。
接下来就该构造Huffman树了。为了构造Huffman树,我们要用到C语言中链表的概念。我们必须用一个结构体来表示Huffman树的节点。对于每个节点而言我们需要这样几个信息:本节点的权重(就是灰度的频数)、指向父节点的指针和分别指向左右子叶节点的指针。于是,我们可以定义这样一个结构体:
Struct Node{
Floatweight;
Node * father;
Node * left;
Node * right;}Huffman_Node
我们需要先确定权最低的两个自由结点,这将是最初的left和right节点。然后建立这两个结点的父结点,并让它的权等于这两个结点的权之和。
接着将这个父结点增加到自由结点的序列中,而两个子结点则从序列中去掉。重复前面的步骤直到只剩下一个自由结点,这个自由结点就是Huffman树的根。
Huffman编码树作为一个二叉树从叶结点逐步向上建立。Huffman树建立好以后,为了把权、概率等数值转化码字,我们还得对整个Huffman树进行扫描。请注意,在建立Huffman树的时候,我们是从树叶开始的,而在对Huffman树分配码字的时候却刚好相反,是从树根开始,沿着各个树枝的走向“顺藤摸瓜”似的对各个系数进行编码。
对于一个节点的两个子节点(left和right),其中一个节点对应的位为0,而另一个结点则人为地设置成为l。解码的时候也是完全相同的一颗Huffman树完成的。下面的循环是实现压缩的关键语句之一[ 1 ]。
for (i = length-1; i >= 0; ――i) {
if ((current_code >> i) & 1)
thebyte |= (char) (1 << curbit);
if (--curbit < 0) {
putc (thebyte, ofile);
thebyte = 0;
curbyte++;
curbit = 7;
}
}
注意:这几行代码执行了数据压缩的功能,但是还没有生成编码和解码所需要的代码表。
4.哈夫曼图像压缩算法性能评价
我们主要从三方面[ 2 ]来评价Huffman的性能:
(1)压缩比的大小;
(2)恢复效果的好坏,也就是能否尽可能的恢复原始数据;
(3)算法的简单易用性以及编、解码的速度。
首先分析一下对压缩比的影响因素(不同的着作中对压缩比的定义不尽相同,这儿我们采用如下定义:压缩比等于压缩之前的以比特计算的数据量比上压缩之后的数据量)。对于Huffman编码来说,我们因为要用额外的位保存和传输Huffman树而“浪费”掉一些存储位,也就是说,为了编、解码的方便,我们把本已减少的数据量又增加了一些。
如果文件比较大的话,这一点多余的数据根本算不了什么,所占比例很小。但是,如果压缩的文件本来就很小的话,那么这笔数据就很可观了。一般来说,经典的Huffman算法的压缩比不是很高,这是无损压缩的“通病”。
第二点就不用说了,由于它是无损压缩,能够完全恢复压缩之前图像的本来面貌。
最后,让我们来分析一下Huffman压缩方法的速度问题。大家在第三节中已经看到了,在压缩的过程中,我们进行了两次扫描,第一次是为了统计各个灰度出现的频数而扫描整幅图像,第二次则是为了分配码字而扫描整个Huffman树。
这样一来,对较大的文件进行编码时,频繁的磁盘读写访问必然会降低数据编码的速度,如果用于网络的话,还会因此带来一些延时,不利于实时压缩和传输。另外,Huffman算法的编码和解码的速度是不对称的,解码快于编码,因为解码不需要生成Huffman树的环节。
5.图像压缩算法结束语
Huffman算法目前已经得到了广泛的应用,软件和硬件都已经实现。基于Huffman经典算法的缺陷,不少人提出了一些自适应算法。前面的算法中,Huffman树是整个图像全部输入扫描完成后构造出来的,而自适应算法(或称动态算法)则不必等到全部图像输入完成才开始树的构造,并且可以根据后面输入的数据动态的对Huffman树进行调整。实际上,实用的Huffman树都是经过某种优化后的动态算法。
网络资源
B. 有人能给我一份哈夫曼编码的压缩和解压么
把要压缩或要解压的文件拖拽到窗口中即可。另存为编辑框是压缩或解压的输出路径。对于压缩来说,另存为路径是目标文件的路径加上一个.shc扩展名。对于解压来说,会去掉最后一个扩展名。
压缩的核心其实就是用了哈夫曼编码原理。我封装了一个哈夫曼编码类,内部使用了一个哈夫曼树类。
要对一个文件进行压缩,执行如下步骤:
1.建立编码方案。第一遍扫描文件,统计这个文件中各种不同的字节出现的次数(256种),以这个次数作为权值,建立对应的哈夫曼树。然后取得每个不同字节对应的01编码序列。
C. 对图像进行霍夫曼编码压缩后如何输出压缩后图像
压缩后的图像就是哈夫曼编码后的01比特流
D. 如何用哈夫曼编码实现英文文本的压缩和解压缩
哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。有人用C函数写了这个编码,见下面链接
http://ke..com/view/189694.htm
E. 基于哈夫曼编码的图像压缩编码程序设计 计算出压缩比对编码后的数据进行解压,并显示解压后的图像;
我空间有篇大学时候写的Huffman算法,C++的,可以编译运行的,不过是控制台的
Huffman本身不适合压缩图片,视频之类,只有对文本压缩效果比较好。
F. 哈夫曼编码进行图像压缩
% 演示图象的哈夫曼编解码过程
% chenyong 2009.04.20
clear all;
close all;
clc;
Dimens = 256; % 矩阵维数,假设矩阵为方阵即256*256
src_size = Dimens^2; % 矩阵元素的个数
gray_level = 9; % 灰度级
src = randn(Dimens); %产生模拟图像矩阵,满足正态分布,零均值,方差为1
%src = randint(Dimens,Dimens,gray_level); % 产生随机图像矩阵,灰度值为0~63,满足均匀分布
src_one = reshape(src,1,src_size);
src_max = max(src_one);
src_min = min(src_one);
quan = linspace(src_min,src_max,gray_level); % 产生均匀量化区间
src_d = []; % 数字矩阵
for row = 1:Dimens % 逐点量化
for vol = 1:Dimens
diff = abs(src(row,vol)-quan);
[min_diff,min_index] = min(diff);
quan_gray = min_index -1;
src_d(row,vol) = quan_gray;
end
end
%将数字图像矩阵还原成模拟矩阵
src_a = [];
quan_space = quan(2)-quan(1);
for row = 1:Dimens
for vol = 1:Dimens
src_a(row,vol) = src_d(row,vol) * quan_space + src_min;
end
end
% prob数组保存图像中各灰度出现的概率
prob = [];
for src_value=0:(gray_level-1)
index = find(src_d==src_value);
i = src_value + 1;
prob(i) = length(index)/src_size;
end
% 画出直方图
% stem(0:gray_level-1,prob);
% xlabel('灰度值');
% ylabel('概率');
% title('灰度直方图');
% huffman编码
p = prob;
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
[q,l]=sort(q);
m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
q=[q(1)+q(2),q(3:n),1];
end
bre=zeros(n-1,n);
bre(n-1,1)=0+j; %虚部表示当前的二进制数的位数,以下类似
bre(n-1,2)=1+j;
for time=1:n-2
loc_1 = find(real(m(n-time,:))==1);
prebit = bre(n-time,loc_1);
bre(n-time-1,1) = (real(prebit)*2 + 0) + j*(imag(prebit)+1);
bre(n-time-1,2) = (real(prebit)*2 + 1) + j*(imag(prebit)+1);
loc_not1 = find(real(m(n-time,:))>1);
bre(n-time-1,3:3+time-1) = bre(n-time,loc_not1);
end
[m1,index] = sort(m(1,:));
code = bre(1,index);
code_data = real(code);
code_bits = imag(code);
disp(['gray level',' ', 'huffman code']);
for i = 1:length(code)
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i)))]);
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i),code_bits(i)))]);
end
code_binary = dec2bin(code_data);
%逐点编码
out = [];
for row = 1:Dimens
for vol = 1:Dimens
now_gray = src_d(row,vol);
now_code = code_binary(now_gray+1,:);
now_bits = code_bits(now_gray+1);
now_code = now_code(end-now_bits+1:end);
out = [out, now_code];
end
end
%计算压缩比
real_bitnum = length(out);
bitnum_no_huffman = src_size*nextpow2(gray_level);
comp_ratio =bitnum_no_huffman/real_bitnum;
Lavg = real_bitnum/src_size;
Hshannon = (-1)*prob*(log2(prob))';
disp(['Lavg = ',num2str(Lavg)]);
disp(['normal bit num = ',num2str(nextpow2(gray_level))]);
disp(['comp_ratio = ',num2str(comp_ratio)]);
disp(['Hshannon = ',num2str(Hshannon)]);
G. 有关哈夫曼编码压缩与解压缩的问题.
压缩代码非常简单,首先用ASCII值初始化511个哈夫曼节点:
CHuffmanNode nodes[511];
for(int nCount = 0; nCount < 256; nCount++)
nodes[nCount].byAscii = nCount;
然后,计算在输入缓冲区数据中,每个ASCII码出现的频率:
for(nCount = 0; nCount < nSrcLen; nCount++)
nodes[pSrc[nCount]].nFrequency++;
然后,根据频率进行排序:
qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);
现在,构造哈夫曼树,获取每个ASCII码对应的位序列:
int nNodeCount = GetHuffmanTree(nodes);
构造哈夫曼树非常简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。这样,新节点就是两个被替换节点的父节点了。如此循环,直到队列中只剩一个节点(树根)。
// parent node
pNode = &nodes[nParentNode++];
// pop first child
pNode->pLeft = PopNode(pNodes, nBackNode--, false);
// pop second child
pNode->pRight = PopNode(pNodes, nBackNode--, true);
// adjust parent of the two poped nodes
pNode->pLeft->pParent = pNode->pRight->pParent = pNode;
// adjust parent frequency
pNode->nFrequency = pNode->pLeft->nFrequency + pNode->pRight->nFrequency;
这里我用了一个好的诀窍来避免使用任何队列组件。我先前就直到ASCII码只有256个,但我分配了511个(CHuffmanNode nodes[511]),前255个记录ASCII码,而用后255个记录哈夫曼树中的父节点。并且在构造树的时候只使用一个指针数组(ChuffmanNode *pNodes[256])来指向这些节点。同样使用两个变量来操作队列索引(int nParentNode = nNodeCount;nBackNode = nNodeCount –1)。
接着,压缩的最后一步是将每个ASCII编码写入输出缓冲区中:
int nDesIndex = 0;
// loop to write codes
for(nCount = 0; nCount < nSrcLen; nCount++)
{
*(DWORD*)(pDesPtr+(nDesIndex>>3)) |=
nodes[pSrc[nCount]].dwCode << (nDesIndex&7);
nDesIndex += nodes[pSrc[nCount]].nCodeLength;
}
(nDesIndex>>3): >>3 以8位为界限右移后到达右边字节的前面
(nDesIndex&7): &7 得到最高位.
注意:在压缩缓冲区中,我们必须保存哈夫曼树的节点以及位序列,这样我们才能在解压缩时重新构造哈夫曼树(只需保存ASCII值和对应的位序列)。
解压缩
解压缩比构造哈夫曼树要简单的多,将输入缓冲区中的每个编码用对应的ASCII码逐个替换就可以了。只要记住,这里的输入缓冲区是一个包含每个ASCII值的编码的位流。因此,为了用ASCII值替换编码,我们必须用位流搜索哈夫曼树,直到发现一个叶节点,然后将它的ASCII值添加到输出缓冲区中:
int nDesIndex = 0;
DWORD nCode;
while(nDesIndex < nDesLen)
{
nCode = (*(DWORD*)(pSrc+(nSrcIndex>>3)))>>(nSrcIndex&7);
pNode = pRoot;
while(pNode->pLeft)
{
pNode = (nCode&1) ? pNode->pRight : pNode->pLeft;
nCode >>= 1;
nSrcIndex++;
}
pDes[nDesIndex++] = pNode->byAscii;
}
过程
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#define M 10
typedef struct Fano_Node
{
char ch;
float weight;
}FanoNode[M];
typedef struct node
{
int start;
int end;
struct node *next;
}LinkQueueNode;
typedef struct
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
void EnterQueue(LinkQueue *q,int s,int e)
{
LinkQueueNode *NewNode;
NewNode=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(NewNode!=NULL)
{
NewNode->start=s;
NewNode->end=e;
NewNode->next=NULL;
q->rear->next=NewNode;
q->rear=NewNode;
}
else printf("Error!");
}
//***按权分组***//
void Divide(FanoNode f,int s,int *m,int e)
{
int i;
float sum,sum1;
sum=0;
for(i=s;i<=e;i++)
sum+=f.weight;
*m=s;
sum1=0;
for(i=s;i<e;i++)
{
sum1+=f.weight;
*m=fabs(sum-2*sum1)>fabs(sum-2*sum1-2*f.weight)?(i+1):*m;
if(*m==i)
break;
}
}
main()
{
int i,j,n,max,m,h[M];
int sta,mid,end;
float w;
char c,fc[M][M];
FanoNode FN;
LinkQueueNode *p;
LinkQueue *Q;
//***初始化队Q***//
Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
Q->rear=Q->front;
Q->front->next=NULL;
printf("\t***FanoCoding***\n");
printf("Please input the number of node:"); /*输入信息*/
scanf("%d",&n);
i=1;
while(i<=n)
{
printf("%d weight and node:",i);
scanf("%f %c",&FN.weight,&FN.ch);
for(j=1;j<i;j++)
{
if(FN.ch==FN[j].ch)
{
printf("Same node!!!\n");
break;
}
}
if(i==j)
i++;
}
for(i=1;i<=n;i++) /*排序*/
{
max=i+1;
for(j=max;j<=n;j++)
max=FN[max].weight<FN[j].weight?j:max;
if(FN.weight<FN[max].weight)
{
w=FN.weight;
FN.weight=FN[max].weight;
FN[max].weight=w;
c=FN.ch;
FN.ch=FN[max].ch;
FN[max].ch=c;
}
}
for(i=1;i<=n;i++) /*初始化h*/
h=0;
EnterQueue(Q,1,n); /*1和n进队*/
while(Q->front->next!=NULL)
{
p=Q->front->next; /*出队*/
Q->front->next=p->next;
if(p==Q->rear)
Q->rear=Q->front;
sta=p->start;
end=p->end;
free(p);
Divide(FN,sta,&m,end); /*按权分组*/
for(i=sta;i<=m;i++)
{
fc[h]='0';
h++;
}
if(sta!=m)
EnterQueue(Q,sta,m);
else
fc[sta][h[sta]]='\0';
for(i=m+1;i<=end;i++)
{
fc[h]='1';
h++;
}
if(m==sta&&(m+1)==end) //如果分组后首元素的下标与中间元素的相等,
{ //并且和最后元素的下标相差为1,则编码码字字符串结束
fc[m][h[m]]='\0';
fc[end][h[end]]='\0';
}
else
EnterQueue(Q,m+1,end);
}
for(i=1;i<=n;i++) /*打印编码信息*/
{
printf("%c:",FN.ch);
printf("%s\n",fc);
}
system("pause");
}
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define N 100
#define M 2*N-1
typedef char * HuffmanCode[2*M];
typedef struct
{
char weight;
int parent;
int LChild;
int RChild;
}HTNode,Huffman[M+1];
typedef struct Node
{
int weight; /*叶子结点的权值*/
char c; /*叶子结点*/
int num; /*叶子结点的二进制码的长度*/
}WNode,WeightNode[N];
/***产生叶子结点的字符和权值***/
void CreateWeight(char ch[],int *s,WeightNode *CW,int *p)
{
int i,j,k;
int tag;
*p=0;
for(i=0;ch!='\0';i++)
{
tag=1;
for(j=0;j<i;j++)
if(ch[j]==ch)
{
tag=0;
break;
}
if(tag)
{
(*CW)[++*p].c=ch;
(*CW)[*p].weight=1;
for(k=i+1;ch[k]!='\0';k++)
if(ch==ch[k])
(*CW)[*p].weight++;
}
}
*s=i;
}
/********创建HuffmanTree********/
void CreateHuffmanTree(Huffman *ht,WeightNode w,int n)
{
int i,j;
int s1,s2;
for(i=1;i<=n;i++)
{
(*ht).weight =w.weight;
(*ht).parent=0;
(*ht).LChild=0;
(*ht).RChild=0;
}
for(i=n+1;i<=2*n-1;i++)
{
(*ht).weight=0;
(*ht).parent=0;
(*ht).LChild=0;
(*ht).parent=0;
}
for(i=n+1;i<=2*n-1;i++)
{
for(j=1;j<=i-1;j++)
if(!(*ht)[j].parent)
break;
s1=j; /*找到第一个双亲不为零的结点*/
for(;j<=i-1;j++)
if(!(*ht)[j].parent)
s1=(*ht)[s1].weight>(*ht)[j].weight?j:s1;
(*ht)[s1].parent=i;
(*ht).LChild=s1;
for(j=1;j<=i-1;j++)
if(!(*ht)[j].parent)
break;
s2=j; /*找到第一个双亲不为零的结点*/
for(;j<=i-1;j++)
if(!(*ht)[j].parent)
s2=(*ht)[s2].weight>(*ht)[j].weight?j:s2;
(*ht)[s2].parent=i;
(*ht).RChild=s2;
(*ht).weight=(*ht)[s1].weight+(*ht)[s2].weight;
}
}
/***********叶子结点的编码***********/
void CrtHuffmanNodeCode(Huffman ht,char ch[],HuffmanCode *h,WeightNode *weight,int m,int n)
{
int i,j,k,c,p,start;
char *cd;
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
c=i;
p=ht.parent;
while(p)
{
start--;
if(ht[p].LChild==c)
cd[start]='0';
else
cd[start]='1';
c=p;
p=ht[p].parent;
}
(*weight).num=n-start;
(*h)=(char *)malloc((n-start)*sizeof(char));
p=-1;
strcpy((*h),&cd[start]);
}
system("pause");
}
/*********所有字符的编码*********/
void CrtHuffmanCode(char ch[],HuffmanCode h,HuffmanCode *hc,WeightNode weight,int n,int m)
{
int i,j,k;
for(i=0;i<m;i++)
{
for(k=1;k<=n;k++) /*从(*weight)[k].c中查找与ch相等的下标K*/
if(ch==weight[k].c)
break;
(*hc)=(char *)malloc((weight[k].num+1)*sizeof(char));
for(j=0;j<=weight[k].num;j++)
(*hc)[j]=h[k][j];
}
}
/*****解码*****/
void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)
{
int i=0,j,p;
printf("***StringInformation***\n");
while(i<m)
{
p=2*n-1;
for(j=0;hc[j]!='\0';j++)
{
if(hc[j]=='0')
p=ht[p].LChild;
else
p=ht[p].RChild;
}
printf("%c",w[p].c); /*打印原信息*/
i++;
}
}
main()
{
int i,n,m,s1,s2,j; /*n为叶子结点的个数*/
char ch[N],w[N]; /*ch[N]存放输入的字符串*/
Huffman ht; /*二叉数 */
HuffmanCode h,hc; /* h存放叶子结点的编码,hc 存放所有结点的编码*/
WeightNode weight; /*存放叶子结点的信息*/
printf("\t***HuffmanCoding***\n");
printf("please input information :");
gets(ch); /*输入字符串*/
CreateWeight(ch,&m,&weight,&n); /*产生叶子结点信息,m为字符串ch[]的长度*/
printf("***WeightInformation***\n Node "); /*输出叶子结点的字符与权值*/
for(i=1;i<=n;i++)
printf("%c ",weight.c);
printf("\nWeight ");
for(i=1;i<=n;i++)
printf("%d ",weight.weight);
CreateHuffmanTree(&ht,weight,n); /*产生Huffman树*/
printf("\n***HuffamnTreeInformation***\n");
for(i=1;i<=2*n-1;i++) /*打印Huffman树的信息*/
printf("\t%d %d %d %d\n",i,ht.weight,ht.parent,ht.LChild,ht.RChild);
CrtHuffmanNodeCode(ht,ch,&h,&weight,m,n); /*叶子结点的编码*/
printf(" ***NodeCode***\n"); /*打印叶子结点的编码*/
for(i=1;i<=n;i++)
{
printf("\t%c:",weight.c);
printf("%s\n",h);
}
CrtHuffmanCode(ch,h,&hc,weight,n,m); /*所有字符的编码*/
printf("***StringCode***\n"); /*打印字符串的编码*/
for(i=0;i<m;i++)
printf("%s",hc);
system("pause");
TrsHuffmanTree(ht,weight,hc,n,m); /*解码*/
system("pause");
}
H. 哈夫曼编码法的压缩和解压缩怎么实现
建立一棵赫夫曼树,设每个父节点的左子节点为1,右子节点为0,然后由根节点到所要编码的字符的叶节点的路径确定字符的编码。比如要编码a,假设a在第三层,则由根节点到a的路径为:根节点——右子节点(0)——左子节点(1)。那么a的编码就为01。就这样把所有字符进行编码,建立一个赫夫曼编码表。利用这个编码表把字符串编码就是压缩了,解压缩就是把参照赫夫曼编码表把编码转为字符串。
I. 跪求哈夫曼编码压缩与其它压缩算法的比较(复杂性和压缩效果)
(1)所形成的Huffman编码的码字是不是唯一的,但是可以被指定为唯一的编码效率为“1”大,小的是“0”时,两个最小概率符号赋值。反之也可以。如果两个符号的发生的概率是相等的,排列无论前面是可能的,所以霍夫曼码字的结构不是唯一的,对于相同的信息源,不管如何在上述的顺序安排的,它的平均码字长度是不改变,因此,编码效率是独一无二的。
(2)只有当不均匀时,每个符号的信息源的发生的概率,霍夫曼编码的效果是唯一明显的。
(3)霍夫曼编码必须是精确的原始文件中的各符号的发生频率的统计数据,并且如果没有准确的统计数据,压缩将低于预期。 Huffman编码通常必须经过两道,第一遍统计的第二次产生编码,编码速度是比较慢的。电路的复杂性的另一种实现的各种长度的编码,解码处理是相对复杂的,因此,解压缩处理是相对缓慢。
(4)Huffman编码只能使用整数来表示一个符号,而不是使用小数,这在很大程度上限制了压缩效果。
(5)霍夫曼是所有的位,如果改变其中一个可以使数据看起来完全不同
J. 如何用哈夫曼编码制作压缩解压缩软件
去问小翠啊, 望采纳,记得给分