赫夫曼树java实现
2020-03-30 19:04
676 查看
赫夫曼树
基本介绍
给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,成这样的二叉树为最优二叉树,也称赫夫曼树。
赫夫曼树是带权路径长度最短的树,权值较大的节点里根较近。
赫夫曼树的几个重要概念
路径和路径长度:在一棵树中,从一个结点往下可以达到子结点之间的通路,称为路径。通路中分支的数目称为路径长度。
节点的权:给树中结点赋予一个有某种含义的数值,称这个数值为该节点的权。
带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积。
树的带权路径长度:定义为所有叶子结点的带权路径长度之和,记为WPL,权值越大的结点离根结点越近的二叉树才是最优二叉树。
赫夫曼树构建步骤
- 将给定数组由小到大排序,将每个数据都看成一个结点,每个结点可以看成最简单的二叉树
- 取出根结点最小的两颗二叉树
- 组成一颗新的二叉树,新的二叉树的根结点的权值是前面两棵二叉树根结点权值的和
- 再将这棵新的二叉树,以 根结点的权值大小在排序,不断重复,再到数列中所有的数据都被处理就得到了一颗赫夫曼树
如下图所示:
赫夫曼树的代码实现
创建结点类
为了让Node对象实现支持排序,Collections集合排序
让Node实现Comparable接口
class Node implements Comparable<Node> { int value; //结点权值 Node left; //指向左子结点 Node right; //指向右子结点 //构造函数 public Node(int value) { this.value = value; } //写一个前序遍历 public void preOrder(){ System.out.println(this); if(this.left != null){ this.left.preOrder(); } if(this.right != null){ this.right.preOrder(); } } @Override public String toString(){ return "Node [value = " + value + "]"; } @Override public int compareTo(Node o){ //表示从小到大排 return this.value - o.value; } }
赫夫曼树的实现
import java.util.ArrayList; import java.util.Collections; import java.util.List; 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("是空树,不能遍历!"); } } //创建赫夫曼树的方法 /** * @param arr 需要创建成赫夫曼树的数组 * @return 创建好的赫夫曼树的root节点 */ public static Node createHuffmanTree(int[] arr){ //遍历arr数组 //将arr的每一个元素够成一个Node //将Node放入到ArrayList中 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; //从ArrayList中删除处理过的二叉树 nodes.remove(leftNode); nodes.remove(rightNode); //将parent加入到nodes中 nodes.add(parent); } //最终列表中只剩下唯一一个节点,将其返回 return nodes.get(0); } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 赫夫曼树、赫夫曼编码和JAVA实现
- java实现赫夫曼树
- 用Java实现Web服务器 HTTP协议
- 如何在Java中实现远程方法调用
- 一个实现MD5的简洁的java类
- 使用Java实现数据报通讯过程
- 用Java实现Server-Client结构的聊天系统
- 一个实现排列和组合的JavaBean
- 再谈将C++语言源码转成html的方法(vim实现,可用于java,perl,python等等多种语言)
- 在 Windows 中实现 Java 本地方法
- Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO 2D GRAPHICS)
- 在JAVA应用程序中如何实现FTP的功能
- Java 与 .NET 的基于 WS-Security的Web Services集成实现(上)
- java语音聊天室原形的实现
- BPEL4WS的开源Java实现
- 基于Java实现简单Http服务器之一
- java实现精确的"四舍五入"
- Java实现POP3服务器
- Java Tip: 用Reflection实现Visitor模式