Huffman Tree

哈夫曼树;哈夫曼编码;最优二叉树
自底向上
变长编码;前缀编码;熵编码
数据无损压缩;最短编码;最佳判定树

一、基本概念

  1. Huffman Tree,又称最优二叉树,是带权路径长度最短的树,权值较大的结点离根较近。
    定义:给定n权值作为n个叶子节点,构造一棵二叉树,若这棵二叉树的带权路径长度达到最小,则称这样的二叉树为最优二叉树,也称为Huffman树。

  2. 路径:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路。

  3. 路径长度:通路中分支的数目称为路径长度。
    e.g. 若规定根结点的层数为111,则从根结点到第LLL层结点的路径长度为L−1L-1L−1。

  4. 结点的权:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

  5. 带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积。

  6. 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL
    WPL=∑i=1nwiliWPL = \sum_{i=1}^nw_il_i WPL=i=1∑n​wi​li​
    其中,nnn表示叶子结点的数目,wiw_iwi​和lil_ili​分别表示叶子结点kik_iki​的权值和树根结点到叶子结点kik_iki​之间的路径长度。

二、性质

  1. 不唯一(具有相同带权结点);左右子树可以互换;
  2. 带权值的节点都是叶子节点;
  3. Huffman tree中只有叶子节点和度为222的节点,没有度为1的节点;
  4. 一棵有nnn个叶子节点的Huffman tree共有2n−12n-12n−1个节点,需要n−1n-1n−1次合并。

三、构造

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

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

四、应用—— Huffman Coding

  1. 定义:Huffman Coding是一种用于无损数据压缩的熵编码(权编码)算法。由美国计算机科学家大卫·霍夫曼(David Albert Huffman)在1952年发明。
  2. 性质:
    • 变长码:频繁出现的字符分配更短的码;不频繁出现的字符分配更长的码
    • 前缀编码(立刻可解码性):任一字符的编码都不会是另一字符的(更长)编码的前缀
  3. 分类:
    • 静态编码:1)依据数据构建Huffman tree;2)依据Huffman tree为字符分配相应的码

      • 需要存储Huffman tree,方可解码
    • 动态编码:t+1t+1t+1个字符的编码依据前ttt个字符
      • 无需存储Huffman tree,即可解码
  4. 约定:
    • 将权值小的最为左节点,权值大的作为右节点
    • 左孩子编码为0,右孩子编码为1

五、实现

1. 基于python的实现

  1. 构建Huffman tree的节点对象(名称;权值;左子节点;右子节点)
  2. 根据构建的Huffman tree,并生成对应的码本
    • 初始化节点对象
    • 利用heapq构建最小堆
    • 每次取出堆中最小的两个值,构成新树,循环该过程,知道仅剩一个根节点
    • 迭代编码
      • 终止条件:到达叶子节点(判断Huffman tree是否只有一个节点的特殊情况)
      • 编码左节点(0)、右节点(1)
  3. 依据码本进行编码
  4. 依据码本进行解码
class HeapNode(object):left = Noneright = Noneitem = Noneweight = 0def __init__(self, i, w):self.item = iself.weight = wdef setChildren(self, ln, rn):self.left = lnself.right = rndef __repr__(self):return "%s - %s — %s _ %s" % (self.item, self.weight, self.left, self.right)def __lt__(self, other):return self.weight < other.weight
from itertools import groupby
from heapq import *class HuffmanTree():def __init__(self):self.codes = {}self.reverse_mapping = {}def build_huffman_tree(self, text):itemqueue =  [HeapNode(a,len(list(b))) for a,b in groupby(sorted(text))]heapify(itemqueue)while len(itemqueue) > 1:l = heappop(itemqueue)r = heappop(itemqueue)n = HeapNode(None, r.weight+l.weight)n.setChildren(l,r)heappush(itemqueue, n)return itemqueuedef make_codes(self, s, node):if node.item:if not s:self.codes[node.item] = "0"else:self.codes[node.item] = sself.reverse_mapping[s] = node.itemelse:self.make_codes(s+"0", node.left)self.make_codes(s+"1", node.right)def encoded_text(self, text):encoded_text = ""for character in text:encoded_text += self.codes[character]return encoded_textdef decode_text(self, encoded_text):current_code = ""decoded_text = ""for bit in encoded_text:current_code += bitif(current_code in self.reverse_mapping):character = self.reverse_mapping[current_code]decoded_text += charactercurrent_code = ""return decoded_text
if __name__ == '__main__':InputFile = "./sample.txt"with open(InputFile,'r') as f:text = f.read().rstrip()huff = HuffmanTree()huffTree = huff.build_huffman_tree(text)huff.make_codes('', huffTree[0])encode = huff.encoded_text("hello")text_ = huff.decode_text(encode)print (encode)print (text_)
1010000110110101101000
hello

