导航:首页 > 源码编译 > 哈夫曼算法最优前缀码

哈夫曼算法最优前缀码

发布时间:2022-09-13 15:34:08

Ⅰ 如何证明哈夫曼编码一定是不重复的最优编码

哈夫曼编码完全依据字符出现概率来构造异字头的平均长度最短的码字,所以频率相同的编码可以互换,两种编码之后的字符串的平均期望长度是相同的。这里你和你同学做出的结果不同是因为哈夫曼树是二叉树,编码频率相同,但插入到二叉树的顺序不同,所以出现了不同的结果。

Ⅱ 求数据结构(JAVA版)实验树和二叉树题目答案

/**
* @param args
之前在大学的时候写的一个二叉树算法,运行应该没有问题,就看适不适合你的项目了 */
public static void main(String[] args) {

BiTree e = new BiTree(5);
BiTree g = new BiTree(7);
BiTree h = new BiTree(8);
BiTree l = new BiTree(12);
BiTree m = new BiTree(13);
BiTree n = new BiTree(14);
BiTree k = new BiTree(11, n, null);
BiTree j = new BiTree(10, l, m);
BiTree i = new BiTree(9, j, k);
BiTree d = new BiTree(4, null, g);
BiTree f = new BiTree(6, h, i);
BiTree b = new BiTree(2, d, e);
BiTree c = new BiTree(3, f, null);
BiTree tree = new BiTree(1, b, c);
System.out.println("递归前序遍历二叉树结果: ");
tree.preOrder(tree);
System.out.println();
System.out.println("非递归前序遍历二叉树结果: ");
tree.iterativePreOrder(tree);
System.out.println();
System.out.println("递归中序遍历二叉树的结果为:");
tree.inOrder(tree);
System.out.println();
System.out.println("非递归中序遍历二叉树的结果为:");
tree.iterativeInOrder(tree);
System.out.println();
System.out.println("递归后序遍历二叉树的结果为:");
tree.postOrder(tree);
System.out.println();
System.out.println("非递归后序遍历二叉树的结果为:");
tree.iterativePostOrder(tree);
System.out.println();
System.out.println("层次遍历二叉树结果: ");
tree.LayerOrder(tree);
System.out.println();
System.out.println("递归求二叉树中所有结点的和为:"+getSumByRecursion(tree));
System.out.println("非递归求二叉树中所有结点的和为:"+getSumByNoRecursion(tree));

System.out.println("二叉树中,每个节点所在的层数为:");
for (int p = 1; p <= 14; p++)
System.out.println(p + "所在的层为:" + tree.level(p));
System.out.println("二叉树的高度为:" + height(tree));
System.out.println("二叉树中节点总数为:" + nodes(tree));
System.out.println("二叉树中叶子节点总数为:" + leaf(tree));
System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));
System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));
System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));
System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));
System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));
System.out.println("--------------------------------------");
tree.exChange();
System.out.println("交换每个节点的左右孩子节点后......");
System.out.println("递归前序遍历二叉树结果: ");
tree.preOrder(tree);
System.out.println();
System.out.println("非递归前序遍历二叉树结果: ");
tree.iterativePreOrder(tree);
System.out.println();
System.out.println("递归中序遍历二叉树的结果为:");
tree.inOrder(tree);
System.out.println();
System.out.println("非递归中序遍历二叉树的结果为:");
tree.iterativeInOrder(tree);
System.out.println();
System.out.println("递归后序遍历二叉树的结果为:");
tree.postOrder(tree);
System.out.println();
System.out.println("非递归后序遍历二叉树的结果为:");
tree.iterativePostOrder(tree);
System.out.println();
System.out.println("层次遍历二叉树结果: ");
tree.LayerOrder(tree);
System.out.println();

System.out.println("递归求二叉树中所有结点的和为:"+getSumByRecursion(tree));
System.out.println("非递归求二叉树中所有结点的和为:"+getSumByNoRecursion(tree));

System.out.println("二叉树中,每个节点所在的层数为:");
for (int p = 1; p <= 14; p++)
System.out.println(p + "所在的层为:" + tree.level(p));
System.out.println("二叉树的高度为:" + height(tree));
System.out.println("二叉树中节点总数为:" + nodes(tree));
System.out.println("二叉树中叶子节点总数为:" + leaf(tree));
System.out.println("二叉树中父节点总数为:" + fatherNodes(tree));
System.out.println("二叉树中只拥有一个孩子的父节点数:" + oneChildFather(tree));
System.out.println("二叉树中只拥有左孩子的父节点总数:" + leftChildFather(tree));
System.out.println("二叉树中只拥有右孩子的父节点总数:" + rightChildFather(tree));
System.out.println("二叉树中同时拥有两个孩子的父节点个数为:" + doubleChildFather(tree));
}
}

