一、哈夫曼树简介

1、构建哈夫曼树

计算每个字符出现的概率,将这个概率做为权值之比。

利用这些带权值的字符构建出哈夫曼树。

具体构建步骤:

① 首先以每个带权重的字符作为根结点,组成森林,每个结点上存储相应的权值。

② 在森林中选取权值最小的两个树作为一棵新树的左右子树,新树的权值等于左右子树权值之和。

③ 从森林中剔除之前的两棵树,并将新的树加入到森林中。

④ 一直重复2、3步骤,直到森林中只剩下一棵树就是哈夫曼树

2、哈夫曼编码

哈夫曼编码是现代压缩算法的基础。

如果要传输字符串ABC直接用ASCII码着实有点冗长。而且出于对方要能解码,可用下图方式编码:

       这样其实也有点浪费。哈夫曼编码本质就是利用将出现频率最小的字符编码为最长的二进制数,而出现频率较高的字符就编码为较短的二进制数,这样又节约了很多空间。

哈夫曼编码其实就是在哈夫曼树的基础上,规定left为0,right为0。最后对应元素的哈夫曼编码就是从根结点出发到相应叶子结点的数字组合

3、哈夫曼树总结

n个带权重的字符构建出来的哈夫曼树有n个叶子结点。换言之,之前的n个字符最后在哈夫曼树的位置都是叶子结点。因此注定每个字符的哈夫曼编码都不可能是其他字符编码的前缀。

哈夫曼树是带权路径长度最短的树,

二、哈夫曼树实现

1、分析

哈夫曼树的实现需要从森林中取出权值最小的两棵树,那这个完全可以用优先队列实现或者最小堆也是一样。jdk源码的优先队列底层突然发现用的是最小堆,比较的时候需要注意!

2、实现

 public class HuffmanTree<E> {private int size = 0;private Node<E> root;private PriorityQueue<Node<E>> forest;private E nodeName;/*** 给生成的结点命名** @param nodeName 多余结点的名字*/public HuffmanTree(E nodeName) {this.nodeName = nodeName;}public HuffmanTree() {this(null);}private static class Node<E> implements Comparable {int weight;E element;Node<E> parent;Node<E> left;Node<E> right;public Node(int weight, E element, Node<E> parent) {this.weight = weight;this.element = element;this.parent = parent;}@Overridepublic int compareTo(Object o) {return this.weight - ((Node<E>) o).weight;}}/*** 根据传入的HashMap生成森林*/public void generateForest(HashMap<E, Integer> map) {forest = new PriorityQueue<>();Set<E> sets = map.keySet();for (E e : sets) {forest.offer(new Node<>(map.get(e), e, null));}}public void doHuffmanTree() {if (root == null)root = new Node<E>(0, null, null);this.size = (forest.size() << 1) - 1;while (forest.size() != 1) {Node<E> left = forest.remove();Node<E> right = forest.remove();if (left == null || right == null)return;Node<E> newNode = new Node<>(left.weight + right.weight, nodeName, null);newNode.left = left;newNode.right = right;root = newNode;forest.offer(newNode);}}/*** 哈夫曼树中序遍历*/public void traversal() {inOrderTraversal(root);}private void inOrderTraversal(Node<E> node) {if (node == null)return;inOrderTraversal(node.left);System.out.print(node.element + " ");inOrderTraversal(node.right);}public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("B", 3);map.put("C", 8);map.put("D", 6);map.put("A", 1);map.put("E", 2);HuffmanTree<String> huffmanTree = new HuffmanTree<>("tempNode");huffmanTree.generateForest(map);huffmanTree.doHuffmanTree();System.out.println(huffmanTree.size);huffmanTree.traversal();}}