Huffman Tree相关推荐

  1. java哈夫曼_用 JAVA 实现哈夫曼树(Huffman Tree)

    -1. 什么是树 树是一种 有层次关系的 数据结构.它由结点组成. 图一: 树的结点由 数据域 和 子结点域 组成.数据域 作为数据的容器:子结点域 存放 子结点 的地址.一个结点是它的子结点的父结点 ...

  2. 数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)

    哈夫曼树Huffman tree 又称最优完全二叉树,切入正题之前,先看几个定义 1.路径 Path 简单点讲,路径就是从一个指定节点走到另一个指定节点所经过的分支,比如下图中的红色分支(A-> ...

  3. Huffman Tree哈夫曼树权值路径长度WPL计算,binarytree ,Python

    Huffman Tree哈夫曼树(霍夫曼树.赫夫曼树)权值路径长度WPL计算,binarytree ,Python 计算定义:把构建成功的哈夫曼树的每一个边缘节点(叶子)值乘以该节点到根的路径长度,最 ...

  4. 哈夫曼树(Huffman Tree)

    定义 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数).树的路 ...

  5. 哈夫曼树(Huffman Tree),与哈夫曼编码

    目录 一.哈夫曼树 1.什么是哈夫曼树? 2.哈夫曼树关键字说明 3.用代码实现哈夫曼树思路分析 4.代码实现 二.哈夫曼编码 1.哈夫曼编码基本介绍 2.原理剖析 3.代码实现 一.哈夫曼树 1.什 ...

  6. 【数据结构与算法】-哈夫曼树(Huffman Tree)与哈夫曼编码

    超详细讲解哈夫曼树(Huffman Tree)以及哈夫曼编码的构造原理.方法,并用代码实现. 1哈夫曼树基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径. 结点的路径长度:两 ...

  7. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  8. 哈夫曼树(Huffman Tree)及哈夫曼编码(Huffman Coding)

    目录 一.Huffman树(最优二叉树) 1.定义 2.构造 构造哈夫曼树的算法 哈夫曼树特点 二.Huffman编码 一.Huffman树(最优二叉树) 1.定义 树的带权路径长度,就是树中所有的叶 ...

  9. Huffman Tree哈夫曼树的最小堆实现

    带权路径长度WPL:从根结点到各个叶子结点的路径长度和相应叶子结点权值的乘积之和 哈夫曼树:带权路径长度最小的二叉树(最优二叉树) -没有度为1的结点,有n个叶子结点的哈夫曼树共有2n-1个结点 -任 ...

最新文章

  1. 刷题:二叉树的非递归遍历方式
  2. SVG-不是图片的图片
  3. python刷题技巧_【python刷题】分治法
  4. MySQL应用安装_mysql安装和应用
  5. 聊聊ExecutorService的监控
  6. OpenStack Glance简介
  7. 高级PHP应用程序漏洞审核技术
  8. .net中三种Timer使用总结
  9. Tiny4412 使用superboot安装启动安卓/Linux/UbuntuCore系统, 使用SD-Flasher烧写
  10. Java 他们每人单独过桥的时间是_java实现 n人过桥问题
  11. 明源云客微信抢房技巧_明源演示 - 微信抢房_软件抢房_网上选房_手机抢房_代抢房 - 爱抢房...
  12. 电能质量监测装置及系统
  13. 前端背景图放置_CSS 背景图片排版
  14. 中国省份毗邻关系JSON数据[相邻省份][所辖市级信息][行政区划]
  15. 如何复制网页上的任何内容(比如百度文库)
  16. linux 非root 安装ImageMagick 以及python调用ImageMagick将图片生成gif案例
  17. QGIS基本功 | 16 要素渲染——地理数据可视化之道
  18. 纹理表示(Texture)
  19. JavaScript for impatient programmers
  20. 【Python从零到壹】input()函数

热门文章

  1. 开通公众号啦:java4all
  2. mysql:mysql的基本函数
  3. 单片机工程师如何继续提升自己?
  4. 岛屿最大面积 leetcode Java_LeetCode:岛屿的最大面积
  5. 艺术照片特效软件JixiPix Premium Pack Mac2020-10-15
  6. Powermill汽车件模具五轴数控CNC编程视频教程
  7. C++——计算x的n次幂
  8. 制作Windows PE启动镜像命令
  9. 麻将与扑克的文化内涵
  10. 如何通过美股交易软件完成开户?美股开户交易要点有哪些?