终于把哈夫曼树及哈弗曼编码弄好了~
哈夫曼树就是最优二叉树
和上次的搜索二叉树一样,哈夫曼树也有它特定的构造规则:
1.要把要存入哈夫曼树的数据分别创建一个树
2.把这些树按照大小顺序排序(在Java里面用优先队列PriorityQueue非常方便)
3.去两个最小的树,把他们合并在一块儿,并把合并后的树放回队列,如此递归往复……
4.把最后剩下的那个树设置为根节点。
这样,哈夫曼树就构造完成了~
检查方法就是把哈夫曼树的所有叶结点的编码都输出来,向左走编码为0,向右走编码为1(根据自己规定)
然后再根据编码把树画出来,检查~
首先是节点类:
/**
* 哈夫曼树节点类
* @author Micro
*
*/
public class HafNode implements Comparable<HafNode>{
private HafNode father;
private HafNode left;
private HafNode right;
private int num;
//重载构造器
public HafNode (int num) {
this.num=num;
}
public HafNode getFather() {
return father;
}
public void setFather(HafNode father) {
this.father = father;
}
public HafNode getLeft() {
return left;
}
public void setLeft(HafNode left) {
this.left = left;
}
public HafNode getRight() {
return right;
}
public void setRight(HafNode right) {
this.right = right;
}
public int getNum() {
return num;
}
public void setNum(int i) {
this.num = i;
}
//设置要比较的对象
@Override
public int compareTo(HafNode o) {
// 要比较的是数字大小
int P = o.getNum();
return num-P;
}
}
然后就是建树过程和输出哈弗曼编码:
import java.util.PriorityQueue;
/**
* 创建哈夫曼树并获得各叶节点的哈弗曼编码
*
* @author Micro
*
*/
public class HafTest {
// 创建根节点
private static HafNode root;
// 程序入口
public static void main(String[] args) {
// 创建一个数组
int[] a = { 1, 4, 3, 5, 6 ,4,6,7,6};
// 创建优先队列
PriorityQueue<HafNode> queue = new PriorityQueue<HafNode>();
HafTest ht = new HafTest();
// 把每个数新建一个节点
for (int i = 0; i < a.length; i++) {
HafNode hf = new HafNode(a[i]);
queue.add(hf);
}
ht.HafTree(queue);
String Code = "";
ht.print(root, Code);
}
// 创建哈夫曼树
public void HafTree(PriorityQueue<HafNode> queue) {
while (queue.size() > 1) {
HafNode min1, min2;
min1 = queue.poll();
min2 = queue.poll();
// 创建合并的节点
HafNode result = new HafNode(min1.getNum() + min2.getNum());
result.setLeft(min1);
result.setRight(min2);
min1.setFather(result);
min2.setFather(result);
queue.add(result);
}
root = queue.peek();
}
// 打印叶节点
public void print(HafNode a, String Code) {
if (a.getLeft() == null && a.getRight() == null) {
System.out.println(a.getNum() + "的哈夫曼编码为:" + Code);
}
if (a.getLeft() != null) {
print(a.getLeft(), Code + '0');
}
if (a.getRight() != null) {
print(a.getRight(), Code + '1');
}
}
}
输出的结果为:
4的哈夫曼编码为:000
1的哈夫曼编码为:0010
3的哈夫曼编码为:0011
4的哈夫曼编码为:010
5的哈夫曼编码为:011
6的哈夫曼编码为:100
6的哈夫曼编码为:101
6的哈夫曼编码为:110
7的哈夫曼编码为:111
恩~~没有错误~~
这样,一个最基本的哈夫曼树就完成了,下面就是利用这个树实现文件的压缩~加油~~~