哈夫曼树

哈弗曼树

六眼飞鱼酱① 提交于 2019-12-20 02:37:20
[实验内容] 1、建立哈夫曼树; 2、哈夫曼编码、解码。 【实验测试数据】 #include "stdio.h" #include "stdlib.h" #include "string.h" typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/ /*哈夫曼树类型定义*/ typedef struct { char letter; int weight; /*结点的权值*/ int parent; /*双亲的下标*/ int LChild; /*左孩子结点的下标*/ int RChild; /*右孩子结点的下标*/ }HTNode,*HuffmanTree;/*HuffmanTree是结构数组类型*/ /*在1~i-1范围内选择两个parent为0且weight最小的结点,其序号分别赋给s1、s2返回*/ void select(HuffmanTree *ht,int n, int *s1, int *s2) { int i; int min; for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { min = i; i = n+1; } } for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { if((*ht)[i].weight < (*ht)[min]

数据结构——哈夫曼树

痴心易碎 提交于 2019-12-19 12:40:57
转自:http://www.cnblogs.com/skywang12345/p/3706833.html 哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。 定义 :给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答。 (01) 路径和路径长度 定义 :在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 例子 :100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。 (02) 结点的权及带权路径长度 定义 :若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 例子 :节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。 (03) 树的带权路径长度 定义 :树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。 例子 :示例中,树的WPL= 1* 100 + 2* 50 + 3* 20 + 3* 10 = 100 + 100 + 60 + 30 =

哈夫曼树C++实现详解

