package com.ietree.basic.datastructure.tree;

 import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue; /**
* Created by ietree
* 2017/5/1
*/
public class HuffmanTree { public static class Node<E> {
E data;
double weight;
Node leftChild;
Node rightChild; public Node(E data, double weight) {
this.data = data;
this.weight = weight;
} public String toString() {
return "Node[data=" + data + ", weight=" + weight + "]";
}
} public static void main(String[] args) { List<Node> nodes = new ArrayList<Node>();
nodes.add(new Node("A", 40));
nodes.add(new Node("B", 8));
nodes.add(new Node("C", 10));
nodes.add(new Node("D", 30));
nodes.add(new Node("E", 10));
nodes.add(new Node("F", 2)); Node root = HuffmanTree.create(nodes);
System.out.println(breadthFirst(root)); } /**
* 构造哈夫曼树
*
* @param nodes 节点集合
* @return 构造出来的哈夫曼树的根节点
*/
private static Node create(List<Node> nodes) { // 只要nodes数组中还有2个以上的节点
while (nodes.size() > 1) {
quickSort(nodes);
// 获取权值最小的两个节点
Node left = nodes.get(nodes.size() - 1);
Node right = nodes.get(nodes.size() - 2);
// 生成新节点,新节点的权值为两个子节点的权值之和
Node parent = new Node(null, left.weight + right.weight);
// 让新节点作为权值最小的两个节点的父节点
parent.leftChild = left;
parent.rightChild = right;
// 删除权值最小的两个节点
nodes.remove(nodes.size() - 1);
nodes.remove(nodes.size() - 1);
// 将新生成的父节点添加到集合中
nodes.add(parent);
}
// 返回nodes集合中唯一的节点,也就是根节点
return nodes.get(0);
} // 将指定数组的i和j索引处的元素交换
private static void swap(List<Node> nodes, int i, int j) {
Node tmp;
tmp = nodes.get(i);
nodes.set(i, nodes.get(j));
nodes.set(j, tmp);
} // 实现快速排序算法,用于对节点进行排序
private static void subSort(List<Node> nodes, int start, int end) { // 需要排序
if (start < end) {
// 以第一个元素作为分界值
Node base = nodes.get(start);
// i从左边搜索,搜索大于分界值的元素的索引
int i = start;
// j从右边搜索,搜索小于分界值的元素的索引
int j = end - 1;
while (true) {
// 找到大于分界值的元素的索引,或者i已经到了end处
while (i < end && nodes.get(++i).weight >= base.weight) ;
// 找到小于分界值的元素的索引,或者j已经到了start处
while (j > start && nodes.get(--j).weight <= base.weight) ;
if (i < j) {
swap(nodes, i, j);
} else {
break;
}
}
swap(nodes, start, j);
// 递归左子树序列
subSort(nodes, start, j - 1);
// 递归右子树序列
subSort(nodes, j + 1, end);
}
} public static void quickSort(List<Node> nodes) {
subSort(nodes, 0, nodes.size() - 1);
} // 广度优先遍历
public static List<Node> breadthFirst(Node root) { Queue<Node> queue = new ArrayDeque<Node>();
List<Node> list = new ArrayList<Node>();
if (root != null) {
// 将根元素入“队列”
queue.offer(root);
}
while (!queue.isEmpty()) {
// 将该队列的“队尾”的元素添加到List中
list.add(queue.peek());
Node p = queue.poll();
// 如果左子节点不为null,将它加入“队列”
if (p.leftChild != null) {
queue.offer(p.leftChild);
}
// 如果右子节点不为null,将它加入“队列”
if (p.rightChild != null) {
queue.offer(p.rightChild);
}
}
return list; } }

Java中的哈夫曼树的更多相关文章

  1. word2vec中关于霍夫曼树的

    再谈word2vec 标签: word2vec自然语言处理NLP深度学习语言模型 2014-05-28 17:17 16937人阅读 评论(7) 收藏 举报  分类: Felven在职场(86)    ...

  2. 2018.2.14 Java中的哈夫曼编码

    概念 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造 ...

  3. 哈夫曼树的介绍 ---java实现

    一.     什么是哈夫曼树 是一种带权路径长度最短的二叉树,也称最优二叉树 带权路径长度:WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln) N个权值Wi(i=1,2,...n)构 ...

  4. 高级数据结构---赫(哈)夫曼树及java代码实现

    我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...

  5. Java 树结构实际应用 二(哈夫曼树和哈夫曼编码)

     赫夫曼树 1 基本介绍 1) 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), ...

  6. 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)

    参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>       ...

  7. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  8. (哈夫曼树)HuffmanTree的java实现

    参考自:http://blog.csdn.net/jdhanhua/article/details/6621026 哈夫曼树 哈夫曼树(霍夫曼树)又称为最优树. 1.路径和路径长度在一棵树中,从一个结 ...

  9. 哈夫曼树(三)之 Java详解

    前面分别通过C和C++实现了哈夫曼树,本章给出哈夫曼树的java版本. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载请注明出处:htt ...

随机推荐

  1. sqlServer的主键只能自增不能手动增加

    1. 2.找到相应的表,找到表设计.

  2. 离线 + 位优化 - SGU 108 Self-numbers 2

    SGU 108 Self-numbers 2 Problem's Link Mean: 略有这样一种数字:对于任意正整数n,定义d(n)为n加上n的各个位上的数字(d是数字的意思,Kaprekar发明 ...

  3. KMP + 求相等前后缀--- POJ Seek the Name, Seek the Fame

    Seek the Name, Seek the Fame Problem's Link: http://poj.org/problem?id=2752 Mean: 给你一个字符串,求这个字符串中有多少 ...

  4. JS调用asp.net后台方法:PageMethods

    先帮朋友宣传一下程序人生(http://www.manong123.com)的网站,里面都是开发感悟,开发人员创业,支持一下吧~ 原来是通过PageMethods来实现的. 举个列子: Default ...

  5. Mybatis实现了接口绑定,使用更加方便。

    1.Mybatis实现了接口绑定,使用更加方便. 在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件, 而Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生 ...

  6. Java凝视模板

     设置凝视模板的入口: Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是全部需设置凝 ...

  7. C# 重命名文件

    在vb下,有一个方法可以对文件进行重命名,所以,我们只要引用到这种方法进行应用即可. 1.添加引用Microsoft.VisualBasic 2.添加命名空间using Microsoft.Visua ...

  8. 数据库存入数据后id保持不变,或者直接报错

    数据库存入数据后id保持不变,且添加的数据一直在进行覆盖 或者直接报错 数据库存入数据后id保持不变,且添加的数据一直在进行覆盖 原因是: 之前注释掉了loadimage();在该函数中含有建立新的记 ...

  9. Mongodb默认开启与关闭

    默认启动:   $ ./mongodb   默认数据保存路径:/data/db/ 默认端口:27017   修改默认路径:   --dbpath $ ./mongdb --dbpath /mongod ...

  10. POJ2456 Aggressive cows(二分+贪心)

    如果C(d)为满足全部牛之间的距离都不小于d. 先对牛舍的位置排序,然后二分枚举d,寻找满足条件的d. #include<iostream> #include<cstdio> ...