简单介绍;
哈弗曼编码(前缀编码):---哈夫曼树(最优二叉树)可以得到前缀编码,字符串的二进制编码,不是固定长度的,对于词频高的可以短编码,词频低的可以长编码,可以压缩数据,用于通信。前缀编码:更准确的译码,一个字符的编码不是另一个的前缀。利用二叉树来设计前缀编码,左0右1
算法思想:
目的是:得到一个带权值的wpl(带权路径长度最小),每次把权值最小的两棵树合并,直到形成一个二叉树
class Node implements Comparable<Node>{
int freq;
Integer ch;
Node left,right;
boolean isleaf;
public Node(Integer ch,int freq) {
this.freq = freq;
this.ch = ch;
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 o) {
// TODO Auto-generated method stub
return this.freq-o.freq;
}
}
class HuffmanTree{
//传一个map(字符,词频),得到编码
public Map<Integer,String> encode(Map<Integer,Integer> frequencyForChar){
//先放入优先队列进行处理,处理后得到哈夫曼树,但是还没有带上01编码,有一个函数处理,返回函数的值
PriorityQueue<Node> p = new PriorityQueue<Node>();
for (Integer c : frequencyForChar.keySet()) {
p.add(new Node(c,frequencyForChar.get(c)));
}
while(p.size()!=1) {
Node node1 = p.poll();
Node node2 = p.poll();
p.add(new Node(node1,node2,node1.freq+node2.freq));
}
return encodeReal(p.poll());
}
private Map<Integer, String> encodeReal(Node root) {
// TODO Auto-generated method stub
//盛放字符所对应的编码
Map<Integer,String> encodingForChar = new HashMap<>();
//具体编码用函数实现,传入map实现回调
encodeChar(root,"",encodingForChar);
return encodingForChar;
}
private void encodeChar(Node root, String encoding,
Map<Integer, String> encodingForChar) {
// TODO Auto-generated method stub
if(root.isleaf) {
encodingForChar.put(root.ch,encoding);
return;
}
encodeChar(root.left, encoding+"0", encodingForChar);
encodeChar(root.right, encoding+"1", encodingForChar);
}
}
public class Main {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < n; i++) {
int count = in.nextInt();
map.put(count, count);
}
HuffmanTree ht = new HuffmanTree();
Map<Integer,String> encode = ht.encode(map);
for (Entry<Integer, String> s : encode.entrySet()) {
System.out.println(s.getKey()+":"+s.getValue());
}
in.close();
}
}