◇◆丶佛笑我妖孽 提交于 2019-12-19 12:40:31
哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答。 (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 例子:100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。 (02) 结点的权及带权路径长度 定义:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 例子:节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。 (03) 树的带权路径长度 定义:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。 例子:示例中,树的WPL= 1*100 + 2*80 + 3*20 + 3*10 = 100 + 160 + 60 + 30 = 350。 比较下面两棵树 上面的两棵树都是以{10, 20, 50, 100}为叶子节点的树。 左边的树WPL=2*10 + 2

哈夫曼树(一)之 C语言详解

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-19 12:40:19
哈夫曼树(一)之 C语言详解 本章介绍哈夫曼树。和以往一样,本文会先对哈夫曼树的理论知识进行简单介绍,然后给出C语言的实现。后续再分别给出C++和Java版本的实现;实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可。若文章有错误或不足的地方,请帮忙指出! 目录 1 . 哈夫曼树的介绍 2 . 哈夫曼树的图文解析 3 . 哈夫曼树的基本操作 4 . 哈夫曼树的完整源码 转载请注明出处: http://www.cnblogs.com/skywang12345/ 更多内容: 数据结构与算法系列 目录 哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。 定义 :给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答。 (01) 路径和路径长度 定义 :在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 例子 :100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。 (02) 结点的权及带权路径长度 定义 :若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权

哈夫曼树

≯℡__Kan透↙ 提交于 2019-12-19 12:39:28
哈夫曼树(Huffman)树又称最优二叉树,是指对于一组带有确定权值的叶子结点所构造的具有带权路径长度最短的二叉树。从树中一个结点到另一个结点之间的分支构成了两结点之间的路径,路径上的分支个数称为路径长度。二叉树的路径长度是指由根结点到所有叶子结点的路径长度之和。如果二叉树中的叶子结点都有一定的权值,则可将这一概念拓展:设二叉树具有n个带权值的叶子结点,则从根结点到每一个叶子结点的路径长度与该叶子结点权值的乘积之和称为二叉树路径长度,记做: WPL=W1L1+W2L2+......+WnLn; 其中:n为二叉树中叶子结点的个数;Wk为第k个叶子的权值;Lk为第k个叶子结点的路径长度。 若给定n个权值,如何构造一棵具有n个给定权值叶子结点的二叉树,使得其带权路径长度WPL最小?哈夫曼根据"权值大的结点尽量靠近根"这一原则,给出了一个带有一般规律的算法,称为"哈夫曼"算法,哈夫曼算法如下: (1)根据给定n个权值{w1,w2,....,wn}构成n棵二叉树的集合F={T1,T2,.....,Tn};其中,每棵二叉树Ti(1<=i<=n)只有一个带权值wi的根结点,其左、右子树均为空。 (2)在F中选取两棵根结点权值最小的二叉树作为左、右子树来构造一棵新的二叉树,且置新的二叉树根结点权值为其左右子树根结点的权值之和。 (3)在F中删除这两棵树,同时将生成新的二叉树加入到F中。 (4)重复

哈夫曼树

孤街浪徒 提交于 2019-12-19 12:38:18
1、哈夫曼树的基本概念 ---- 哈夫曼(Huffman)树又称作最优二叉树,它是n个带权叶子结点构成的所有二叉树中,带权路径长度最小的二叉树。 ---- “路径”就是从树中的一个结点到另一个结点之间的分支构成的部分,而分支的数目就是路径长度。 ---- 树的路径长度:就是从树根到每一结点的路径长度之和。 ---- 考虑带权的结点,结点的带权路径长度为:从该结点到树根之间的路径长度与结点上权的乘积。 ---- 树的带权路径长度WPL(weighted path length):树中所有叶子结点的带权路径长度之和。 假设一个有n个带权叶子结点的二叉树,其权值为{w1,w2,....wn},每个叶子结点带权wk,每个叶子的路径长度为 lk,则从根结点 到各个叶子结点的路径长度与相应的权值的乘积之和叫做二叉树的带权路径长度,通常记作: 如下图所示是由4个叶子结点构成的三棵不同的带权二叉树: 三棵二叉树的带权路径长度为: (a)WPL=9x2+4x2+5x2+2x2=18+8+10+4=40 (b)WPL=9x1+5x2+4x3+2x3=9+10+12+6=37 (c)WPL=4x1+2x2+5x3+9x3=4+4+15+27=50 其中(b)所示的二叉树的WPL最小,此树是哈夫曼树。由上图可知:由n个带权叶子结点所构成的二叉树中,满二叉树或完全二叉树 不一定是最优二叉树

哈夫曼树与哈弗曼编码

大城市里の小女人 提交于 2019-12-19 12:38:05
在这里主要回顾一下: 哈夫曼树 、 带权路径的计算 、 哈夫曼树的构造java实现 、 以及哈弗曼编码应用 相关定义: 哈夫曼树(Huffman tree): 又称最优二叉树,就是给定n个权值作为n个叶子结点,构造一棵二叉树, 若带权路径长度达到最小 ,则就称为哈夫曼树。 权值: 哈夫曼树的权值是自己定义的,他的物理意义表示数据出现的次数、频率。可以用树的每个结点数据域data存放一个特定的数表示它的值。 路径长度: 在一棵树中,从一个结点往下可以达到的孩子或子孙结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1,这有点像我们楼层的定义,一楼和二楼的楼层距离是1。 结点的带权路径长度为: 从根结点到该结点之间的 路径长度 与 该结点的权值 的 乘积 。 树中所有叶子节点的带权路径长度之和,WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln)。 图解: 哈夫曼树构造过程: 假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为: (1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点),按照权值排序; (2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和

哈夫曼树

断了今生、忘了曾经 提交于 2019-12-19 12:37:43
http://sjjg.js.zwu.edu.cn/SFXX/shu/shu4.6.2.html 1. 哈夫曼树的基本概念   哈夫曼树( Huffman )又称最优二叉树,是一类带权路径长度最短的树,有着广泛的应用。   在讨论哈夫曼树之前首先需要弄清楚关于路径和路径长度的概念。树中两个结点之间的路径由一个结点到另一结点的分支构成。两结点之间的路径长度是路径上分支的数目。树的路径长度是从根结点到每一个结点的路径长度之和。   设一棵二叉树有 n 个叶子结点,每个叶子结点拥有一个权值W 1 ,W 2 , ...... W n ,从根结点到每个叶子结点的路径长度分别为 L1 , L2......Ln ,那么树的带权路径长度为每个叶子的路径长度与该叶子权值乘积之各。通常记作 WPL = L k. W k 。为了直观其见,在图中把带权的叶子结点画成方形,其他非叶子结点仍为圆形。请看图 6.21 中的三棵二叉树以及它们的带权路径长。 (a) wpl=38 (b) wpl=49 (c) wpl=36 图 6.21 具有不同带权路径长度的二叉树 注意: 这三棵二叉树叶子结点数相同,它们的权值也相同,但是它们的 wpl 带权路径长各不相同。图 6.21(c)wpl 最小。它就是哈曼树,最优树。哈夫曼树是,在具有同一组权值的叶子结点的不同二叉树中,带权路径长度最短的树。也称最优树。 2.

哈夫曼树的建立

做~自己de王妃 提交于 2019-12-18 20:49:58
哈夫曼树,又叫赫夫曼树什么其他的了,这个东西吧,主要用来对一组数据的出现概率来进行建数,这样可以使得概率大的放在前面,就使得调用简单一些,而概率小的就放到后面,其实就是对数据的一个优化处理了。 接下来我们就来看看怎么建树吧: #include<stdio.h> #include<stdlib.h> #include<string.h> /为什么会多这么一个string呢,这是因为后面会用到一个strcpy(复制)函数 typedef struct{ int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; /哈夫曼树的结构体定义,权重,父节点,左右孩子结点 typedef char **HuffmanCode; /这个是我们的哈夫曼编码的格式转换 一:建树 通过上表可知,首先我们对数据编号,并令其 parent ,lchild 和 rchild 初始化为 0,接下来我们通过每次选出最小的两个数据然后对其父节点进行编号,并对新生成的父节点的相关信息进行编辑,也就是它的权重,左右孩子结点,接下来继续找最小的就好了,遍历完了之后就能得到右边的这个表了,接下来就是哈夫曼编码了 看下图 我们可以知道左边排0,右边排0,再想到我们上面的排序方式,可以知道我们需要从后面往前面进行逆向的编码,所以我们可以定义一个字符数组

学习日志: 哈夫曼树(最优二叉树)的构建, 压缩长度, 平均信息量(熵)及冗余的计算

随声附和 提交于 2019-12-10 23:05:33
import java . text . DecimalFormat ; import java . util . * ; //关于构建哈夫曼树及计算字符串压缩后平均长度, 平均信息量, 冗余 //测试程序 public class TreeTest { public static void main ( String [ ] args ) { try { //捕获可能出现的异常, 如空指针异常等 Tree tree = new Tree ( ) ; Scanner s = new Scanner ( System . in ) ; String input = s . nextLine ( ) ; List < Node > nodes = tree . getNodes ( input ) ; //System.out.println(nodes); //测试代码 //System.out.println(nodes.size()); //测试代码 Node root = tree . createTree ( nodes ) ; tree . setEncodeLength ( root ) ; //System.out.println(root.leftNode); //测试代码 //System.out.println(root.rightNode.hasLeftNode