Huffman 编码Java实现(贪心算法)

Huffman 编码

问题分析

Java 代码实现

内含详细注释

/*
 * 若尘
 */
package huffmancode;

import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * 哈夫曼编码
 * @author ruochen
 * @version 1.0
 */
public class Test {

	/** 用来存放节点值 */
	private static LinkedList<HuffNode> huffList = new LinkedList<HuffNode>();
	
	public static void main(String[] args) {
		// 第一个输入元素个数
		// 然后换行输入 对应权值 元素
		/** 如 
		 * 5
		 * 10 a
		 * 6 b
		 * 4 c
		 * 19 d
		 * 1 e
		 * **/
		System.out.println("Please input: ");
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			huffList.add(new Test().new HuffNode(sc.nextInt(), sc.next()));
		}
		huffmanCode();
		decode(huffList.get(0), "");
	}
	
	class HuffNode implements Comparable<HuffNode> {
		/** 权值 */
		int value;
		String name;
		/** 左孩子节点 */
		HuffNode lChild = null;
		/** 右孩子节点 */
		HuffNode rChild = null;
		
		public HuffNode(int value, String name) {
			this.value = value;
			this.name = name;
		}
		
		public HuffNode(HuffNode lChild, HuffNode rChild) {
			this.lChild = lChild;
			this.rChild = rChild;
			// 权值之和,即合并两个叶子节点
			this.value = lChild.value + rChild.value;
		}
		
		/**
		 * 按照权值大小非递减序列
		 * @param o
		 * @return
		 */
		@Override
	    public int compareTo(HuffNode o) {
	    	if (this.value < o.value) {
	    		return -1;
	    	} else if (this.value == o.value) {
	    		return 0;
	    	} else {
	    		return 1;
	    	}
	    }
	}
	
	/**
	 * 哈夫曼编码
	 */
	public static void huffmanCode() {
		if (huffList.size() == 1) {
			return ;
		}
		while (huffList.size() > 1) {
			// 排序
			Collections.sort(huffList);
			// 将前两个节点进行合并
			HuffNode node = new Test().new HuffNode(huffList.get(0), huffList.get(1));
			// 删除前两个节点
			huffList.remove();
			huffList.remove();
			// 将新生成的节点添加到列表中
			huffList.add(node);
		}
		// 编码完成后,此时huffList中只剩一个根节点
	}
	

	/**
	 * 解码
	 * @param n
	 * @param code
	 */
	public static void decode(HuffNode n, String code) {
		if ((n.lChild == null) && (n.rChild == null)) {
			// 叶子节点, 此时输出其对应编码
			System.out.print(n.name + "--->" + code);
			System.out.println();
			return ;
		}
		// 遍历左子树
		decode(n.lChild, code + "0");
		// 遍历右子树
		decode(n.rChild, code + "1");
		return ;
	}
}

Please input: 
5
10 a
6 b
4 c
19 d
1 e
d--->0
a--->10
e--->1100
c--->1101
b--->111
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是哈夫曼编码贪心算法的伪代码和Java实现: 伪代码: 1. 初始化一个优先队列(最小堆)Q,将所有字符和它们的频率添加到队列中。 2. while(Q.size()>1) do: a. 从Q中删除两个频率最低的节点,将它们合并成一个新的节点。 b. 将新节点添加到Q中。 3. 根据生成的哈夫曼树,为每个字符生成哈夫曼编码Java实现: ``` import java.util.PriorityQueue; import java.util.Comparator; import java.util.HashMap; public class HuffmanCoding { // 定义内部节点类 private static class Node { char c; int freq; Node left; Node right; public Node(char c, int freq) { this.c = c; this.freq = freq; } } // 定义比较器,用于优先队列中节点的排序 private static class NodeComparator implements Comparator<Node> { public int compare(Node n1, Node n2) { return n1.freq - n2.freq; } } // 生成哈夫曼编码 public static HashMap<Character, String> generateHuffmanCode(String text) { // 统计字符频率 HashMap<Character, Integer> freqMap = new HashMap<>(); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); freqMap.put(c, freqMap.getOrDefault(c, 0) + 1); } // 构建哈夫曼树 PriorityQueue<Node> pq = new PriorityQueue<>(new NodeComparator()); for (char c : freqMap.keySet()) { pq.offer(new Node(c, freqMap.get(c))); } while (pq.size() > 1) { Node left = pq.poll(); Node right = pq.poll(); Node parent = new Node('\0', left.freq + right.freq); parent.left = left; parent.right = right; pq.offer(parent); } Node root = pq.poll(); // 生成哈夫曼编码 HashMap<Character, String> codeMap = new HashMap<>(); generateCode(root, new StringBuilder(), codeMap); return codeMap; } // 递归生成哈夫曼编码 private static void generateCode(Node node, StringBuilder prefix, HashMap<Character, String> codeMap) { if (node == null) { return; } if (node.left == null && node.right == null) { codeMap.put(node.c, prefix.toString()); } else { prefix.append('0'); generateCode(node.left, prefix, codeMap); prefix.deleteCharAt(prefix.length() - 1); prefix.append('1'); generateCode(node.right, prefix, codeMap); prefix.deleteCharAt(prefix.length() - 1); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

若尘

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值