生活随笔
收集整理的这篇文章主要介绍了
哈夫曼编码之大根堆小根堆揭西县
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
哈夫曼编码 根据数据出现的频率对数据进行编码,从而压缩原始数据。
例如对于一个文本文件,其中各种字符出现的次数如下:
a : 10 b : 20 c : 40 d : 80 可以将每种字符转换成二进制编码,例如将 a 转换为 00,b 转换为 01,c 转换为 10,d 转换为 11。这是最简单的一种编码方式,没有考虑各个字符的权值(出现频率)。而哈夫曼编码采用了贪心策略,使出现频率最高的字符的编码最短,从而保证整体的编码长度最短。
首先生成一颗哈夫曼树,每次生成过程中选取频率最少的两个节点,生成一个新节点作为它们的父节点,并且新节点的频率为两个节点的和。选取频率最少的原因是,生成过程使得先选取的节点位于树的更低层,那么需要的编码长度更长,频率更少可以使得总编码长度更少。
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;public class hufman {
private class Node implements Comparable<Node>{char ch;int frequency;boolean isleaf;Node left;Node right;public Node(char a,int f) {ch=a;frequency=f;isleaf=true;}public Node(Node left,Node right,int frequency) {this.left=left;this.right=right;this.frequency=frequency;}@Overridepublic int compareTo(Node o) {// TODO Auto-generated method stubreturn this.frequency-o.frequency;}
}public Map<Character,String> encode(Map<Character,Integer> frquencyChar){PriorityQueue<Node> p=new PriorityQueue();for(char c:frquencyChar.keySet()) {p.add(new Node(c,frquencyChar.get(c)));}while(p.size()!=1) {Node n1= p.poll();Node n2= p.poll();p.add(new Node(n1,n2,n1.frequency+n2.frequency));}return Encode(p.poll());}public Map<Character,String> Encode(Node root){Map<Character,String> m=new HashMap();Encode(root,"",m);return m;}public void Encode(Node node,String a,Map<Character,String> m) {while(node.isleaf) {m.put(node.ch, a);return;}Encode(node.left,a+"0",m);Encode(node.right,a+"1",m);}}
man.java
import java.util.HashMap;
import java.util.Map;public class Teat {public static void main(String[] args) {// TODO Auto-generated method stubMap <Character,Integer> frquencyChar=new HashMap();frquencyChar.put('a', 1);frquencyChar.put('c', 19);frquencyChar.put('2', 13);frquencyChar.put('5', 14);hufman a=new hufman();Map<Character,String> b=a.encode(frquencyChar);for(char m:b.keySet()) {System.out.println(m+b.get(m));}}}
这是一个大根堆,所以重写了Node 对象中的compareTo 函数, 继承 Comparable 接口, 首先将字符与权重加入一个map中,我理解的是构建小根堆,这样每次都是最小的现出来。相加构成节点这个样子。 重写了函数之后,compare这个函数我觉得是》0 就要交换,<0 不交换,this.fre-o.fre>0 说明后来者小,进行交换。
PriorityQueue <Integer> maxHeap = new PriorityQueue<Integer>( new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {// TODO Auto-generated method stubreturn o2.compareTo(o1);}});
还可以 通过这个样子重写进行大根堆 小根堆变换。 https://blog.csdn.net/liou825/article/details/21322403 https://blog.csdn.net/zcf1784266476/article/details/68961473
总结
以上是生活随笔 为你收集整理的哈夫曼编码之大根堆小根堆揭西县 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔 网站内容还不错,欢迎将生活随笔 推荐给好友。