霍夫曼树
以此谨记自己学习java心得
这几天一直再学数据结构与算法,学到了树结构,前天也简单讲了线索化二叉树的前序遍历。今天所学的是霍夫曼树,相比较而言霍夫曼树比以前的数组、链表这种难一点。尤其是霍夫曼编码,让我看着老师讲解,还写了一个下午的代码。
首先,先简单介绍一下霍夫曼树,霍夫曼树的每一个叶子结点所代表的数字,我暂且称之为权值。另外一个概念,我称之为层数,如果以根节点为第一层,则每一行为一层,就可得到叶子结点的层数,再将该叶子结点的权值乘以该叶子结点到根节点的层数差,这个乘积就叫做带权路径长度。根据排列组合,如果带权路径长度最小,就叫做霍夫曼树。那么如何通过代码来实现一个霍夫曼树,思路如下,先创建一个Tree类用与存放结点,结点属性拥有value ,left,right。再给一个一维Int数组,数组里的值可以当作Tree对象的value。前提,这个数组必须是有序的,在这里默认为从小到大,其实这个数组排序方法我有七八种方法,等下次在做一个仔细说明各个排序算法。排完序后,先将Tree的对象以value为形参创建起来。我这里将数组存放于集合中,再将集合的0号索引和1号索引取出,将这两个索引值相加,再以这个相加的值创建Tree对象,再将这个对象添加进集合中,这个对象以left,right的形式保存之前的0号位和1号位,再集合中将原来的0号位与1号位删除,再进行集合内部排序。
到最后集合中只剩一个数据,然后再将这个数据作为根节点进行前序遍历
代码如下,首先是结点信息
```java
class Node implements Comparable<Node>{
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
public Node() {
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
@Override
public int compareTo(Node o) {
if (this.value>o.value){
return 1;
}
if (this.value==o.value){
if (o.left!=null) {
return -1;
}
}
return -1;
}
}
然后是霍夫曼树的类`
public class HuffmanTree {
public static void main(String[] args) {
int []array=new int[]{2,3,5,6,4};
Node node = createTree(array);
// System.out.println(node);
}
public static Node createTree(int [] arr){
ArrayList<Node> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
Node node = new Node(arr[i]);
list.add(node);
}
Collections.sort(list);
System.out.println(list);
// System.out.println(list);
while (list.size()>1) {
Node node1 = list.get(0);
Node node2 = list.get(1);
Node node = new Node(node1.value + node2.value);
node.left=node1;
node.right=node2;
list.remove(node1);
list.remove(node2);
list.add(node);
Collections.sort(list);
}
prologue(list.get(0));
System.out.println(list.get(0).left);
return list.get(0);
}
public static void prologue(Node node){
System.out.println(node.value);
if (node.left!=null){
prologue(node.left);
}
if (node.right!=null){
prologue(node.right);
}
}
}
```明天再做霍夫曼编码分析