Ⅲ 在什么情况下,等长编码是最优前的编码

在(平均码长为2.24)情况下,等长编码是最优前的编码.常见的等长编码就是前缀码。所谓最优前缀码是指,平均码长或文件总长最小的前缀编码称为最优的前缀码(这里的平均码长相当于码长的期望值)。
变长编码可能使解码产生二义性,而前缀码的出现很好地解决了这个问题。而平均码长相当于二叉树的加权路径长度,从这个意义上说,由哈夫曼树生成的编码一定是最优前缀码,故通常不加区分的将哈夫曼编码也称作最优前缀码。
需要注意的是,由于哈夫曼树建立过程的不唯一性可知,生成的哈夫曼编码也是不唯一的.

Ⅳ 哈夫曼编码码长怎么算

设某信源产生有五种符号u1、u2、u3、u4和u5,对应概率P1=0.4,P2=0.1,P3=P4=0.2,P5=0.1。

霍夫曼编码是变长编码,思路:对概率大的编的码字短,概率小的编的码字长,这样一来所编的总码长就小,这样编码效率就高。上面那样求是不对的,除非你这6个码字是等概率的,各占1/6。应该用对应的概率*其对应得码长,再求和。

实际应用中

除采用定时清洗以消除误差扩散和采用缓冲存储以解决速率匹配以外,主要问题是解决小符号集合的统计匹配,例如黑(1)、白(0)传真信源的统计匹配,采用0和1不同长度游程组成扩大的符号集合信源。游程,指相同码元的长度(如二进码中连续的一串0或一串1的长度或个数)。

按照CCITT标准,需要统计2×1728种游程(长度),这样,实现时的存储量太大。事实上长游程的概率很小,故CCITT还规定:若l表示游程长度,则l=64q+r。

Ⅳ 前缀编码的哈夫曼编码

用构造哈夫曼树的过程生成的二进制前缀编码。哈夫曼树是一类带权路径长度最短的树。
特点:长度最短

Ⅵ 离散数学如何判断前编码

即上述编码是二进制的前缀码。前缀码:对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀。

利用哈夫曼树很容易求出给定字符集及其概率(或频度)分布的最优前缀码。该编码即为最优前缀码(也称哈夫曼编码)。2. 哈夫曼编码为最优前缀码。这个比较复杂,一般记牢好商品条形码中的前缀码(用来标识国家或地区的),加上对批号的认识就差不多了。

欧莱雅在在法国的前缀码是30-37,表示是 。离散数学前缀码,utf-8 是一种针对unicode的可变长度字符编码,也是一种前缀码。其中第09-20项用于设置需要进行ip路由的市话前缀码(1位或2位)。

在系统中设置经济线路接入号码,见系统编程项目03(经济线路接入号),市话经济线路的指定前缀码见系统编程16项(限制代码b)的09~20项输入,是否设置定时参数,见系统编程项目08(定时参数调整)的参数2。

c的一个前缀码编码方案对应于一棵二叉树t。则平均码长定义为:使平均码长达到最的前缀码编码方案称为c的最优前缀码。离散数学前缀码,二叉树t表示字符集c的一个最优前缀码,证明可以对t作适当修改后得到一棵新的二叉树t”,在t”中x和y是最深叶子且为兄弟,同时t”表示的前缀码也是c的最优前缀码。

二叉树t表示字符集c的一个最优前缀码,x和y是树t中的两个叶子且为兄弟,z是它们的父亲。f(y)的字符,则树t’=t-{x,y}表示字符集c’=c-{x, y} ∪ { z}的一个最优前缀码。

Ⅶ 请描述哈夫曼算法,并用图描述构造哈夫曼树的过程。

这个讲的相当清楚。
首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为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就只用哈夫曼编码就可以了,而是一幅图片经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。

Ⅷ 叙述哈夫曼算法的思想

