数据结构与算法Java版——哈夫曼树
来源:互联网 发布:移动数据什么意思 编辑:程序博客网 时间:2024/06/05 13:35
哈夫曼树也称最优二叉树,是二叉树中的一种应用,它是权数路径最短的树,在信息检索中比较常用。
这个学期学了数据结构这本书,所以我打算用Java实现其中表,队,栈,树。如果你有兴趣可以持续关注我后续操作。我的个人博客为我的博客
哈夫曼树定义:给定一组具有确定权值的叶子节点,可以构造出不同的二叉树,将其中带权路径长度最小的二叉树称为哈夫曼树。
哈夫曼树的实现的基本思想(书上的定义太多,这里我自己简化以下):
1. 我们自己创建一个节点集合,把每个节点初始化,并且权数要赋值。
2. 选择节点集合中权值最小的两个节点,将这两个节点分别作为左子树和右子树,生成一颗新的二叉树,这个二叉树根节点权值就是选出的两个节点的权值的和。
3. 在集合删除(2)中选择出来的两个节点,再把新生成的节点加入集合中。
4. 重复(2)、(3),直到集合中只有一棵二叉树时,这个二叉树就是哈夫曼树。
这里仍然用的二叉链表实现的二叉树,所以先创建Node类
class Node<T>{ T data; //数据 double quanShu; //权数 Node lChild; //左子树 Node rChild; //右子树 public Node(T data, double quanShu) { super(); this.data = data; this.quanShu = quanShu; } @Override public String toString() { return "Node["+data+" "+quanShu+"]"; }}
创建哈夫曼树类并实现一系列方法:
public class HaFuManTree { //创建哈夫曼树 public Node createHaFuManTree(List<Node> nodes){ //节点元素大于或者等于2时继续循环 while(nodes.size()>1) { //升序排序 sort(nodes); //获得最小的两位节点 Node lChild=nodes.get(0); Node rChild=nodes.get(1); //将最小的两个节点"结合" Node parent=new Node(null, lChild.quanShu+rChild.quanShu); parent.lChild=lChild; parent.rChild=rChild; //删除已经结合的两个节点 nodes.remove(0); nodes.remove(0); //添加生成的节点 nodes.add(parent); } return nodes.get(0); //返回根节点 } //冒泡排序,将nodes按照权数升序排序 public List<Node> sort(List<Node> nodes){ for(int i=0;i<nodes.size();i++) { for(int j=i;j<nodes.size();j++) { if(nodes.get(i).quanShu>nodes.get(j).quanShu) { Node node = nodes.get(i); nodes.set(i,nodes.get(j)); nodes.set(j, node); } } } return nodes; } //层序遍历,利用队实现 public void levelTraversal(Node root){ //创建队 Queue q=new LinkedList<>(); //添加根节点 q.add(root); while(!q.isEmpty()){ //第一个元素出队 Node node=(Node) q.poll(); System.out.print(node+" "); if(node.lChild!=null) q.add(node.lChild); if(node.rChild!=null) q.add(node.rChild); } } //获得哈夫曼树带权数路径长度 public double getPathNum(Node root,int height){ if(root==null){ return 0; }else{ if(root.lChild==null&&root.rChild==null){ return root.quanShu*height; }else{ return getPathNum(root.lChild, height+1)+getPathNum(root.rChild, height+1); } } }}
以上代码就实现了哈夫曼树了,在这个过程中,个人觉得最麻烦的是递归,容易晕,不过递归最重要的就是两点:
1. 找重复处理的逻辑
2. 找结束处理的逻辑
如果递归仍然理不清楚可以用笔画画,盘出逻辑,这样会比较清晰。
最后贴上自己的main方法的代码和截图啦
public static void main(String[] args) { List<Node> nodes=new ArrayList<>(); nodes.add(new Node("A", 6)); nodes.add(new Node("B", 20)); nodes.add(new Node("C", 31)); nodes.add(new Node("D", 2)); nodes.add(new Node("E", 12)); nodes.add(new Node("F", 25)); nodes.add(new Node("G", 10)); HaFuManTree fuManTree=new HaFuManTree(); Node root = fuManTree.createHaFuManTree(nodes); fuManTree.levelTraversal(root); System.out.println(); System.out.println("哈夫曼路径长度为:"+fuManTree.getPathNum(root, 0));}
今天的内容就到此结束啦,有兴趣的小伙伴可以自己手动实现下。
阅读全文
0 0
- 数据结构与算法Java版——哈夫曼树
- 数据结构与算法Java版——栈与队
- 《java数据结构与算法》——数组
- 数据结构与算法Java版——单链表的实现
- 数据结构与算法Java版——双向链表
- 数据结构与算法Java版——二叉排序树
- 数据结构与算法Java版——图及其遍历
- 数据结构与算法Java版——八皇后问题
- 数据结构与算法Java版——约瑟夫环问题
- 数据结构与算法—常用数据结构及其Java实现
- 【数据结构与算法】汉诺塔算法——java递归实现
- java数据结构与算法
- Java数据结构与算法
- 《JAVA数据结构与算法》
- java 数据结构与算法
- Java数据结构与算法
- java 数据结构与算法
- Java数据结构与算法
- ubuntu开机自启动tomcat
- Spring整合Ehcache管理缓存
- 读取与保存
- 翻转单词顺序&左旋转字符串
- JAVA设计模式之单例模式
- 数据结构与算法Java版——哈夫曼树
- ToLua学习笔记,创建一个游戏对象
- 几种常用的ajax配合json数据格式向后台发送请求以及后台如何接收数据
- 微信小程序有哪些?401~500
- Linux常用命令(五)——系统安全命令(未拓展)
- 【Python】工作中自己用的一个程序,操作excel
- 3.3 Android Studio中的LogCat及其相关设置
- Windows7(64)+anaconda2(python2.7)安装tensorflow详细步骤
- Python---pycharm安装