java 构建哈夫曼编码_哈夫曼编码树构建的java实现

本科时期学习数据结构的时候老师出于大家熟悉所有数据结构的缘由,所有的数据结构都要自己从零开始写。他的出发点是好的,但是实际开发肯定要站在巨人的肩膀上看世界。

以前用的是C++写的,后来也没怎么用过C++了,都是用Java撸码,废话不多说,说一下大体思路。

1. 哈夫曼编码的原理大可以网上查,就是个局部贪心算法,这里不详细说了。

2. 构建三个类,HuffmanNode类,HuffmanTree类和CustomLinkedList类。

贴码:

HuffmanNode.java

public class HuffmanNode{

private HuffmanNode left = null;

private HuffmanNode right = null;

private Integer weight = 0;

private HuffmanNode(int weight,HuffmanNode left,HuffmanNode right){

this.weight = weight;

this.left = left;

this.right = right;

}

public HuffmanNode(int weight){

this(weight, null, null);

}

public HuffmanNode(HuffmanNode left,HuffmanNode right){

this( left.getWeight() + right.getWeight(), left, right);

}

public boolean isLeaf(){

if(null == left && null == right){

return true;

}

return false;

}

public Integer getWeight(){

return weight;

}

public HuffmanNode getLeft(){

return left;

}

public HuffmanNode getRight(){

return right;

}

}

没什么可说的,就是构造方法那里可以看一看。另外还可以写成泛型,我就懒得写了。

CustomLinkedList.java

import java.util.Comparator;

import java.util.LinkedList;

public class CustomLinkedList extends LinkedList {

private Comparator comparator = null;

public void setComparator(Comparator comparator){

this.comparator = comparator;

}

@Override

public boolean add(E e){

int size = this.size();

int index = 0;

while(index

E ei = this.get(index);

if( comparator.compare(ei, e) > 0){//直到遇到一个元素比待插入元素大

this.add(index, e);

return true;

}

++index;

}

return super.add(e);//之前写了this.add(e)害我无限递归,这里标记一下,真是老糊涂了

}

}

这个类主要就是继承LinkedList,好处是每次插入一个元素都能放到排好序的位置。重点在重载的add方法里,认真看一下。LinkedList的好处是在数组中间插入一个元素是快速的,但是get方法定位一个元素就是相对ArrayList是耗时的。还有一个就是要定义比较器Comparator,这里我用了lambda表达式。最后,有强迫症的同学可以用二分法定位,我这样写是看起来很舒服而已。我的遍历的方法耗时O(n),二分法是O(log(n))。

HufmanTree.java

public class HuffmanTree {

private HuffmanNode root = null;

public void buildHuffmanTree(CustomLinkedList cll){

HuffmanNode t1 = null,

t2 = null;

t1 = cll.pollFirst();

t2 = cll.pollFirst();//取出list里头两个元素

while(null != t2){//判断条件是cll中只剩下一个元素,那么树就建好了

//取出list里头的两个元素用于构建一个新的节点

//然后放进list中,这个list自动将新的节点放在合适的位置

cll.add(new HuffmanNode(t1,t2));

t1 = cll.pollFirst();

t2 = cll.pollFirst();//再取出list里头两个元素

}

root = t1;//根节点存根

}

public void travel(){

travelNode(root);

}

private void travelNode(HuffmanNode subRoot){

if(subRoot.isLeaf()){

System.out.println(subRoot.getWeight());

}else{

travelNode(subRoot.getLeft());

travelNode(subRoot.getRight());

}

}

//test huffmanTree

public static void main(String arg[]){

HuffmanTree hfTree = new HuffmanTree();

CustomLinkedList cll = new CustomLinkedList<>();

cll.setComparator((t1,t2)->t1.getWeight().compareTo(t2.getWeight()));

cll.add(new HuffmanNode(42));

cll.add(new HuffmanNode(120));

cll.add(new HuffmanNode(2));

cll.add(new HuffmanNode(37));

cll.add(new HuffmanNode(32));

cll.add(new HuffmanNode(7));

cll.add(new HuffmanNode(42));

cll.add(new HuffmanNode(24));

cll.stream().map(e->e.getWeight())

.forEach(System.out::println);

hfTree.buildHuffmanTree(cll);

hfTree.travel();

}

}

这个类也没什么好说的,就是二叉树的遍历和哈夫曼树构建,哈夫曼树构建的方法buildffmanTree(CustomLinkedList<> cll)就是贪心算法的精髓,看代码还有注释就能明白。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值