Huffman编码树的Java实现

Huffman编码为字母分配编码,代码长度取决于对应的字母的相对使用频率或者“权”,因此它是一种变长编码。每个字母的Huffman编码是从称为Huffman编码树或简称Huffman树的满二叉树中得到。Huffman树中每个叶子结点对应一个字母,叶结点的权重就是它对应字母的出现频率。其目的在于按照最小外部权重建立一棵树。

首先,定义一个Huffman结点的接口,以反映Huffman树结点所应有的信息

package huffTree;

public interface HuffNode {
	//每个结点的权重
	public int weight();
	//是否是叶子结点
	public boolean isLeaf();
	//左子树
	public HuffNode left();
	//生成左子树
	public void setLeft(HuffNode hn);
	//该结点的右子树
	public HuffNode right();
	//生成该结点的右子树
	public void setRight(HuffNode hn);
}

定义一个元素和频率相对应的类

package huffTree;

public class FreqPair {
	private Object it;
	private int freq;
	public FreqPair(Object it,int freq)
	{
		this.it = it;
		this.freq = freq;
	}
	
	public int weight()
	{
		return freq;
	}
	
	Object val()
	{
		return it;
	}

}

因为叶子结点和内部结点包含不同的信息,所以可以分开实现它们

叶子结点

package huffTree;

public class LeafNode implements HuffNode {
	private FreqPair it;
	
	public LeafNode(Object obj,int freq)
	{
		it = new FreqPair(obj,freq);
	}
	
	FreqPair val()
	{
		return it;
	}
	
	@Override
	public int weight() {
		return it.weight();
	}
	
	@Override
	public boolean isLeaf() {
		return true;
	}

	@Override
	public HuffNode left() {
		return null;
	}

	@Override
	public void setLeft(HuffNode hn) {
		
	}

	@Override
	public HuffNode right() {
		return null;
	}

	@Override
	public void setRight(HuffNode hn) {
		
	}

}

内部结点实现

package huffTree;

public class IntlNode implements HuffNode {
	private HuffNode lc;
	private HuffNode rc;
	private int wgt;
	
	public IntlNode(HuffNode lc,HuffNode rc)
	{
		wgt = lc.weight() + rc.weight();
		this.lc = lc;
		this.rc = rc;
	}
	@Override
	public int weight() {
		return wgt;
	}

	@Override
	public boolean isLeaf() {
		return false;
	}

	@Override
	public HuffNode left() {
		return lc;
	}

	@Override
	public void setLeft(HuffNode hn) {
		lc = hn;
	}

	@Override
	public HuffNode right() {
		return rc;
	}

	@Override
	public void setRight(HuffNode hn) {
		rc = hn;
	}

}

声明Huffman类

package huffTree;

public class HuffTree {
	private HuffNode theRoot;
	
	public HuffTree(Object obj,int freq)
	{
		theRoot = new LeafNode(obj,freq);
	}
	
	public HuffTree(HuffTree lc,HuffTree rc)
	{
		theRoot = new IntlNode(lc.root(),rc.root());
	}
	 
	public HuffNode root()
	{
		return theRoot;
	}
	
	public int weight()
	{
		return theRoot.weight();
	}
}
因为在构建Huffman树的时候要排序,我们可以使用TreeSet的排序功能

首先定义一个比较器

package huffTree;

import java.util.Comparator;

public class comparator<HuffTree> implements Comparator<HuffTree> {

	@Override
	public int compare(HuffTree o1, HuffTree o2) {
		return ((huffTree.HuffTree) o1).weight() - ((huffTree.HuffTree) o2).weight() ;
	}

}

接着实现BuildHuffTree

package huffTree;

import java.util.TreeSet;

public class BuildHuffTree {
	public HuffTree buildTree(TreeSet<HuffTree> ts)
	{
		HuffTree temp1,temp2,temp3 = null;
		for(;ts.size() >= 2;)
		{
			temp1 = ts.pollFirst();
			temp2 = ts.pollFirst();
			temp3 = new HuffTree(temp1,temp2);
			ts.add(temp3);
		}
		return temp3;
	}
}
初始时,所有元素都是叶结点,所以可以将所有的元素都加入到TreeSet集合类中,然后通过调用buildTree实现构建HuffMan树。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值