哈夫曼树应用

合集下载

判定树

判定树

树有广泛的应用,其中一类重要的应用是描述分类过程。

分类是一种常用运算,其作用是将输入数据按预定的标准划分成不同的种类。

例如,某工厂对其产品的质量进行自动检测,并根据检测结果划分产品的质量等级。

等级标准见图4-22。

如何由产品的检测结果值a 确定其质量等级就是一个分类问题。

图4-22 分类问题示例用于描述分类过程的二叉树称为判定树。

判定树的每个非终端结点包含一个条件,因而对应于一次比较或判断;每个终端结点包含一个种类标记,对应于一种分类结果。

例如,图4-23(a)所示为求解上述分类问题的一棵判定树,树上的五个非终端结点对应五个条件判断,即对检测a 的五次比较。

(a)分类问题的一棵判定树(b)分类问题的另一棵判定树图4-23 判定树示例易知一棵判定树描述了一种分类方法。

图4-23(a)中判定树对应的分类算法如下:char classify1(float x)/ * 依给定标准将检测值x区分成相应的质量等级作为返回值 */{ if(x<5) return ('E');else if(x<6) return('D');else if(x<7)return('C');else if(x<8) return('B');else return('A');}利用这个算法,可由产品的检测结果值x确定其质量等级。

当一个分类算法需要反复使用时,其时间性能就值得进一步考虑。

假如进行上述产品质量自动分类(定等级)的工厂的产量很大,上述分类算法就将被频繁地重复使用,这时就需要考虑其时间性能。

假设需要分级的产品有N=100000件,并且这批产品的等级分布如图4-22中表格的第三行所示。

某等级产品总比较次数=某等级的“产品数”X单个检测的“比较次数”比如,D级产品数为N*20%个,为区分出一件产品是D级的,需进行2次比较。

那么,D级产品总比较次数=N*20%*2=100000*0.2*2=40000。

6-10+哈夫曼树

6-10+哈夫曼树

哈夫曼--编码
按A B C D E F G H 这八个字母出现的频率构造哈夫曼树。
A:0110,B:10,C:1110,D:1111, E:110,F:00,G:0111,H:010
树的带权路径长度的含义是各个字符的编码长与 其出现次数的乘积之和,也就是电文的代码总长, 所以采用哈夫曼树构造的编码是一种能使电文代码 总长最短的不等长编码。
对于同一组给定叶结点所构造的哈夫曼树,树的形状可 能不同,但带权路径长度值是相同的,一定是最小的
哈夫曼树—示例 叶结点权值集合为W = W = {7,5,3,1}构造哈夫曼树三种形态:
给定n个权值,需经过n-1次合并最终能得到一棵哈夫曼树。 经过n-1次合并得到n-1个新结点,这n-1个新结点都是具有两个孩子结点的分支 结点。也就是说哈夫曼树中没有度为1的结点。 构造的哈夫曼树共有2n-1个结点。
这样的编码不能保证译码的唯一性,我们称之为具有二义性的译码。
哈夫曼--编码
哈夫曼树可用于构造使电文的编码总长最短的编码方案,且不会产生二义性。
设需要编码的字符集合为{d1,d2,…,dn}, 它们在电文中出现的次数或频率集合为{w1,w2,…,wn}, 以d1,d2,…,dn作为叶结点,w1,w2,…,wn作为它们的权值, 构造一棵哈夫曼树,然后,规定哈夫曼树中的左分支代表0,右分支代表1, 则从根结点到每个叶结点所经过的路径分支组成的0和1的序列便为该结点对应 字符的编码,我们称之为哈夫曼编码。
哈夫曼树--基本概念
给定一组权值,用以作为叶结点可以构造出不同形状的二叉树。 例如,设有4个权值分别为1,3,5,7,作为4个叶结点,构造二叉树。
(a)
(b)
(c)
(d)
(e)

树的遍历和哈夫曼树

