树论之哈夫曼树

2023-11-24 06:08
文章标签 哈夫曼 树论

本文主要是介绍树论之哈夫曼树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

树论之哈夫曼树

给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

哈夫曼树构建

  • 哈夫曼树的节点都是叶子节点
  • 根据哈夫曼树的特点,构建树最好的选择当然是从底层开始。
  • 从底层开始构建时应该选择权重最小的2个值开始构建

哈夫曼树的用途

  • 哈夫曼编码是最优前缀码 因此可用于加密解密
  • 文件压缩解压

代码再现

public class HuffmanTree {List<TreeNode> leafs;Map<Character,Integer> weights;TreeNode rootNode;Map<Character,String> codeMap;Map<String,Character> decodeMap;private HuffmanTree(Map<Character,Integer> weights) {this.weights = weights;leafs = new ArrayList<>();codeMap = new HashMap<>();decodeMap = new HashMap<>();initTree();}public void initTree(){PriorityQueue<TreeNode> queue = new PriorityQueue();Character[] keys =weights.keySet().toArray(new Character[0]);weights.keySet().toArray(keys);for(Character chr:keys){TreeNode treeNode = new TreeNode(chr.toString(),weights.get(chr).intValue());queue.add(treeNode);leafs.add(treeNode);}for(int n=1;n <= keys.length-1;n++) {TreeNode left = queue.poll();TreeNode right = queue.poll();TreeNode newNode = new TreeNode(left.chars+right.chars,left.freq+right.freq);newNode.left = left ; newNode.right = right;left.parent = newNode;right.parent = newNode;queue.add(newNode);}rootNode = queue.poll();}public String encode(String str) {StringBuilder sbr = new StringBuilder();for(Character c : str.toCharArray()) {sbr.append(codeMap.get(c));}System.out.println(str+"=="+sbr.toString());return sbr.toString();}public void decode(String str) {StringBuilder sbr = new StringBuilder();StringBuilder temp = new StringBuilder();for(Character c : str.toCharArray()) {temp.append(c);if(decodeMap.containsKey(temp.toString())) {sbr.append(decodeMap.get(temp.toString()));temp = new StringBuilder();}}System.out.println(str+"=="+sbr.toString());}public void codes(){for(int i=0;i<leafs.size();i++) {TreeNode current = leafs.get(i);Character c = current.chars.charAt(0);String codes = "";while(current.parent!=null) {if(current == current.parent.left) {codes="0"+codes;}else {codes="1"+codes;}current = current.parent;}System.out.println(c+"::"+codes);codeMap.put(c, codes);decodeMap.put(codes, c);}}public static void main(String[] args) {Map<Character,Integer> weights =new HashMap<Character,Integer>();weights.put('a', 3);weights.put('b', 24);weights.put('c', 6);weights.put('d', 20);weights.put('e', 34);weights.put('f', 4);weights.put('g', 12);HuffmanTree huffman = new HuffmanTree(weights);huffman.codes();huffman.decode(huffman.encode("afeddacbad"));}static class TreeNode implements Comparable<TreeNode>{private String chars;//节点字符private int freq;//权重private TreeNode left;//左节点private TreeNode right;//右节点private TreeNode parent;//父节点private TreeNode(String chars,int freq) {this.chars = chars;this.freq = freq;}@Overridepublic int compareTo(TreeNode o) {return this.freq-o.freq;}}
}

这篇关于树论之哈夫曼树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/421366

相关文章

数据结构-非线性结构-树形结构:有序树 ->二叉树 ->哈夫曼树 / 霍夫曼树(Huffman Tree)【根据所有叶子节点的权值构造出的 -> 带权值路径长度最短的二叉树,权值较大的结点离根较近】

哈夫曼树概念:给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。 哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 一、相关概念 二叉树:每个节点最多有2个子树的有序树,两个子树分别称为左子树、右子树。有序的意思是:树有左右之分,不能颠倒 叶子节点:一棵树当中没有子结点的结点称为叶子

哈夫曼树例子

五个字符:a,b,c,d,e,它们出现的的频率为8,14,10,4,18构造相应的哈夫曼树,求出每个字符的哈夫曼编码: 哈夫曼树:54/ \22 32/ \ / \c10 12 b14 e18/ \d4 a8哈夫曼编码:a:011 b:10 c:00 d:010 e:11

合并果子之哈夫曼树——优先队列解决哈夫曼

树-堆结构练习——合并果子之哈夫曼树 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit  Status Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆

九度OJ-1172-哈夫曼树

由于建立的哈夫曼树不唯一,所以机试多考察哈夫曼树的带权路径长度和,如此题。此问题最终转化为利用堆模拟建树过程,求出非叶节点的权值和(=该哈夫曼树的带权路径长度和)。(无需作出哈夫曼树的具体结构体)   收获如下:   ①关于哈夫曼树:该树非叶节点的权值和=该哈夫曼树的带权路径长度和   ②关于堆排序:堆排序建堆O(n*logn),初始堆完成后,每次重新调整只需O(logn)(树深),故是

最优二叉树(哈夫曼树)知识点

路径:在一棵树中从一个结点往下到孩子或孙子结点之间的通路 结点的路径长度:从根节点到该节点的路径上分支的数目 树的路径长度:树中每个结点的路径长度之和 结点的权:给树中的结点赋予一个某种含义的值,则该值为该节点的权 结点的带权路径长度:结点的路径长度乘以结点的权 树的带权路径长度(WPL):树中所有叶子结点的带权路径长度 (Weight Path Length)   最优二叉树(哈夫

【数据结构与算法】哈夫曼树,哈夫曼编码 详解

哈夫曼树的数据结构。 struct TreeNode {ElemType data;TreeNode *left, *right;};using HuffmanTree = TreeNode *; 结构体包含三个成员: data 是一个 ElemType 类型的变量,用于存储哈夫曼树节点的数据。left 是一个指向 TreeNode 类型的指针,用于指向哈夫曼树节点的左子节点。righ

使用Java实现哈夫曼编码

前言 哈夫曼编码是一种经典的无损数据压缩算法,它通过赋予出现频率较高的字符较短的编码,出现频率较低的字符较长的编码,从而实现压缩效果。这篇博客将详细讲解如何使用Java实现哈夫曼编码,包括哈夫曼编码的原理、具体实现步骤以及完整的代码示例。 哈夫曼编码原理 哈夫曼编码的基本原理可以概括为以下几个步骤: 统计字符频率:遍历输入数据,统计每个字符出现的频率。构建哈夫曼树:根据字符的频率构建一棵哈

C++哈夫曼树+哈夫曼编码的实现(双完整版)

注释详解哈夫曼Tree和哈夫曼Code 一、哈夫曼Tree二、哈夫曼Code   本文是根据B站视频👉青岛大学 - 王卓老师的数据结构来实现的,涉及到哈夫曼Tree 和 哈夫曼Code的C++版完整实现,若有不足欢迎大佬斧正-(/▽\) 一、哈夫曼Tree   具体理论请配合👉B站视频来学习,构造哈夫曼Tree主要的方法如下:   第一步:构造森林全是根   第二步:选用

成长路上的小程序之—— 哈夫曼编码、译码

这是大二数据结构第七次上机老师布置的任务:实现文件操作,对文件进行哈夫曼编码、译码 之所以为此写一篇博客,是因为自认为这个程序对我的意义比较重大。 我是以一个课程设计的要求来写的,大一结束的暑假也做了一个课程设计:《学生通讯录》 但是太水了,完全没有难度。 这个相对来说则有一些巧妙的思想,完全是我独立完成的! 哈哈哈 代码如下: #include <cstdlib>#inclu

信息学奥赛初赛天天练-23-CSP-J2023基础题-指针、链表、哈夫曼树与哈夫曼编码的实战应用与技巧大揭秘

PDF文档公众号回复关键字:20240608 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 4 假设有一个链表的节点定义如下: struct Node {int data; Node* next;}; 现在有一个指向链表头部的指针:Node* head。如果想要在链表中插入一个新节点,其成员data的值为42,并使新节点成为链表的第一个节点,下面哪个