| 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。 |
| 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近 |
| |
| 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1 |
| 结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积 |

| 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL(weighted path length) ,权值越大的结点离根结点越近的二叉树才是最优二叉树。 |
| WPL最小的就是赫夫曼树 |



| 一个数列 {13, 7, 8, 3, 29, 6, 1},要求转成一颗赫夫曼树 |
| |
| |
| 从小到大进行排序, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树 |
| 取出根节点权值最小的两颗二叉树 |
| 组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和 |
| 再将这颗新的二叉树,以根节点的权值大小 再次排序, 不断重复 1-2-3-4 的步骤,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树 |



| public class HuffmanTree { |
| |
| public static void main(String[] args) { |
| int arr[] = { 13, 7, 8, 3, 29, 6, 1 }; |
| Node root = createHuffmanTree(arr); |
| |
| preOrder(root); |
| } |
| |
| |
| public static void preOrder(Node root) { |
| if(root != null) { |
| root.preOrder(); |
| }else{ |
| System.out.println("是空树,不能遍历~~"); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public static Node createHuffmanTree(int[] arr) { |
| |
| |
| |
| |
| List<Node> nodes = new ArrayList<Node>(); |
| for (int value : arr) { |
| nodes.add(new Node(value)); |
| } |
| |
| while(nodes.size() > 1) { |
| |
| Collections.sort(nodes); |
| System.out.println("nodes =" + nodes); |
| |
| |
| |
| Node leftNode = nodes.get(0); |
| |
| Node rightNode = nodes.get(1); |
| |
| |
| Node parent = new Node(leftNode.value + rightNode.value); |
| parent.left = leftNode; |
| parent.right = rightNode; |
| |
| |
| nodes.remove(leftNode); |
| nodes.remove(rightNode); |
| |
| nodes.add(parent); |
| } |
| |
| return nodes.get(0); |
| } |
| } |
| |
| |
| |
| |
| class Node implements Comparable<Node> { |
| int value; |
| Node left; |
| Node right; |
| |
| |
| public void preOrder() { |
| System.out.println(this); |
| if(this.left != null) { |
| this.left.preOrder(); |
| } |
| if(this.right != null) { |
| this.right.preOrder(); |
| } |
| } |
| |
| public Node(int value) { |
| this.value = value; |
| } |
| |
| @Override |
| public String toString() { |
| return "Node [value=" + value + "]"; |
| } |
| |
| @Override |
| public int compareTo(Node o) { |
| |
| |
| return this.value - o.value; |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术