最近一直很迷茫,很懒散,很多东西遇到一点困难都选择了放弃,真的很糟糕,心里有一种说不出的恐惧,甚至想回家躲一躲,不过,憋了两天,总算把最基本的哈弗曼树给做了出来,心里还是有点小振奋的;虽然比起其他人的成果显得我这一点小振奋很幼稚, 但是,但是!无论怎么说,自己最近的状态真的很差,很差......
好了,废话少说,回到正题,哈弗曼树是一种二叉树,具体的哈弗曼树的定义,构建,编码这些东西有关资料上都有很详细的描述,我就不负责任的免了这点了,具体困扰了我几天的东西就是哈弗曼最后的编码了,由于鄙人是个学渣,所以对于哈弗曼的认识仅限于现学的。在我把最基本的哈弗曼树创建后,最后的编码输出让我陷入了麻烦,树杈让我不知遍历。由于想到所有叶节点都是我正好要输出的对象,所以我就老是想某种方法,通过叶节点来遍历,但是这又如何编码呢,越想越不知怎么办,上网查资料,说道什么左孩子,右孩子又有点晕,仔细看了一下,果然就是左右节点。又想到一个树由多个树杈组成,很容易联想到以前做的科赫雪花,所以就用递归来遍历了。
我做的是最基本的二叉树,是对含有1个a,2个b,3个c,4个d,5个e的字符串建树,首先呢就是定义一个节点类;
public class LinkNode {
LinkNode left;//左节点
LinkNode right;//右节点
Object data;//数据
int times;//频率
String code;//节点的编码号
}
由于我已经在纸上画好了图,所以就直接建树了:
public class HuffmanTree {
/**
* 哈弗曼树的构建
*/
public LinkNode creatTree(){
LinkNode root=null;
LinkNode node1 = new LinkNode();
node1.data = "a";
node1.times=1;
LinkNode node2 = new LinkNode();
node2.data = "b";
node2.times=2;
LinkNode node12 = new LinkNode();
node12.data=3;
node12.left=node1;
node12.right=node2;
LinkNode node3= new LinkNode();
node3.data = "c";
node3.times=3;
LinkNode node33= new LinkNode();
node33.data=6;
node33.left=node12;
node33.right=node3;
LinkNode node4 = new LinkNode();
node4.data = "d";
node4.times=4;
LinkNode node5 = new LinkNode();
node5.data = "e";
node5.times=5;
LinkNode node45 = new LinkNode();
node45.data=9;
node45.left=node4;
node45.right=node5;
LinkNode node6 = new LinkNode();
node6.data=15;
node6.left=node33;
node6.right=node45;
root=node6;
return root;
}
额,这些简单直接的东西我就没写注释了,简单的哈弗曼树做出来之后,就是一个编码输出了:
/*
* 编码的产生
*/
private void getHufmanCode(String path,LinkNode root){
if(root==null)
System.out.println("该树不存在");
//若是叶子结点,则输出它的编码
if(root.left==null && root.right==null)
{
root.code = path;
System.out.println("HufmanCode:"+root.data+"\t"+ path);
return;
}
//左子树递归:左边结点编号是0
if(root.left!=null)
getHufmanCode(path+"0", root.left);
//右子树递归:右边结点编号是1
if(root.right!=null)
getHufmanCode(path+"1", root.right);
}
大家可以看出来,通过一个左右子树的递归来实现编码,最后就是实力化对象了:
public static void main(String[] args) {
HuffmanTree hTree = new HuffmanTree();
LinkNode mm= hTree.creatTree();
hTree.getHufmanCode("", mm);
}
这只是一个最简单的哈弗曼树的创建及编码了,当然对于一串任意的字符串进行哈弗曼编码,要做的事情就很多了,大致步骤我也知道,遍历统计,排序,建树,编码......哈弗曼也可以进行压缩,这些东西都是需要我去完成的,不过话说国庆就要来了,暂时没计划的我还是尽量抽时间完成积压的作业吧。