Java数据结构——哈夫曼编码

哈夫曼编码:

在信息传输中,若按照ascii码进行表示,每一个码表示一个字符,总体上需要的码长较长

为了实现数据的压缩传输,利用数据出现的频率,进行哈夫曼编码,让出现频率高的字符编码长度较短,而出现频率低的字符编码长度较长,从而让总体码长较短

实现思路:

统计待传输信息中的各个字符出现次数,并以此作为树节点的权值,构建各个字符组成的哈夫曼树

显然各个字符节点都是叶子节点,从根节点出发,规定向左的路径编码0,向右的路径编码1,对于任意一个字符的哈夫曼编码,只需要连接根节点与该字符节点,并将路径上的编码合成一个大的编码即可

对于哈夫曼编码的生成,通过递归实现,分别向左、向右递归并让编码加上对应的路径码,直到找到叶子节点,将该叶子节点代表的字符和对应的编码存入hashmap中


代码实现:

节点类HuffmanCodingNode:

public class HuffmanCodingNode implements Comparable<HuffmanCodingNode> {
	public Character data;
	public int weight;
	public HuffmanCodingNode left;
	public HuffmanCodingNode right;

	public HuffmanCodingNode(Character data, int weight) {
		this.data = data;
		this.weight = weight;
	}

	@Override
	public String toString() {
		return "HuffmanCodingNode{" + "data=" + data + ", weight=" + weight + '}';
	}

	@Override
	public int compareTo(HuffmanCodingNode o) {
		return this.weight - o.weight;
	}
}

哈夫曼树类HuffmanCoding:

public class HuffmanCoding {
	public HuffmanCodingNode root;
	public Map<Character, String> huffmanCodes = new HashMap<>();

	public HuffmanCoding(String str) {
		List<HuffmanCodingNode> nodes = new ArrayList<>();
		Map<Character, Integer> counts = new HashMap<>();
		char[] strArray = str.toCharArray();
		Integer count;
		for (char c : strArray) {
			count = counts.get(c);
			if (count == null) {
				counts.put(c, 1);
			} else {
				counts.put(c, count + 1);
			}
		}
		for (Map.Entry<Character, Integer> entry : counts.entrySet()) {
			nodes.add(new HuffmanCodingNode(entry.getKey(), entry.getValue()));
		}
		while (nodes.size() > 1) {
			Collections.sort(nodes);
			HuffmanCodingNode leftNode = nodes.get(0);
			HuffmanCodingNode rightNode = nodes.get(1);
			HuffmanCodingNode parentNode = new HuffmanCodingNode(null, leftNode.weight + rightNode.weight);
			parentNode.left = leftNode;
			parentNode.right = rightNode;
			nodes.remove(leftNode);
			nodes.remove(rightNode);
			nodes.add(parentNode);
		}
		root = nodes.get(0);
	}

	//生成哈夫曼编码
	public void getHuffmanCodes() {
		getHuffmanCodes(root, "", new StringBuilder());
	}

	public void getHuffmanCodes(HuffmanCodingNode node, String code, StringBuilder stringBuilder) {
		StringBuilder newStringBuilder = new StringBuilder(stringBuilder);
		newStringBuilder.append(code);
		if (node != null) {
			if (node.data == null) {
				getHuffmanCodes(node.left, "0", newStringBuilder);
				getHuffmanCodes(node.right, "1", newStringBuilder);
			} else {
				huffmanCodes.put(node.data, newStringBuilder.toString());
			}
		}
	}
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值