赫夫曼树:权值越大的结点离根结点越近的二叉树就是最优二叉树。 WPL值也越小。
WPL值:权值乘根结点到自己的线数。
权值:这个9就是权值。
图中的b就是赫夫曼树。
怎么形成一个赫夫曼树呢?
假如有这么一个数组:3,7,19,8,30,1
形成的思路是:先进行排序。然后把最小的两个生成一个二叉树。根节点是这两个权值的和。然后把最小的这两个删除掉。把生成的那个根节点放到数组中。然后再进行排序。再挑选出最小的两个。
排序:1 3 7 8 19 30
排序:4 7 8 19 29 30
排序:8 11 19 29 30
排序:19 19 29 30
排序:29 30 38
排序:38 59
这就是生成赫夫曼树的原理。
接下来我们用代码来实现一下:
1 package com.Huffman; 2 3 /** 4 * 链表。赫夫曼树结构用到的双链表。 5 */ 6 public class Node implements Comparable<Node> { 7 //数据 8 int value; 9 //左儿子 10 Node leftNode; 11 //右儿子 12 Node rightNode; 13 14 public Node(int value) { 15 this.value = value; 16 } 17 18 19 @Override 20 public String toString() { 21 return "Node{" + 22 "value=" + value + 23 '}'; 24 } 25 26 //排序。前面加 - ,是倒序。 27 @Override 28 public int compareTo(Node o) { 29 return -(this.value-o.value); 30 } 31 }
1 package com.Huffman; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6 7 /** 8 * 赫夫曼树:就是最优二叉树。权值越大的结点离根结点越近的二叉树。WPL值最小。 9 */ 10 public class HuffmanTree { 11 public static void main(String[] args) { 12 int arr[] = {3, 7, 8, 29, 5, 11, 23, 14}; 13 Node node = createHuffmanTree(arr); 14 System.out.println(node); 15 } 16 //创建赫夫曼树。 17 public static Node createHuffmanTree(int[] arr){ 18 //先使用数组中的所有元素。创建若干个二叉树。(只有一个节点) 19 List<Node> nodes = new ArrayList<>(); 20 for (int value : arr) { 21 nodes.add(new Node(value)); 22 } 23 //循环处理.要不断的两个相加。然后删除。最后只剩下一个。 24 while(nodes.size()>1){ 25 // 排序 26 Collections.sort(nodes); 27 //取出权值最小的两个二叉树(左和右)。 28 Node left = nodes.get(nodes.size() - 1); 29 Node right = nodes.get(nodes.size() - 2); 30 //构建一个新的二叉树。 31 Node newTree = new Node(left.value + right.value); 32 //把取出的那两个删除掉。 33 nodes.remove(left); 34 nodes.remove(right); 35 //放在原来的二叉树集合中。 36 nodes.add(newTree); 37 38 } 39 return nodes.get(0); 40 } 41 }