java实现哈夫曼编码(优先队列)

简单介绍;

哈弗曼编码(前缀编码):---哈夫曼树(最优二叉树)可以得到前缀编码,字符串的二进制编码,不是固定长度的,对于词频高的可以短编码,词频低的可以长编码,可以压缩数据,用于通信。前缀编码:更准确的译码,一个字符的编码不是另一个的前缀。利用二叉树来设计前缀编码,左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();
    	
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章