树的遍历和哈夫曼树
}
2021/4/18 北京化工大学信息学院 数据结构 33
求二叉树高度的递归算法
int Height ( BinTreeNode * T ) { if ( T == NULL ) return -1; else { int m = Height ( T->leftChild ); int n = Height ( T->rightChild ) ); return (m > n) ? m+1 : n+1;
中序遍历 (Inorder Traversal)
中序遍历二叉树算法的框架是:
若二叉树为空,则空操作;
-
否则 中序遍历左子树 (L);
+
/
访问根结点 (V);
a *e f
中序遍历右子树 (R)。
遍历结果
b-
a+b*c-d-e/f
cd
2021/4/18 北京化工大学信息学院 数据结构 20
二叉树递归的中序遍历算法
如果 n = 0,称为空树;如果 n > 0,则 ▪ 有一个特定的称之为根(root)的结点,
它只有直接后继,但没有直接前驱; ▪ 除根以外的其它结点划分为 m (m 0)
个 互不相交的有限集合T0, T1, …, Tm-1,每 个集合又是一棵树,并且称之为根的子树。
2021/4/18 北京化工大学信息学院 数据结构 3
typedef struct node { //树结点定义
TreeData data;
//结点数据域
struct node * leftChild, * rightchild;
//子女指针域
} BinTreeNode;
typedef BinTreeNode * BinTree; //树定义,代表树的根指针

哈夫曼树的平均编码长度

哈夫曼树的平均编码长度

哈夫曼树的平均编码长度
哈夫曼树的平均编码长度是指使用哈夫曼编码时,哈夫曼编码的总码长,除以出现的信息总字节数。

它是度量信息压缩技术中重要的参数,可以清楚地反映出编码和信息压缩技术的效率。

一、哈夫曼树的平均编码长度
1. 定义:哈夫曼树的平均编码长度是指使用哈夫曼树编码时,编码的总码长,除
以出现的信息总字节数。

2. 原理:哈夫曼编码的原理是,将较小的权值编码成较短的编码,而将较大的权值编码成较长的编码,这样,编码的总码长度就做出了贡献,使得编码总码长度降低。

3.计算:哈夫曼平均编码长度L = (sum(Pi*Li))/n ,其中Pi为概率,Li为对应的编码长度,n为文件中字节的总数。

4.应用:哈夫曼树的平均编码长度的应用情况非常广泛,常用来衡量压缩文件效果,以及传输数据链路的时延。

二、改进哈夫曼树的平均编码长度
1.动态哈夫曼树的应用:给出的源符号中有一组能够极大地缩减信息压缩时间和空间的改进型哈夫曼树——动态哈夫曼树,它可以计算出最优策略,即编码总数最小,权重最小。

这样,编码长度就比普通哈夫曼树大大缩小,达到了节省时间和空间的效果。

2.属性的重新确定:哈夫曼树的平均编码长度可以通过重新确定源文件属性而实现优化,建立合适的文件数据结构和定义顺序,使编码缩短。

3.编码技术:编码技术也可以显著缩短哈夫曼树的平均编码长度,二进制及其它数据表示法也可以用于改进哈夫曼树的平均编码长度,减少压缩包的容量。

总结:哈夫曼树的平均编码长度对于信息压缩技术中有着重要的意义,可以反映出编码和信息压缩技术的效率,可以从动态哈夫曼树的应用,以及属性的重新确定,以及编码技术等来得到优化改进,并实现了信息压缩的效果。

哈夫曼编码集和定长编码集构成的二叉树

哈夫曼编码集和定长编码集构成的二叉树

哈夫曼编码集和定长编码集构成的二叉树在信息论和计算机科学中,哈夫曼编码集和定长编码集构成的二叉树是一个非常重要的概念。

它们是用来表示和压缩数据的有效方法,也被广泛应用在数据传输和存储中。

理解这个概念对于深入研究数据处理和编码技术至关重要。

在本文中,我将对哈夫曼编码集和定长编码集构成的二叉树进行深度和广度的探讨,以便读者能更全面地理解这一概念。

1. 哈夫曼编码集和定长编码集的概念解释哈夫曼编码集和定长编码集是两种不同的编码方法,用于将数据进行压缩或表示。

定长编码集是一种固定长度的编码方式,例如每个字符都用8位二进制数表示。

而哈夫曼编码集是一种根据数据的出现频率来动态分配编码长度的方法,出现频率高的字符使用较短的编码,出现频率低的字符使用较长的编码。

哈夫曼编码集通常能够更有效地压缩数据,因为它充分利用了数据的统计特性。

2. 哈夫曼编码集和定长编码集构成的二叉树哈夫曼编码集和定长编码集构成的二叉树是通过将编码集中的每个字符构建成一个叶节点,然后根据编码长度和频率构建一棵二叉树。

在这棵二叉树中,出现频率高的字符对应的叶节点距离根节点较近,而出现频率低的字符对应的叶节点距离根节点较远。

这样就能够根据字符的编码快速地找到对应的二进制表示,从而实现高效的数据压缩和传输。

3. 深入探讨哈夫曼编码集和定长编码集构成的二叉树哈夫曼编码集和定长编码集构成的二叉树在数据压缩和编码领域有着广泛的应用。

它不仅能够有效地压缩数据,还能够提高数据传输和存储的效率。

通过深入研究这一概念,我们能够更全面地了解数据压缩的原理和方法,从而更好地应用于实际场景中。

4. 个人观点和理解对于哈夫曼编码集和定长编码集构成的二叉树,我认为它是一种非常高效且优雅的数据表示和压缩方法。

它通过合理地利用数据的统计特性,能够在不损失数据准确性的前提下大大减小数据的存储和传输开销。

在实际应用中,我们可以根据数据的特点选择合适的编码方式,以达到最佳的压缩效果。

哈夫曼编码应用的一种改进——范式哈夫曼编码

哈夫曼编码应用的一种改进——范式哈夫曼编码

种 最 优 的前 缀 编 码 技 术 ,然 而 其 存 在 的 沿 着 从根 结 点 到 叶结 点 ( 含 原 信 息 ) 路 包 的 范式哈 夫曼编码最 早 由 S h rz1 6 】 c wa t 【9 4 足 却 制 约 了 它 的 直 接 应 用 。 首 先 ,其 解 码 径 ,向左 孩子 前 进 编码 为 0,向 右孩 子 前 进 提 出 ,它 是 哈 夫 曼 编 码 的一 个子 集 。其 中 心 思 想是 : 使用 某些 强 制 的约 定 , 通 过很 仅 时 间为 O 1v )其 中 l v (a g , a g为码 字 的平均长 编码 为 1,当然 也 可 以 反过 来 规 定 。 例 如 :对 下 面 这 串 出 现 了五 种 字 符 的 少 的 数 据 便 能 重 构 出 哈 夫 曼 编 码 树 的 结 度 ; 次 ,更为 最 重 要 的 是 ,解码 器 需 要 知 其 道 哈 夫 曼编 码 树 的 结 构 ,因而 编 码 器 必 须 信息(0 4 个字符长 ) 行编码 :a c d a a d d 构 。其 中一 种 很 重 要 的 约 定 是数 字序 列属 进 cb e ecc e 为 解 码 器 保 存 或 传 输 哈 夫 曼 编 码 树 。对 于 小 量 数 据 的 压 缩 而 言 ,这 是 很 大 的 开 销 。 因 而 ,应 用 哈 夫 曼编 码 的 关 键 是 如 何 降 低 哈 夫 曼 编 码 树 的 存 储 空 间 。本 文主 要 介 绍 种 常 用 的 方法 范 式 哈 夫 曼编 码 以 及 解 码 算 法 , 目前 流行 的 很 多压 缩 方 法 都 使
例如对下面达串出现了五种字符的信个字符长进行编码五种字符的出现次数分别一一构造出的哈夫曼树如下于是我们得到了此信息的编码表可以将例子中的信息编码为码长共位若用码表示上述信息则需要缩但是其解码时间为其中为码字的平均长度并且解码器需要知道哈夫曼编码村的结构因而编码器必须为解码器保存或传输哈夫曼编码树

哈夫曼树的构造

哈夫曼树的构造关键思想: 依据哈弗曼树的定义,⼀棵⼆叉树要使其WPL值最⼩,必须使权值越⼤的叶⼦结点越靠近根结点,⽽权值越⼩的叶⼦结点越远离根结点。

哈弗曼根据这⼀特点提出了⼀种构造最优⼆叉树的⽅法,其基本思想如下:1。

根据给定的n个权值{w1, w2, w3 ... w n },构造n棵只有根节点的⼆叉树,令起权值为w j2。

在森林中选取两棵根节点权值最⼩的树作为左右⼦树,构造⼀颗新的⼆叉树,置新⼆叉树根节点权值为其左右⼦树根节点权值之和。

注意,左⼦树的权值应⼩于右⼦树的权值。

3。

从森林中删除这两棵树,同时将新得到的⼆叉树加⼊森林中。

(换句话说,之前的2棵最⼩的根节点已经被合并成⼀个新的结点了)4。

重复上述两步,直到只含⼀棵树为⽌,这棵树即是哈弗曼树以下演⽰了⽤Huffman算法构造⼀棵Huffman树的过程:考研题⽬:三、哈夫曼树的在编码中的应⽤在电⽂传输中,须要将电⽂中出现的每⼀个字符进⾏⼆进制编码。

在设计编码时须要遵守两个原则:(1)发送⽅传输的⼆进制编码,到接收⽅解码后必须具有唯⼀性,即解码结果与发送⽅发送的电⽂全然⼀样;(2)发送的⼆进制编码尽可能地短。

以下我们介绍两种编码的⽅式。

1. 等长编码这样的编码⽅式的特点是每⼀个字符的编码长度同样(编码长度就是每⼀个编码所含的⼆进制位数)。

如果字符集仅仅含有4个字符A,B,C,D,⽤⼆进制两位表⽰的编码分别为00,01,10,11。

若如今有⼀段电⽂为:ABACCDA,则应发送⼆进制序列:00010010101100,总长度为14位。

当接收⽅接收到这段电⽂后,将按两位⼀段进⾏译码。

这样的编码的特点是译码简单且具有唯⼀性,但编码长度并⾮最短的。

2. 不等长编码在传送电⽂时,为了使其⼆进制位数尽可能地少,能够将每⼀个字符的编码设计为不等长的,使⽤频度较⾼的字符分配⼀个相对照较短的编码,使⽤频度较低的字符分配⼀个⽐較长的编码。

⽐如,能够为A,B,C,D四个字符分别分配0,00,1,01,并可将上述电⽂⽤⼆进制序列:000011010发送,其长度仅仅有9个⼆进制位,但随之带来了⼀个问题,接收⽅接到这段电⽂后⽆法进⾏译码,由于⽆法断定前⾯4个0是4个A,1个B、2个A,还是2个B,即译码不唯⼀,因此这样的编码⽅法不可使⽤。

哈夫曼树

实例
字符序列:DATA TRERTER ARE AREA ART 用0、1组合进行编码,希望01串长度最短。 字符集为{A,D,T,R,E},各字母出现的次 数为{6,1,4,6,4} 高频字符,译码尽可能短


一个方案
– – – – – A:10 D:010 T:011 R:11 E:00

基本术语

结点的权
– 在许多实际应用中,常常将树中的某些结 点赋上一个具有一定意义的实数,这个实 数称为该结点的权

结点的带权路径
– 从根结点到结点的路径长度*结点的权
树的带权路径WPL
– 树中所有叶子结点的带权路径长度之和
基本术语

对所有叶子结点i计算 Wi Li

计算WPL
哈夫曼树
最优树/哈夫曼树
(1)与n个权对应的结点构成具有n棵二叉 树的森林F={T1,T2,…,Tn},其中每棵二叉 树Ti都只有一个根结点,左右子树均空 (2)从F中选出根结点权值最小的两棵树 作为一棵树的左右子树,且置新树的根 结点权值为左右子树根结点权值之和 (3)从F中删除这两棵树,将新树加入F (4)重复(2)、(3),直到F中只含一棵树
哈夫曼树
哈夫曼(haffman)树又称为最优二叉树, 它是n个带权叶子结点构成的二叉树中 WPL最小的二叉树。 ??

ቤተ መጻሕፍቲ ባይዱ
– 所有叶子结点的权值均为1(或相等),构 成的二叉树形式? – 在哈夫曼树中叶子结点的权与路径长度的关 系? – 叶子数目已知,结点总数=? – 唯一性?
哈夫曼树—构造(贪心)
ht[m].codify:=“”; for i:=m downto n+1 do begin p:=ht[i].lchild; if p<>0 then ht[p].codify:=ht[i].codify+”0” p:=ht[i].rchild; if p<>0 then ht[p].codify:=ht[i].codify+”1” end;

哈夫曼树结点数和叶子结点数的关系

哈夫曼树结点数和叶子结点数的关系
哈夫曼树是一种经典的数据结构,它是一种最优二叉树,可以用来压缩数据。

在哈夫曼树中,每个叶子结点对应一个字符,并且每个非叶子结点对应两个子节点。

由于哈夫曼树是最优的,所以它的深度最小,也就是说,所有叶子结点到根结点的路径长度之和最小。

哈夫曼树的结点数和叶子结点数之间有一定的关系。

我们可以通过数学归纳法来证明这个结论。

首先,当只有一个字符时,哈夫曼树只有一个叶子结点,结点数也只有一个。

当有两个字符时,哈夫曼树有两个叶子结点和一个非叶子结点,结点数为三。

当有三个字符时,哈夫曼树有三个叶子结点和两个非叶子结点,结点数为五。

我们可以发现,每增加一个字符,哈夫曼树就会增加一个叶子结点和一个非叶子结点,因此,结点数总是奇数。

我们可以用数学公式来表达这个结论。

假设有n个字符,哈夫曼树有m个叶子结点和n-1个非叶子结点。

则哈夫曼树的结点数为:
m + (n-1) = n + (n-1) = 2n-1
因此,哈夫曼树的结点数总是奇数,与叶子结点数的关系为:结点数 = 2 x 叶子结点数 - 1。

这个结论对于哈夫曼树的构建和分析都具有重要的意义。

- 1 -。

哈夫曼树构造规则

哈夫曼树构造规则哈夫曼树是一种用于数据压缩和编码的重要数据结构。

它是由一组字符和它们对应的频率构成的,根据频率构造出来的一种特殊的二叉树。

哈夫曼树的构造规则如下:1. 频率越高的字符越靠近根节点在哈夫曼树中,频率越高的字符被赋予越短的编码,这样可以减少编码的长度,从而达到压缩数据的目的。

因此,在构造哈夫曼树时,我们需要根据字符的频率来确定它们在树中的位置,频率越高的字符越靠近根节点。

2. 构造过程中采用贪心算法构造哈夫曼树的过程中,我们需要根据字符的频率来选择合适的节点进行合并。

在每一步中,我们选择频率最小的两个节点进行合并,然后将合并后的节点作为一个新节点插入到原来的节点集合中。

这种选择最小频率的节点的策略就是贪心算法。

3. 合并节点的频率为两个节点频率之和当我们选择两个频率最小的节点进行合并时,合并后的节点的频率就是这两个节点的频率之和。

这是因为合并后的节点代表了这两个节点的集合,所以它的频率就是这两个节点频率之和。

4. 构造过程中节点数目逐渐减少在构造哈夫曼树的过程中,每次合并两个节点,树的节点数目就减少一个。

最终,当只剩下一个节点时,这个节点就是哈夫曼树的根节点。

5. 构造过程中节点的位置不变在哈夫曼树的构造过程中,每个节点的位置是固定的,只是节点之间的连接关系发生了变化。

频率越高的节点越靠近根节点,频率越低的节点越远离根节点。

6. 哈夫曼树的带权路径长度最小哈夫曼树的带权路径长度是指树中每个叶子节点的权值乘以它到根节点的路径长度之和。

在所有可能的二叉树中,哈夫曼树的带权路径长度是最小的,这也是它被广泛应用于数据压缩和编码的原因之一。

通过以上的构造规则,我们可以得到一个符合要求的哈夫曼树。

这棵树可以用于对字符进行编码和解码,实现数据的压缩和解压缩。

在哈夫曼树中,频率高的字符对应的编码较短,频率低的字符对应的编码较长,从而实现了数据的有效压缩。

同时,由于哈夫曼树的构造过程中采用了贪心算法,所以构造出来的哈夫曼树的带权路径长度是最小的,这也保证了数据压缩的效果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一.具体任务 题目:哈夫曼树应用 功能: 1.从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上; 2. 中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中,并输出结果。同时将此字符形式的编码文件写入文件CodePrint中。 3.利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中,并输出结果。 二.软件环境 Code::Blocks10.05 三.算法设计思想 1.建立哈夫曼树函数 void HuffTree(HNode Huff[],int n) //生成哈夫曼树 { FILE *fp; char d; int i,j,w,m1,m2,x1,x2; for(i=0;i<2*n-1;i++) //对数组Huff初始化 { Huff[i].ch=' '; Huff[i].weight=0; Huff[i].parent=-1; Huff[i].lchild=-1; Huff[i].rchild=-1; } printf("输入%d个字符及它的权值: \n",n);//读入数据 getchar(); for(i=0;i{ printf("请输入第%d个字符:",i+1); scanf("%c",&d); getchar(); Huff[i].ch=d; printf("请输入第%d个字符的权值:",i+1); scanf("%d",&w); getchar(); Huff[i].weight=w; } for(i=0;i//构造哈夫曼树并生成该树的n-1个分支结点 { m1=m2=32767; x1=x2=0; for(j=0;j//选取最小和次小两个权值结点并将其序号送x1和x2 { if(Huff[j].parent==-1&&Huff[j].weight{ m2=m1; x2=x1; m1=Huff[j].weight; x1=j; } else if(Huff[j].parent==-1&&Huff[j].weight{ m2=Huff[j].weight; x2=j; } } //将找出的两棵子树合并为一棵新的子树 Huff[x1].parent=n+i; Huff[x2].parent=n+i; Huff[n+i].weight=Huff[x1].weight+Huff[x2].weight; Huff[n+i].lchild=x1; Huff[n+i].rchild=x2; } 2.对哈夫曼树进行编码

void HuffmanCode(HNode Huff[],int n) //生成哈夫曼编码 { FILE *fw; HCode HuffCode[MAXSIZE/2],cd; // MAXSIZE/2为叶结点的最大个数 int i,j,c,p; for(i=0;i//求每个叶结点的哈夫曼编码 { HuffCode[i].weight=Huff[i].weight; cd.start=MAXBIT-1; c=i; p=Huff[c].parent; while(p!=-1) { if(Huff[p].lchild==c) cd.bit[cd.start]=0; else cd.bit[cd.start]=1; cd.start--; c=p; p=Huff[c].parent; } for(j=cd.start+1;j//保存该叶结点字符的哈夫曼编码 HuffCode[i].bit[j]=cd.bit[j]; HuffCode[i].start=cd.start; //保存该编码在数组bit中的起始位置 } 3.根据哈夫曼编码进行译码 void decode(HNode Huff[],int n) //依次读入电文,根据哈夫曼树译码 { FILE *fs; int i,j=0; char b[MAXSIZE]; i=2*n-2; //从根结点开始往下搜索 printf("【输入电文,并进行译码】\n"); getchar(); printf("输入发送的编码(以'2'为结束标志):\n"); gets(b); printf("译码后的字符为:\n"); while(b[j]!='2') { if(b[j]=='0') i=Huff[i].lchild; //走向左孩子 else i=Huff[i].rchild; //走向右孩子 if(Huff[i].lchild==-1) //tree[i]是叶结点 { printf("%c",Huff[i].ch); i=2*n-2; //回到根结点 } j++; } printf("\n"); if(Huff[i].lchild!=-1&&b[j]!='2') //电文读完,但尚未到叶子结点 printf("\nERROR\n"); //输入电文 4.菜单调用 void menu() { printf("菜单如下\n"); printf("1-------建立哈夫曼树\n" ); printf("2-------进行哈夫编码\n"); printf("3-------进行哈夫译码\n"); printf("0-------程序退出\n"); } 5.main函数进行调用 int main() { HNode Huff[MAXSIZE]; int n,sel; printf(" ——哈夫曼编码与译码——\n"); printf("Input numbers of leaf :\n"); //n为叶结点个数 scanf("%d",&n); do { menu(); printf("请输入您的选择:\n"); scanf("%d",&sel); switch(sel) { case 1: HuffTree(Huff,n);//建立哈夫曼树 break; case 2: HuffmanCode(Huff,n); //生成哈夫曼编码 break; case 3: decode(Huff,n);//译码变代码 break; } }while(sel!=0); return 0; } 四.源代码 #include #include #define MAXSIZE 1000 #define MAXBIT 1000 //定义哈夫曼编码的最大长度 typedef struct { char ch;//增加一个域用于存放该节点的字符 int weight,parent,lchild,rchild; }HNode; //哈夫曼树结点类型 typedef struct { int weight; int bit[MAXBIT]; int start; }HCode; //哈夫曼编码类型 void HuffTree(HNode Huff[],int n) //生成哈夫曼树 { FILE *fp; char d; int i,j,w,m1,m2,x1,x2; for(i=0;i<2*n-1;i++) //对数组Huff初始化 { Huff[i].ch=' '; Huff[i].weight=0; Huff[i].parent=-1; Huff[i].lchild=-1; Huff[i].rchild=-1; } printf("输入%d个字符及它的权值: \n",n);//读入数据 getchar(); for(i=0;i{ printf("请输入第%d个字符:",i+1); scanf("%c",&d); getchar(); Huff[i].ch=d; printf("请输入第%d个字符的权值:",i+1); scanf("%d",&w); getchar(); Huff[i].weight=w; } for(i=0;i//构造哈夫曼树并生成该树的n-1个分支结点 { m1=m2=32767; x1=x2=0; for(j=0;j//选取最小和次小两个权值结点并将其序号送x1和x2 { if(Huff[j].parent==-1&&Huff[j].weight{ m2=m1; x2=x1; m1=Huff[j].weight; x1=j; } else if(Huff[j].parent==-1&&Huff[j].weight{ m2=Huff[j].weight; x2=j; } } //将找出的两棵子树合并为一棵新的子树 Huff[x1].parent=n+i; Huff[x2].parent=n+i; Huff[n+i].weight=Huff[x1].weight+Huff[x2].weight; Huff[n+i].lchild=x1; Huff[n+i].rchild=x2;

相关文档
最新文档