请描述哈夫曼算法,并用图描述构造哈夫曼树的过程 ♂
请描述哈夫曼算法,并用图描述构造哈夫曼树的过程
- 请描述哈夫曼算法,并用图描述构造哈夫曼树的过程
- 如何写压缩软件,运用哈夫曼算法实现
- 哈夫曼的编码
- 哈夫曼树及哈夫曼编码译码的实现(根据程序画流程图及对每句程序注释)
- 哈夫曼编码译码的具体步骤不太明白
这个讲的相当清楚。
首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。它是一种变长的编码。在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。(注:码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。)
然而怎样构造一棵哈夫曼树呢?最具有一般规律的构造方法就是哈夫曼算法。一般的数据结构的书中都可以找到其描述:
一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止。
用C语言实现上述算法,可用静态的二叉树或动态的二叉树。若用动态的二叉树可用以下数据结构: struct tree{
float weight; /*权值*/
union{
char leaf; /*叶结点信息字符*/
struct tree *left; /*树的左结点*/
};
struct tree *right; /*树的右结点*/
};
struct forest{ /*F集合,以链表形式表示*/
struct tree *ti; /* F中的树*/
struct forest *next; /* 下一个结点*/
};
例:若字母A,B,Z,C出现的概率为:0.75,0.54,0.28,0.43;则相应的权值为:75,54,28,43。
构造好哈夫曼树后,就可根据哈夫曼树进行编码。例如:上面的字符根据其出现的概率作为权值构造一棵哈夫曼树后,经哈夫曼编码得到的对应的码值。只要使用同一棵哈夫曼树,就可把编码还原成原来那组字符。显然哈夫曼编码是前缀编码,即任一个字符的编码都不是另一个字符的编码的前缀,否则,编码就不能进行翻译。例如:a,b,c,d的编码为:0,10,101,11,对于编码串:1010就可翻译为bb或ca,因为b的编码是c的编码的前缀。刚才进行哈夫曼编码的规则是从根结点到叶结点(包含原信息)的路径,向左孩子前进编码为0,向右孩子前进编码为1,当然你也可以反过来规定。
这种编码方法是静态的哈夫曼编码,它对需要编码的数据进行两遍扫描:第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并必须把树的信息保存起来,即把字符0-255(2^8=256)的频率值以2-4BYTES的长度顺序存储起来,(用4Bytes的长度存储频率值,频率值的表示范围为0--2^32-1,这已足够表示大文件中字符出现的频率了)以便解压时创建同样的哈夫曼树进行解压;第二遍则根据第一遍扫描得到的哈夫曼树进行编码,并把编码后得到的码字存储起来。 静态哈夫曼编码方法有一些缺点:一、对于过短的文件进行编码的意义不大,因为光以4BYTES的长度存储哈夫曼树的信息就需1024Bytes的存储空间;二、进行哈夫曼编码,存储编码信息时,若用与通讯网络,就会引起较大的延时;三、对较大的文件进行编码时,频繁的磁盘读写访问会降低数据编码的速度。
因此,后来有人提出了一种动态的哈夫曼编码方法。动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。动态哈夫曼编码比静态哈夫曼编码复杂的多,有兴趣的读者可参考有关数据结构与算法的书籍。
前面提到的JPEG中用到了哈夫曼编码,并不是说JPEG就只用哈夫曼编码就可以了,而是一幅图片经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。
到文件压缩大家很容易想到的就是rar,zip等我们常见的压缩格式。然而,还有一种就是大家在学习数据结构最常见到的哈夫曼树的数据结构,以前还不知道他又什么用,其实他最大的用途就是用来做压缩,也是一些rar,zip压缩的祖先,称为哈弗曼压缩(什么你不知道谁是哈弗曼,也不知道哈弗曼压缩,不急等下介绍)。
随着网络与多媒体技术的兴起,人们需要存储和传输的数据越来越多,数据量越来越大,以前带宽有限的传输网络和容量有限的存储介质难以满足用户的需求。
特别是声音、图像和视频等媒体在人们的日常生活和工作中的地位日益突出,这个问题越发显得严重和迫切。如今,数据压缩技术早已是多媒体领域中的关键技术之一。
一、什么是哈弗曼压缩
Huffman(哈夫曼)算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明Huffman算法在无损压缩算法中是最优的。Huffman原理简单,实现起来也不困难,在现在的主流压缩软件得到了广泛的应用。对应用程序、重要资料等绝对不允许信息丢失的压缩场合,Huffman算法是非常好的选择。
二、怎么实现哈弗曼压缩
哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。
故我们得了解几个概念:
1、二叉树:在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。
2、哈夫曼编码(Huffman Coding):是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。
三、哈夫曼编码生成步骤:
①扫描要压缩的文件,对字符出现的频率进行计算。
②把字符按出现的频率进行排序,组成一个队列。
③把出现频率最低(权值)的两个字符作为叶子节点,它们的权值之和为根节点组成一棵树。
④把上面叶子节点的两个字符从队列中移除,并把它们组成的根节点加入到队列。
⑤把队列重新进行排序。重复步骤③④⑤直到队列中只有一个节点为止。
⑥把这棵树上的根节点定义为0(可自行定义0或1)左边为0,右边为1。这样就可以得到每个叶子节点的哈夫曼编码了。
既如 (a)、(b)、(c)、(d)几个图,就可以将离散型的数据转化为树型的了。
如果假设树的左边用0表示右边用1表示,则每一个数可以用一个01串表示出来。
则可以得到对应的编码如下:
1--》110
2--》111
3--》10
4--》0
每一个01串,既为每一个数字的哈弗曼编码。
为什么能压缩:
压缩的时候当我们遇到了文本中的1、2、3、4几个字符的时候,我们不用原来的存储,而是转化为用它们的01串来存储不久是能减小了空间占用了吗。(什么01串不是比原来的字符还多了吗?怎么减少?)大家应该知道的,计算机中我们存储一个int型数据的时候一般式占用了2^32-1个01位,因为计算机中所有的数据都是最后转化为二进制位去存储的。所以,想想我们的编码不就是只含有0和1嘛,因此我们就直接将编码按照计算机的存储规则用位的方法写入进去就能实现压缩了。
比如:
1这个数字,用整数写进计算机硬盘去存储,占用了2^32-1个二进制位
而如果用它的哈弗曼编码去存储,只有110三个二进制位。
效果显而易见。
哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。它是一种变长的编码。在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。(注:码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。) 而且哈夫曼编码是按照子树到父亲,而其读码则是完全相反的。 因此,后来有人提出了一种动态的哈夫曼编码方法。动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。动态哈夫曼编码比静态哈夫曼编码复杂的多,有兴趣的读者可参考有关数据结构与算法的书籍。
前面提到的JPEG中用到了哈夫曼编码,并不是说JPEG就只用哈夫曼编码就可以了,而是一幅图片经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。
哈夫曼树的构造算法。
const maxvalue= 10000; {定义最大权值}
maxleat=30; {定义哈夫曼树中叶子结点个数}
maxnode=maxleaf*2-1;
type HnodeType=record
weight: integer;
parent: integer;
lchild: integer;
rchild: integer;
end;
HuffArr:array of HnodeType;
var ……
procedure CreatHaffmanTree(var HuffNode: HuffArr); {哈夫曼树的构造算法}
var i,j,m1,m2,x1,x2,n: integer;
begin
readln(n); {输入叶子结点个数}
for i:=0 to 2*n-1 do {数组HuffNode初始化}
begin
HuffNode.weight=0;
HuffNode.parent=-1;
HuffNode.lchild=-1;
HuffNode.rchild=-1;
end;
for i:=0 to n-1 do read(HuffNode.weight); {输入n个叶子结点的权值}
for i:=0 to n-1 do {构造哈夫曼树}
begin
m1:=MAXVALUE; m2:=MAXVALUE;
x1:=0; x2:=0;
for j:=0 to n+i-1 do
if (HuffNode.parent=-1) then
begin m2:=m1; x2:=x1;
m1:=HuffNode.weight; x1:=j;
end
else if (HuffNode.parent=-1) then
begin m2:=HuffNode.weight; x2:=j; end;
{将找出的两棵子树合并为一棵子树}
HuffNode.parent:=n+i;
HuffNode.weight;
HuffNode.rchild:=x2;
end;
end;
这是以前写的,可是我不想加注释了,Huffman编码其实原理很简单的,你自己好好学下吧,一句一句注释也太夸张了啊。
#include《string.h》
#include《stdlib.h》
#include《stdio.h》
int m,s1,s2;
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char ** HuffmanCode;
void Select(HuffmanTree HT,int n)
{
int i,j;
for(i=1;i《=n;i++)
if(HT.parent==0)
{s1=i;
break;
}
for(j=i+1;j《=n;j++)
if(HT.parent==0)
{
s2=j;
break;
}
for(i=1;i《=n;i++)
{
if(HT.parent==0)
if(HT.weight)
if(s2!=i)
s1=i;
}
for(j=1;j《=n;j++)
{
if(HT.parent==0)
if(HT.weight)
if(s1!=j)
s2=j;
}
if(s1》s2)
{
int temp=s1;
s1=s2;
s2=temp;
}
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
int i,j;
char *cd;
int p;
int cdlen;
if (n《=1) return;
m = 2 * n - 1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));
for (i=1; i《=n; i++)
{
HT;
HT.parent=0;
HT.lchild=0;
HT.rchild=0;
}
for (i=n+1; i《=m; i++)
{
HT.weight=0;
HT.parent=0;
HT.lchild=0;
HT.rchild=0;
}
//添加查看,便于调试
printf(“构造过程显示:
“);
for(i=1;i《=m;i++)
printf(“%4d%4d%4d%4d%4d
“,i,HT.rchild);
system(“pause“);
for(i=n+1;i《=m;i++)
{
Select(HT,i-1);
HT.parent = i;
HT.rchild = s2;
HT.weight;
//添加查看,便于调试
/*printf(“s1=%d,s2=%d
“,s1,s2);
for(j=1;j《=i;j++)
printf(“%d%4d%4d%4d“,j,HT.rchild);
system(“pause“);
*/
}
cd = (char *)malloc(n*sizeof(char));
p=m;
cdlen=0;
for(i=1;i《=m;i++)
HT.weight=0;
while(p)
{
if(HT.weight==0)
{
HT.weight=1;
if(HT.lchild!=0)
{
p=HT.lchild;
cd=’0’;
}
else if(HT.rchild==0)
{
HC=(char *)malloc((cdlen+1)*sizeof(char));
cd=’0’;
strcpy(HC,cd);
}
}
else if(HT.weight==1)
{
HT.weight=2;
if(HT.rchild!=0)
{
p=HT.rchild;
cd=’1’;
}
}
else
{
HT.weight=0;
p=HT.parent;
--cdlen;
}
}
}
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int *w,n,i;
printf(“请输入节点数:
“);
scanf(“%d“,&n);
HC = (HuffmanCode)malloc(n*sizeof(HuffmanCode));
w=(int *)malloc(n*sizeof(int));
printf(“请输入节点的权值:
“);
for(i=0;i《n;i++)
scanf(“%d“,&w);
HuffmanCoding(HT,HC,w,n);
printf(“输出编码:
“);
for(i=1;i《=n;i++)
printf(“%2d(%4d):%s
“,i,w);
return 0;
system(“pause“);
}
PRSDBLOGAffectedRowCount @PackageType,1350,@@RowCount
while @@rowcount》1
delete
from temp
OUTPUT deleted.*
INTO temp_deleted
WHERE OperateTime 》 @CurrentDate
exec PRSDBLOGAffectedRowCount
set rowcount 0
相关tag:哈夫曼编码的基本步骤
本站部分资源来源于网络,如果侵犯了您的权益,请联系我们删除1354090129@qq.com
请提供Bentley(奔特力)Microstation软件中文教程的下载地址 ♂
请提供Bentley(奔特力)Microstation软件中文教程的下载地址
- 请提供Bentley(奔特力)Microstation软件中文教程的下载地址
- bentley二次开发可以做哪些应用
- 未能加载文件或程序集 bentley.microstation.DLL 或它的某一个依赖项.找不到指
- bentleycut是什么软件
- 请问北京Bentley软件公司怎么样请了解的指点一二,不懂的不要乱说,谢谢
相当年我也找的很辛苦阿~~~关于microstation的,因为我用这个软件,所以找了些。中文版的资料都是旧的,新版本的几乎都是英文的。
这个是视频学习:
http://www.xincad.com/forum/viewthread.php?tid=19667
这个是个论坛,有些视频和其他学习资料:
http://www.xincad.com/forum/forumdisplay.php?fid=94
这个也是一些资料:
http://www.bentleybbs.com/
http://www.zestcorp.com/Downloads/?type=4&Downloads=0
一个论坛,现在很少人了:
http://www.abbs.com.cn/bbs/post/page?bid=48&sty=1&tpg=1&s=0&age=0
bentley的二次开发,主要解决本土化、易用性问题。
由于是国外BIM软件,与国标规范的衔接不到位,需要通过二次开发来解决本地化落地的问题。
国外软件的使用习惯与国人的使用习惯,会有所不同,为了提高软件的使用效率,需要对软件二次开发,在原软件平台上,添加外部命令面板,从而达到快速操作,容易上手的目的。
应该是电脑缺失这个dll文件,你修复一下就可以了。
打开腾讯电脑管家--电脑诊所--软件问题--丢失.Dll 文件--一键修复--完成
腾讯电脑管家是一款免费专业的安全软件,融合了清理垃圾、电脑加速、修复漏洞、软件管理、电脑诊所等一系列辅助电脑管理功能,满足用户杀毒防护和安全管理的双重需求。能有效预防和解决计算机上常见的安全风险。
bentleycut是什么软件
Bentley不是指一个软件,而是一家公司的名字。Bentley系列产品软件是Bentley在2004年开发的技术专业3D建模软件,该软件会将所有命令加载到文件中,以更好地减少存储容量。为了更好地整合到示范法规的各个方面,软件可以与各种第三方软件一起使用。Bentley软件的主要功能包括:
(1)Bentley软件模型具有完整的功能,并且有许多易于使用的建模软件可用于构建BIM实体模型。软件的应用领域非常广泛,可以在工业产品设计,建筑规划与设计及其基础设施建设设计方案等多个层面上使用。
(2)Bentley有多种模型方法,可以满足设计计划人员对各种模型方法的要求。Bentley软件是一种基于MicroStation图形服务平台构建3D模型的软件。根据MicroStation图形服务平台的Bentley软件,可以开发各种模型方法,例如实线,网格图形,B样条曲线斜率,特征参数化和拓扑结构。。
(3)Bentley系统的模型工作需要与各种第三方软件配合使用。因此,设计人员将在模型的整个过程中接触各种操作面板,这将降低其可执行性。Bentley软件具有多种模型方法,但是通过不同模型方法构建的角色实体模型具有不同的特征。(资料来源于m.chinarevit.com)
最好说下你对哪方面感兴趣
总体来说算是还可以的公司,工资是一般的美资软件企业水平,待遇比AutoCAD、微软、SAP、Orical、IBM等差,销售的工作确实压力比较大,技术人员比较紧张,中国区的业务分成直销和渠道,因为进入中国市场时间比较晚,市场开拓的情况不是很理想,国内的市场知名度不是很高,但最近几年国内业绩增长较大,最近也在扩招人员,中国区的老板是马来西亚人
相关tag:bentleymoses软件下载
本站部分资源来源于网络,如果侵犯了您的权益,请联系我们删除1354090129@qq.com