Java 用PriorityQueue 实现Huffman Code

本文详细介绍了霍夫曼编码的实现原理及其在数据压缩领域的应用。通过使用霍夫曼树,文章展示了如何为不同字符分配最优前缀编码,以达到最小化编码长度的目的。并提供了完整的Java代码实现,包括构建霍夫曼树、生成编码映射以及从比特串解码回原始文本的过程。
https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/

character   Frequency
    a            5
    b           9
    c           12
    d           13
    e           16
    f           45

* HuffmanNode.java

package org.geeksforgeeks.www.huffman;

public class HuffmanNode {
	protected int data;
	protected char c;

	protected HuffmanNode left;
	protected HuffmanNode right;

	public HuffmanNode(char c, int freq) {
		this.c = c;
		this.data = freq;
		this.left = null;
		this.right = null;
	}

	public int getData() {
		return this.data;
	}

	public char getChar() {
		return this.c;
	}

	public void setLeft(HuffmanNode left) {
		this.left = left;
	}

	public void setRight(HuffmanNode right) {
		this.right = right;
	}

	public boolean isLeaf() {
		return this.left == null && this.right == null;
	}

	public static String decodeFromBitString(HuffmanNode root, String bs) {
		String text = "";
		HuffmanNode node = root;

		for (int i = 0; i < bs.length(); i++) {
			if (node.isLeaf()) {
				text += node.c;
				node = root; // rewind
			}		
			char c = bs.charAt(i);
			if (c == '0') {
				node = node.left;
			} else if (c == '1') {
				node = node.right;
			} else {
				throw new IllegalArgumentException("must be 0 or 1");
			}
		}
	    if (node.isLeaf()) {
           text += node.c;
	    }
		return text;
	}
}

* Huffman.java

package org.geeksforgeeks.www.huffman;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;

/**
 * https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/
 * @author Mch
 */
public class Huffman {
	protected HuffmanNode root = null;
	private int length = 0;
	
	public Huffman(char[] charArray, int[] charFreq) throws IllegalArgumentException {
		
		int n = charArray.length;
		if (n != charFreq.length) {
			throw new IllegalArgumentException("charArray.length != charFreq.length");
		}
		PriorityQueue<HuffmanNode> q = new PriorityQueue<HuffmanNode>(n,
				new Comparator<HuffmanNode>() {
					@Override
					public int compare(HuffmanNode o1, HuffmanNode o2) {
						return o1.data  - o2.data;
					}
				});
		
		for (int i = 0; i < n; i++) {
			q.add( new HuffmanNode(charArray[i], charFreq[i]) );
		}
		
		while (q.size() > 1) {
			HuffmanNode x = q.poll(), y = q.poll();
			HuffmanNode f = new HuffmanNode('-', x.getData() + y.getData());
			f.setLeft(x);
			f.setRight(y);
			this.root = f;
			q.add(f);
		}
		this.length = n;
	}
	
	public int size() {return this.length;}
	
	public HashMap<String, String> getEncodeMap() {
		HashMap<String, String> pairs = new HashMap<String, String>(this.size());
		addPair(pairs, this.root, "");
		return pairs;
	}
	
	private static void addPair(HashMap<String, String> pairs, HuffmanNode root, String s) {
		if (root.left == null && root.right == null && Character.isLetter(root.c)) {
			pairs.put(root.c + "", s);
			return;
		}
		addPair(pairs, root.left, s + "0");
		addPair(pairs, root.right, s + "1");
	}
	
	public String decodeFromBitString(String bs) {
		return HuffmanNode.decodeFromBitString(this.root, bs);
	}
	
	public static void main(String []args) {

		char[] charArray = {'a', 'b', 'c', 'd', 'e', 'f'};
		int[] charFreq = {5, 9, 12, 13, 16, 45};
		try {
			Huffman tree = new Huffman(charArray, charFreq);
			
			HashMap<String, String> map = tree.getEncodeMap();
			for (Entry<String, String> entry : map.entrySet()) {
				System.out.println(entry.getKey() + ": " + entry.getValue() );
			}
			
			String text = "cabaddfabdef", bs = "";
			for (int i = 0; i < text.length(); i++) {
				bs += map.get("" + text.charAt(i));
			}
			System.out.println(bs);
			
			System.out.println(tree.decodeFromBitString(bs));
			
		} catch (IllegalArgumentException e) {
			e.getMessage();
		}
		
	}
}

* test:

a: 1100

b: 1101

c: 100

d: 101

e: 111

f: 0

1001100110111001011010110011011011110

cabaddfabdef

参照:

https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fareast_mzh

打赏个金币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值