运行过了没有任何问题,有什么问题可以交流下.
#include
#include
#define N 6
typedef struct
{

int W,P,R,L;
}HTNode;
typedef struct
{
char ch;
char code[10];
}HTCode;
HTCode HC[27];
void select(HTNode HT[],int *min1,int *min2,int *a,int *b)
{

int i;int mina=100,minb=100;
int m,n;

for(i=1;i

Ⅸ 求助有关哈夫曼树的问题!急!满意的答案再加!

哈夫曼树
一、 基本术语
1. 路径与路径长度
若在一棵树中存在一个结点序列 k1, k2, …., kj ,使得kj是kj+1的双亲(1<=i<j),则称结点序列是从k1到kj 的路径(如树中的某个结点到它的某个祖先,或者到它的某个后代的的包括它本身的一系列按顺序的结点序列称为路径),因树中的每个结点只有一个双亲结点,所以这是两个结点间的唯一路径,从k1到kj 所经过的分支数称为这两点之间的路径长度。它等于结点数-1。
如: 从结点A到结点J的结点序
列为A,B,E,J。
路径长度为3。

8 10

4 5 3
2. 结点的权和带权路径长度
如果根据需要给树中的结点赋予一个有某中意义的实数,则称此实数为该结点的权,结点带权路径长度规定为从树根结点到该结点之间的路径长度乘上该结点的权值所得到的乘积。
3. 树的带权路径长度
树的带权路径长度定义为树中所有叶结点的带权路径长度之和,通常记为:
n
WPL=∑ wili wi和li 分别代表叶结点ki的权值和ki到
i=1 根结点的路径长度
例如:上图的WPL=(4+5+3)*3+(8+10)*2=72
4. 哈夫曼树
哈夫曼树又称为最优二叉树,它是由n个带权叶结点构成的所有二叉树中带权路径长度WPL最小的二叉树。
例如:有四个叶结点a,b,c,d,分别带权为9,4,5,2,可以构成三棵不同的二叉树(当然可以构成更多的二叉树)见下图:

9 4 5 2 WPL=(9+4+5+2)*2=40

4

2

5 9
WPL=(9+5)*3+2*2+4*1=50

4

2

5 9
WPL=(9+5)*3+2*2+4*1=50

9

5

4 2
WPL=9*1+5*2+(2+4)*3=37
可以证明最后一棵二叉树是哈夫曼树。
二、 构造哈夫曼树
1. 将n个叶结点构成独立的n棵二叉树,每棵二叉树只有一个根结点。
2. 选择两棵权值最小的二叉树合并成一棵二叉树,并以这两棵二叉树的权值之和作为这棵二叉树的权值,取消原来的两棵二叉树。
3. 重复2,知道只剩一棵二叉树为止。
例如:有6个带权叶结点的权值分别为:3,6,8,5,2,2,构造一棵哈夫曼树,并计算WPL的结果。
1.构造6棵二叉树

3 6 8 5 2 2
2选出两个权值最小的二叉树的组成一棵二叉树

2 2 合并权值为4

3 6 8 5
3 6 8 5 4
2 2
选出两个权值最小的二叉树的组成一棵二叉树

7 6 8 5

3

2 2
选出两个权值最小的二叉树的组成一棵二叉树

7 11 8

3
5 6
2 2
选出两个权值最小的二叉树的组成一棵二叉树

15 11

8
5 6
3

2 2

选出两个权值最小的二叉树的组成一棵二叉树(最终的哈夫曼树)

8
5 6
3

2 2
WPL=(2+2)*4+3*3+(5+6+8)*2=16+9+38=63
作业:P221/9

阅读全文

与哈夫曼算法最优前缀码相关的资料

热点内容
卡尔曼滤波算法书籍 浏览:763
安卓手机怎么用爱思助手传文件进苹果手机上 浏览:840
安卓怎么下载60秒生存 浏览:799
外向式文件夹 浏览:231
dospdf 浏览:427
怎么修改腾讯云服务器ip 浏览:382
pdftoeps 浏览:489
为什么鸿蒙那么像安卓 浏览:732
安卓手机怎么拍自媒体视频 浏览:182
单片机各个中断的初始化 浏览:720
python怎么集合元素 浏览:477
python逐条解读 浏览:829
基于单片机的湿度控制 浏览:495
ios如何使用安卓的帐号 浏览:879
程序员公园采访 浏览:807
程序员实战教程要多长时间 浏览:970
企业数据加密技巧 浏览:131
租云服务器开发 浏览:809
程序员告白妈妈不同意 浏览:332
攻城掠地怎么查看服务器 浏览:597