赫夫曼树

赫夫曼树:权值越大的结点离根结点越近的二叉树就是最优二叉树。 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 }
View Code
 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 }
View Code
原文地址:https://www.cnblogs.com/bulrush/p/9963060.html