【数据拾遗(java描述)】--- 哈夫曼树的基本实现
来源:互联网 发布:星光图片素材软件 编辑:程序博客网 时间:2024/06/05 13:29
相关定义
节点之间的路径长度:在树中从一个结点到另一个结点所经历的分支,构成了这两个结点间的路径上的经过的分支数称为它的路径长度
树的路径长度:从树的根节点到树中每一结点的路径长度之和。在结点数目相同的二叉树中,完全二叉树的路径长度最短。
结点的权:在一些应用中,赋予树中结点的一个有某种意义的实数。
结点的带权路径长度:结点到树根之间的路径长度与该结点上权的乘积。
树的带权路径长度(Weighted Path Length of Tree:WPL):定义为树中所有叶子结点的带权路径长度之和
哈夫曼树(即最优二叉树):从已给出的目标带权结点(单独的结点) 经过一种方式的组合形成一棵树.使树的权值最小.。最优二叉树是带权路径长度最短的二叉树。根据结点的个数,权值的不同,最优二叉树的形状也各不相同。它们的共同点是:带权值的结点都是叶子结点。权值越小的结点,其到根结点的路径越长。
代码实现
import java.util.ArrayList;import java.util.List;import java.util.Queue;import java.util.concurrent.LinkedBlockingQueue;/** * 哈夫曼树的简单实现 * * @author xdsjs * * @param <T> */public class HuffmanTree<T> { /** * 创建哈夫曼树 * * @param binNodes * 结点列表 * @return 生成的哈夫曼树的根结点 */ public BinNode<T> creatHuffmanTree(List<BinNode<T>> binNodes) { while (binNodes.size() > 1) { quickSort(binNodes, 0, binNodes.size() - 1); BinNode<T> leftNode = binNodes.get(0); BinNode<T> rightNode = binNodes.get(1); BinNode<T> rootNode = (BinNode<T>) new BinNode<String>("P", leftNode.getWeight() + rightNode.getWeight()); rootNode.setLeftNode(leftNode); rootNode.setRightNode(rightNode); binNodes.remove(0); binNodes.remove(0); binNodes.add(rootNode); } return binNodes.get(0); } /** * 快排 * * @param binNodes * @param begin * @param end * @return */ private void quickSort(List<BinNode<T>> binNodes, int begin, int end) { if (begin < end && binNodes != null) { BinNode<T> baseNode = binNodes.get(begin);// 取第一个点位基准点 int i = begin; int j = end; while (i < j) { // 从右向左寻找比基准点小的 while (i < j && binNodes.get(j).getWeight() >= baseNode.getWeight()) j--; if (i < j) binNodes.set(i++, binNodes.get(j)); // 从左往右寻找比基准点大的 while (i < j && binNodes.get(i).getWeight() <= baseNode.getWeight()) i++; if (i < j) binNodes.set(j--, binNodes.get(i)); } binNodes.set(i, baseNode);// 将基准点移动到适当的位置 // 递归调用对子区间进行处理 quickSort(binNodes, begin, i - 1); quickSort(binNodes, i + 1, end); } System.out.println(binNodes.toString()); } /** * 层次遍历(队列实现) * * @param subTree */ public void levelTraverse(BinNode<T> subTree) { if (subTree == null) return; Queue<BinNode<T>> queue = new LinkedBlockingQueue<>(); queue.add(subTree); while (!queue.isEmpty()) { BinNode<T> binNode = queue.poll(); if (binNode != null) { visted(binNode); if (binNode.getLeftNode() != null) queue.add(binNode.getLeftNode()); if (binNode.getRightNode() != null) queue.add(binNode.getRightNode()); } } } /** * 访问某结点 * * @param subTree */ public void visted(BinNode<T> subTree) { System.out.println("--name:" + subTree.getDataValue()); } public static void main(String[] args) { List<BinNode<String>> binNodes = new ArrayList<>(); binNodes.add(new BinNode<String>("A", 8)); binNodes.add(new BinNode<String>("B", 5)); binNodes.add(new BinNode<String>("C", 6)); binNodes.add(new BinNode<String>("D", 9)); binNodes.add(new BinNode<String>("E", 4)); binNodes.add(new BinNode<String>("F", 8)); binNodes.add(new BinNode<String>("G", 8)); binNodes.add(new BinNode<String>("H", 16)); HuffmanTree<String> huffmanTree = new HuffmanTree<>(); BinNode<String> root = huffmanTree.creatHuffmanTree(binNodes); huffmanTree.levelTraverse(root); }}
/** * 表示树节点的类 * * @author xdsjs * * @param <T> * 结点数据域类型 */public class BinNode<T> { private BinNode<T> leftNode;// 左结点 private BinNode<T> rightNode;// 右结点 private T dataValue;// 数据域 private double weight;// 权重 public BinNode() { } public BinNode(T dataValue) { super(); this.dataValue = dataValue; } public BinNode(T dataValue, double weight) { super(); this.dataValue = dataValue; this.weight = weight; } public BinNode(BinNode<T> leftNode, BinNode<T> rightNode, T dataValue) { this.leftNode = leftNode; this.rightNode = rightNode; this.dataValue = dataValue; } public BinNode<T> getLeftNode() { return leftNode; } public void setLeftNode(BinNode<T> leftNode) { this.leftNode = leftNode; } public BinNode<T> getRightNode() { return rightNode; } public void setRightNode(BinNode<T> rightNode) { this.rightNode = rightNode; } public T getDataValue() { return dataValue; } public void setDataValue(T dataValue) { this.dataValue = dataValue; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public String toString() { return "name" + this.getDataValue() + "\n" + "weight" + this.getWeight() + "\n"; }}
参考博客:http://m.blog.csdn.net/blog/bruce_6/38656413
1 0
- 【数据拾遗(java描述)】--- 哈夫曼树的基本实现
- 【数据拾遗(java描述)】--- 二叉树的基本操作
- 知识点拾遗:UDP传输数据最简单的java实现
- 【算法拾遗(java描述)】--- 排序算法概述
- 【算法拾遗(java描述)】--- 交换排序(冒泡、快排)
- 【算法拾遗(java描述)】--- 选择排序(直接选择排序、堆排序)
- 【算法拾遗(java描述)】--- 插入排序(直接插入排序、希尔排序)
- 黑马程序员——java基础拾遗之多线程(一) 多线程的两种实现
- JAVA拾遗 - 线程的三种简单实现
- JAVA拾遗 - 并查集算法的实现与改进
- Java 拾遗(一)
- Java 拾遗(else)
- Java 拾遗(二)
- 数据结构(java语言描述)-- 表的简单数组实现
- 数据结构(java语言描述)-- 队列的循环数组实现
- 单链表的存储方式及实现(java语言描述)
- 冒泡排序算法的实现(Java语言描述)
- JAVA SE 拾遗(1)
- Analysis of Linux kernel crashes
- SVM(二)拉格朗日对偶问题
- Python——函数的高级话题(1)
- monkeyrunner-balabala.....
- 什么样的硬件设备在支撑 Stack Overflow?
- 【数据拾遗(java描述)】--- 哈夫曼树的基本实现
- Java 反射的再次学习
- Android一些小知识-不定时更新
- 支持向量机,线性不可分和核函数
- Julia : csv =>hdf5
- 从大数据菜鸟走上大师的历程 Scala 第十四讲 package 访问权限
- UVa 10976 分数拆分
- Android学习之路-Fragment之二
- php安装memcache和memcached扩展