Huffman编码树的Java实现

来源:互联网 发布:刀哥swift微博源码 编辑:程序博客网 时间:2024/06/03 00:08

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;}@Overridepublic int weight() {return it.weight();}@Overridepublic boolean isLeaf() {return true;}@Overridepublic HuffNode left() {return null;}@Overridepublic void setLeft(HuffNode hn) {}@Overridepublic HuffNode right() {return null;}@Overridepublic 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;}@Overridepublic int weight() {return wgt;}@Overridepublic boolean isLeaf() {return false;}@Overridepublic HuffNode left() {return lc;}@Overridepublic void setLeft(HuffNode hn) {lc = hn;}@Overridepublic HuffNode right() {return rc;}@Overridepublic 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> {@Overridepublic 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树。


原创粉丝点击