哈夫曼树+哈夫曼编码

前天acm实验课,老师教了几种排序,抓的一套题上有一个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这里我就结合课本,写一篇关于哈夫曼树的博客。

哈夫曼树的介绍

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*20 + 2*50 + 2*100 = 360  右边的树WPL=350

左边的树WPL > 右边的树的WPL。你也可以计算除上面两种示例之外的情况,但实际上右边的树就是{10,20,50,100}对应的哈夫曼树。至此,应该堆哈夫曼树的概念有了一定的了解了,下面看看如何去构造一棵哈夫曼树。

哈夫曼树的图文解析

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,哈夫曼树的构造规则为:

1. 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);  2. 在森林中选出根结点的权值最小的两棵树进行合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;  3. 从森林中删除选取的两棵树,并将新树加入森林;  4. 重复(02)、(03)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

以{5,6,7,8,15}为例,来构造一棵哈夫曼树。

第1步:创建森林,森林包括5棵树,这5棵树的权值分别是5,6,7,8,15。  第2步:在森林中,选择根节点权值最小的两棵树(5和6)来进行合并,将它们作为一颗新树的左右孩子(谁左谁右无关紧要,这里,我们选择较小的作为左孩子),并且新树的权值是左右孩子的权值之和。即,新树的权值是11。 然后,将"树5"和"树6"从森林中删除,并将新的树(树11)添加到森林中。  第3步:在森林中,选择根节点权值最小的两棵树(7和8)来进行合并。得到的新树的权值是15。 然后,将"树7"和"树8"从森林中删除,并将新的树(树15)添加到森林中。  第4步:在森林中,选择根节点权值最小的两棵树(11和15)来进行合并。得到的新树的权值是26。 然后,将"树11"和"树15"从森林中删除,并将新的树(树26)添加到森林中。  第5步:在森林中,选择根节点权值最小的两棵树(15和26)来进行合并。得到的新树的权值是41。 然后,将"树15"和"树26"从森林中删除,并将新的树(树41)添加到森林中。  此时,森林中只有一棵树(树41)。这棵树就是我们需要的哈夫曼树!

原文地址:https://www.cnblogs.com/wkfvawl/p/9783271.html

时间: 2024-10-09 19:35:37

哈夫曼树+哈夫曼编码的相关文章

《大话数据结构》笔记(6-3)--树:赫夫曼树

代码实现: 第六章    树:赫夫曼树 赫夫曼树定义与原理 从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径长度. 树的路径长度就是从树根到每一结点的路径长度之和. 对于带权的结点,结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积. 树的带权路径长度为树中所有叶子结点的带权路径长度之和. 假设有n个权值{w1, w2, ..., wn},构造一棵有n个叶子结点的二叉树,每个叶子结点带权wk ,每个叶子的路径长度为lk,则其中带权路径长度WPL最

数据结构&&哈弗曼树和哈弗曼编码

1.什么是哈夫曼树和哈弗曼编码 大家来看这样一道面试题(题目来自于<程序员面试宝典>).用二进制来编码字符串"abcdabaa",需要能够根据编码,解码回原来的字符串,最少需要多长的二进制字符串? A.12 B.14 C.18 D.24 解析:典型的哈弗曼编码问题:字符串"abcdabaa"有4个a.2个b.1个c.1个d.构造哈弗曼树如下图所示(图好丑).a编码0(1位),b编码10(2位),d编码111(3位).二进制字符串的总长度为1*4+2*2+

《数据结构复习笔记》--哈夫曼树,哈夫曼编码

先来了解一下哈夫曼树. 带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值 wk,从根结点到每个叶子结点的长度为 lk,则每个叶子结点的带权路径长度之和就是: 最优二叉树或哈夫曼树: WPL最小的二叉树. [例]有五个叶子结点,它们的权值为{1,2,3,4,5},用此权值序列可以构造出形状不同的多个二叉树. 其中结果wpl最小值的是:33=(1+2)*3+(3)*2+(4+5)*2: 哈夫曼树的构造: 每次把权值最小的两棵二叉树合并, 代码: typedef struct Tr

赫夫曼树的构建、编码、译码解析

当你開始看这篇博文的时候.我相信你对树及二叉树的基本概念已有所了解.我在这里就不再赘述. 我们主要对赫 夫曼树的特点.构建.编码.译码做一个具体的介绍,并附有代码,全部函数代码都通过了測试.我不保证全部代码是最优的(毕竟是我一个人苦思冥想出来的,我相信在大家的集思广益之下还有优化的空间),但我保证全部代码是正确的. 一.赫夫曼树的特点 赫夫曼树又称作最优二叉树,是一类带权路径长度最短的树. 首先给出路径和路径长度的概念.从树中一个节点到 还有一个节点之间的分支构成这两个节点之间的路径.路径上的分

《数据结构复习笔记》--二叉搜索树

二叉搜索树:维基百科:click here 二叉查找树(Binary Search Tree),也称二叉搜索树.有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值: 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 任意节点的左.右子树也分别为二叉查找树. 没有键值相等的节点(no duplicate nodes

《数据结构复习笔记》--堆

把堆的相关知识在复习一下.加深理解 堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前, 先来了解一下二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示

数据结构复习笔记--数组

最后还是决定在未来的道路上走向软件开发者这条路,从现在重新复习数据结构和算法. 关于数组有几个比较有意思的特点. 1.对于数组 int List[3],编译器将List[i]解释为指向一个地址为List + i*sizeof(int)的整数的指针. 对于int * List, int *List2[5],两个都是指向int 类型的变量,但是编译器会为后者分配五个整数存储空间. List2实际是上指向List2[0],List2 + i 实际上是&List2[i].在C语言中是不需要加上偏移量的.

《大话数据结构》笔记(6-1)--树:树

代码实现: https://github.com/Lyu0709/data-structure/blob/master/src/com/coding/basic/tree/Tree.java 第六章    树 树的定义 树的结点包含一个数据元素及若干指向其子树的分支. 结点拥有的子树数称为结点的度(degree). 度为0的结点称为叶结点(Leaf)或终端结点:度不为0的结点称为非终端结点或分支结点. 除根结点之外,分支结点也称为内部结点. 树的度是树内各结点的度的最大值. 结点的子树的根称为该

《大话数据结构》笔记(6-2)--树:二叉树

代码实现: 第六章    树:二叉树 定义 特点 二叉树的五种基本形态: 1. 空二叉树 2. 只有一个根结点 3. 根结点只有左子树 4. 根结点只有右子树 5. 根结点基友左子树又有右子树 特殊二叉树 斜树 所有结点都只有左子树的二叉树叫做左斜树.所有结点都只有右子树的二叉树叫做右斜树. 这两者统称为斜树. 斜树有很明显的特点,就是每一层都只有一个结点,结点的个数与二叉树的深度相同. 其实线性表结构可以理解为树的一种极其特殊的表现形式. 满二叉树 在一棵二叉树中,如果所有分支结点都存在左子树