思路:
  1. 构建小根堆
  2. 根据小根堆实现哈夫曼树
  3. 根据哈夫曼树对数据进行编码
代码实现如下:
/**
* @Author: DaleyZou
* @Description: 使用java实现一个哈夫曼编码的小程序
* @Date: Created in 19:45 2018-9-27
* @Modified By:
*/
public class HuffmanCode {
private class Node implements Comparable<Node>{
char ch; // 字符
int freq; // 权值
boolean isLeaf; // 是否是叶子节点
Node left, right; // 父节点的左节点和右节点 // 初始化一个带权值的叶子节点
public Node(char ch, int freq){
this.ch = ch;
this.freq = freq;
this.isLeaf = true;
} // 构建一个节点,带左右节点
public Node(Node left, Node right, int freq){
this.left = left;
this.right = right;
this.freq = freq;
this.isLeaf = false;
} @Override
public int compareTo(Node node) {
return this.freq - node.freq;
}
} // 构建一颗哈夫曼树
public Map<Character, String> encode(Map<Character, Integer> frequencyForChar){
PriorityQueue<Node> priorityQueue = new PriorityQueue<>();
for (Character ch : frequencyForChar.keySet()){
priorityQueue.add(new Node(ch,frequencyForChar.get(ch)));
}
while (priorityQueue.size() != 1){ // 构建小根堆
Node left = priorityQueue.poll();
Node right = priorityQueue.poll();
priorityQueue.add(new Node(left, right, left.freq + right.freq));
}
return encode(priorityQueue.poll());
} public Map<Character, String> encode(Node root){
HashMap<Character, String> hashMap = new HashMap<>();
encode(root, "", hashMap);
return hashMap;
} public void encode(Node root, String encoding, HashMap<Character,String> hashMap) {
if (root.isLeaf){ // 已经到叶子节点,递归结束
hashMap.put(root.ch, encoding);
return;
}
encode(root.left, encoding + "0" ,hashMap); // 编码左节点
encode(root.right, encoding + "1", hashMap); // 编码右节点
} // 测试结果是否正确
public static void main(String[] args){
Map<Character, Integer> frequencyForChar = new HashMap<>();
frequencyForChar.put('a', 10);
frequencyForChar.put('b', 20);
frequencyForChar.put('c', 40);
frequencyForChar.put('d', 80); HuffmanCode huffmanCode = new HuffmanCode();
Map<Character, String> encode = huffmanCode.encode(frequencyForChar);
for (Character ch : encode.keySet()){
System.out.println(ch + " : " + encode.get(ch));
}
} }

不使用优先级队列,自己手动实现小根堆

java使用优先级队列实现哈夫曼编码的更多相关文章

  1. java实现哈夫曼编码

    java实现哈夫曼编码 哈夫曼树   既然是学习哈夫曼编码,我们首先需要知道什么是哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫 ...

  2. Java实现哈夫曼编码和解码

    最近无意中想到关于api返回值加密的问题,譬如我们的api需要返回一些比较敏感或者重要不想让截获者得到的信息,像如果是做原创图文的,文章明文返回的话则有可能被抓包者窃取. 关于请求时加密的方式比较多, ...

  3. 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码

    20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...

  4. Java数据结构(十二)—— 霍夫曼树及霍夫曼编码

    霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...

  5. Java 树结构实际应用 二(哈夫曼树和哈夫曼编码)

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

  6. java 哈夫曼编码

    //哈夫曼树类 public class HaffmanTree { //最大权值 ; int nodeNum ; //叶子结点个数 public HaffmanTree(int n) { this. ...

  7. 04-树6. Huffman Codes--优先队列(堆)在哈夫曼树与哈夫曼编码上的应用

    题目来源:http://www.patest.cn/contests/mooc-ds/04-%E6%A0%916 In 1953, David A. Huffman published his pap ...

  8. 2018.2.14 Java中的哈夫曼编码

    概念 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造 ...

  9. 10: java数据结构和算法: 构建哈夫曼树, 获取哈夫曼编码, 使用哈夫曼编码原理对文件压缩和解压

    最终结果哈夫曼树,如图所示: 直接上代码: public class HuffmanCode { public static void main(String[] args) { //获取哈夫曼树并显 ...

随机推荐

  1. ArrayList代码分析

    集合算是java中最常用的部分了,阅读该部分jdk代码可以让我们更加清楚的了解其实现原理,在使用时也能心中有数,有利于写出高质量的代码. ArrayList 底层数组实现,初始长度10,超过长度后的自 ...

  2. 最新版本dede与discuz通过ucenter完美整合

    人合租虚拟主机.然后到相关的官方网站上面下载相关的程序,我下载的是DedeCmsV5.7-GBK+Discuz_X2_RC_SC_GBK+UCenter_1.6.0_SC_GBK这个程序组合.涉及到怎 ...

  3. pta5-9 Huffman Codes (30分)

    5-9 Huffman Codes   (30分) In 1953, David A. Huffman published his paper "A Method for the Const ...

  4. [巩固C#] 三、依赖注入是什么?

    阅读目录   接口 在说依赖注入之前,先了解下什么是接口. 我们在学编程的时候都知道,接口的相关规则:(来源百度百科) 1. 接口是一个引用类型,通过接口可以实现多重继承. 2. C#中接口的成员不能 ...

  5. C#天气预报程序

    首先要引用这个服务,http://www.webxml.com.cn/Webservices/WeatherWebService.asmx 出现对话框后,把中央气象的服务网址添加到里面 选择高级, 添 ...

  6. [转]c#匿名类

    首先让我们看一个例子, 假设我们并没有Person类, 并且我们关心的属性只有Name和Age. 下面的代码演示了我们如何在没有声明类型的情况下来构建一个对象的: 1: var tom = new { ...

  7. sass基础2

  8. sharepoint 2010 FieldLookup 的更新方法

    网上有,但是是错误的,稍微改一下,就可以了 第一个方法是要更新的item,其中 _fieldname 为要更新的lookup字段名字,_lookupValue为要更新的值. public void S ...

  9. Linux文件种类与扩展名

    一.文件种类 1)普通文件:ls -al第一个字符为[-]的 纯文本文件(ASCII) 二进制文件(binary):Linux中的可执行文件 数据格式文件(data):特定格式的文件,如:Linux登 ...

  10. VC++ MFC类库基础(55讲全)

    视频保存在播音员 网盘中内容简介: 本部分是您成为VC++软件工程师必备的阶段,如果您没有任何基础,学习C++能快速让您进入编程领域,建议配合书籍<C++入门经典> 关键词: VC++.V ...