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();
    	
	}
}

 

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