哈夫曼树(HuffmanTree)相关推荐

  1. 树:哈夫曼树和哈夫曼编码的详细介绍以及代码实现

    闲扯前言 哈夫曼编码的代码实现对于初学数据结构的同学可能会有些困难,没有必要灰心,其实没啥,学习就犹如攀登一座又一座的山峰,每当我们攻克一个难点后,回首来看,也不过如此嘛.我们要做的就是不断的去攀越学 ...

  2. 数据结构哈夫曼树(C语言版)

    文章目录 一. 问题 需求分析 代码分析 结构体定义使用 建立哈夫曼树,首先需要找到两个权值最小的两个叶子结点,然后建树 哈夫曼编码(我采用的是从叶子结点-->根节点,所以实际是反过来的) 使用 ...

  3. 简单的哈夫曼树程序实现

    //因时间原因程序较混乱,有些结构还可优化,有些函数借鉴其他大佬居多,算半原创吧/ /* 题目要求 ::::: 哈夫曼树 (10分) 编写一个哈夫曼编码译码程序.针对一段文本,根据文本中字符出现频率构 ...

  4. 哈夫曼树实现文件的压缩与解压缩

    利用哈夫曼树实现文件的压缩与解压缩 压缩: 1.统计出文件中相同字符出现的次数 2.获取哈夫曼编码 次数作为权值构建哈夫曼树 3.重新编码,写回压缩文件 保存头文件: 源文件后缀 编码信息的行数 每个 ...

  5. 赫夫曼树、赫夫曼编码

    基本介绍 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为赫夫曼树(HuffmanTree). 赫夫曼树是带权路径长度最短的树, ...

  6. 哈夫曼树(最优二叉树)、哈夫曼编码

    在此祝大家新年快乐,新的一年守住头发,不断进步! 哈夫曼树 一.哈夫曼树基本概念 二.哈夫曼树的构造算法 三.哈夫曼构造算法的实现 四.哈夫曼编码 五.哈夫曼编码的算法实现 一.哈夫曼树基本概念 (1 ...

  7. 种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林

    虽然今天不是植树节,但是我今天想种树. 文章目录 树,什么是树? 二叉树 定义 二叉树的创建 二叉树的前中后序遍历 前序遍历: 中序遍历 后序遍历 已知前序.中序遍历结果,还原二叉树 已知后序.中序遍 ...

  8. 数据结构与算法(赫夫曼树,赫夫曼编码)

    赫夫曼树 基本介绍: (1)给定n个权值作为n给叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树(HuffmanTree),还有的树翻译为霍夫 ...

  9. 哈夫曼树实现文件压缩

    最近在学了哈夫曼树之后,作为练习,写了一个文件压缩的小项目: 在这里和大家分享一下: 主要实现思路: 利用哈夫曼树的特性对字符进行哈夫曼编码,其中运用到了最小堆:利用最小堆的特性,找出构造哈夫曼树的结 ...

最新文章

  1. java post 打开新页面_JAVA后台POST/GET访问方法
  2. 多个vue项目合并成一个_集美们,快看如何一步将多个PDF合并成一个PDF
  3. Coursera自动驾驶课程第5讲:Vehicle Dynamic Modeling
  4. 鱼c论坛python课后作业_三日速成python?打工人,小心钱包,别当韭菜
  5. SpringMVC注解@RequestParam全面解析____ 注解@RequestParam如何使用加与不加的区别
  6. 第十届蓝桥杯大赛青少年创意编程C++组省赛 第1题 水下探测器
  7. c语言第一章节测试,计算机二级C语言教程章节测试:字符串
  8. 图形推理1000题及答案解析_判断推理图形推理——区分旋转翻转
  9. 盘点国内外那些有野心的BI公司
  10. Ubuntu18.04忘记密码解决
  11. 毕业5年决定人的一生-- 大家千万不要错过这篇文章
  12. matplotlib画图去掉边缘空白
  13. 作为一个iOS攻城狮不得不了解的网络知识
  14. Xcode可以清理哪些缓存?
  15. [NLP]OpenNLP介绍
  16. java 根据指定链接生成二维码
  17. 18650锂电池知识全解析
  18. 印象笔记 linux 命令行,在Linux的命令行下使用Evernote的教程
  19. 黑马程序员-MyBatis 框架-最全入门笔记、阿伟看了都得说真大、真细、真全!!!
  20. Norton推出基于云查杀免费小工具Norton Power Eraser

热门文章

  1. 3、《Jmeter基础篇》 从此善用逻辑控制器(1)
  2. Charles对虚拟机操作
  3. 团队内部合作的几种模式
  4. 计算机期刊及会议投稿指南
  5. ONAP项目加入新成员推动业界发展和技术进步
  6. linux 使用jstack_技德发布JStack 2.0,在Linux系统中无缝运行移动应用
  7. 站在云MSP风口 融资1.7亿的Bespin Global要干什么?
  8. 死神激斗显示服务器列表,境界死神激斗出现黑屏问题怎么处理 处理方案一览...
  9. 绿色版mysql8.0安装
  10. 独立显卡和集成显卡的区别