JavaDemo——哈夫曼树

哈夫曼树构造过程:

列表里选出权重(或者出现次数)最低的两个,构成新树的左右子节点,新树父节点的权重为这两个子节点权重之和,将父节点(树)丢进列表里,重复操作,最后列表只剩一个,即哈夫曼树,所有子树的左边标0右边标1,节点的路径即哈夫曼编码;

Demo:

package testHuffman;

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

public class TestHuffman {

	public static void main(String[] args) {
		//优先级队列,自动排序
		PriorityQueue q = new PriorityQueue<>(new Comparator() {
			@Override
			public int compare(Node o1, Node o2) {
				if(o1.priority == o2.priority) {
					return o1.n-o2.n;
				}else {
					return o1.priority - o2.priority;
				}
			}
		});
		//初始数据
		Map map = new HashMap<>();
		map.put("A",5);
		map.put("B",24);
		map.put("C",7);
		map.put("D",17);
		map.put("E",34);
		map.put("F",5);
		map.put("G",13);
		//初始数据放入队列
		for(String v:map.keySet()) {
			System.out.println("放入队列:"+v+":"+map.get(v));
			q.add(new Node(map.get(v), v, null, null, 1));
		}
		System.out.println("=队列="+q);
		//构造哈夫曼树
		while(q.size()>1) {
			//取出优先级最小的两个
			Node n1 = q.poll();
			Node n2 = q.poll();
			System.out.println("取出:"+n1+n2);
			//构成新树
			Node newNode = new Node(n1.priority+n2.priority, "("+n1.name+""+n2.name+")", n1, n2, n1.n>n2.n?n1.n+1:n2.n+1);
			System.out.println("放入:"+newNode);
			//重新放入队列
			q.add(newNode);
			System.out.println("=队列="+q);
		}
		//取出哈夫曼树
		Node tree = q.poll();
		Map code_word = getTreeCode(tree);
		System.out.println(code_word);
		
		Map word_code = new HashMap<>();
		for(String code:code_word.keySet()) {
			word_code.put(code_word.get(code), code);
		}
		
		//测试
		String msg = "DCABCFDBFABEGA";
		for(String word:word_code.keySet()) {
			msg = msg.replaceAll(word, word_code.get(word));
		}
		System.out.println("编码:"+msg);
		
		String subCode = "";
		String reMsg = "";
		for(int i=0;i getTreeCode(Node root) {
		Map m = new HashMap<>();
		getRoad("",root,m);
		return m;
	}
	//构造路径,左0右1
	private static Map getRoad(String r, Node n, Map m) {
		if(n.left == null) {
			m.put(r, n.name);
		}else {
			getRoad(r+"0", n.left, m);
		}
		if(n.right == null) {
			m.put(r, n.name);
		}else {
			getRoad(r+"1", n.right, m);
		}
		return m;
	}
}
class Node{
	public int priority;
	public String name;
	public Node left;
	public Node right;
	public int n;//用于保存树层级,优先级相同按层级排序,每次选层级最小的两个

	public Node(int priority, String name, Node left, Node right, int n) {
		this.priority = priority;
		this.name = name;
		this.left = left;
		this.right = right;
		this.n = n;
	}

	@Override
	public String toString() {
		return "{"+priority + ":" + name+"}";
	}
}

结果:

JavaDemo——哈夫曼树_第1张图片

同组数据产生的哈夫曼树可能不唯一,存在超过两个相同权重节点的选择问题和左右子树的位置问题;

你可能感兴趣的:(JavaDemos,哈夫曼树)