哈弗曼树的理解和实现(Java)
哈弗曼树概述
哈弗曼树又称最优树,是一种带权路径长度最短的树,在实际中有广泛的用途。哈弗曼树的定义,涉及路径、路径长度、权等概念。哈弗曼树可以用于哈弗曼编码,用于压缩,用于密码学等。
哈弗曼树的一些定义
路径:从树中的一个结点到另一个结点之间的分支构成这两个结点的路径,
路径长度:路径上的分支数目称为路径长度。
树的路径长度:从树根到每一个结点的路径长度之和,我们所说的完全二叉树就是这种路径长度最短的二叉树。
权:赋予某个实体一个量,是对实体的某个或某些属性的数值化描述。
节点的带权路径长度:从该节点到树根之间的路径长度与节点上权的乘积。
树的带权路径长度:如果在树的每一个叶子结点上赋上一个权值,那么树的带权路径长度就等于根结点到所有叶子结点的路径长度与叶子结点权值乘积的总和。
最优二叉树:从已给出的目标带权结点(单独的结点) 经过一种方式的组合形成一棵树.使树的权值最小.。最优二叉树是带权路径长度最短的二叉树。根据结点的个数,权值的不同,最优二叉树的形状也各不相同。它们的共同点是:带权值的结点都是叶子结点。权值越小的结点,其到根结点的路径越长。

他们的带权长度分别为:
WPL1:7*2+5*2+2*2+4*2=36
WPL2:7*3+5*3+2*1+4*2=46
WPL3:7*1+5*2+2*3+4*3=35
所以,第三棵树的带权路径最短。
构造哈弗曼树
1) 根据给定的n个权值{w1, w2, w3, w4......wn}构造n棵只有根节点的二叉树,这n棵二叉树构成一个森林F。
2) 在森林F中选择两棵根节点的权值最小的二叉树,作为一棵新的二叉树的左右子树,且令新的二叉树的根节点的权值为其左右子树的权值和;
3)从F中删除被选中的那两棵子树,并且把构成的新的二叉树加到F森林中;
4)重复2 ,3 操作,直到森林只含有一棵二叉树为止,此时得到的这棵二叉树就是哈夫曼树。

代码实现(Java)
节点类:
package 哈弗曼树;
public class HuffmanNode {
private Object data;
private int weight;
private HuffmanNode lChild;
private HuffmanNode rChild;
public HuffmanNode() {
this.data = null;
this.weight = 0;
this.lChild = null;
this.rChild = null;
}
public HuffmanNode(Object data, int weight) {
this.data = data;
this.weight = weight;
}
public HuffmanNode(int weight, HuffmanNode lChild, HuffmanNode rChild) {
this.weight = weight;
this.lChild = lChild;
this.rChild = rChild;
}
public HuffmanNode(Object data, int weight, HuffmanNode lChild, HuffmanNode rChild) {
this.data = data;
this.weight = weight;
this.lChild = lChild;
this.rChild = rChild;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public HuffmanNode getlChild() {
return this.lChild;
}
public void setlChild(HuffmanNode lChild) {
this.lChild = lChild;
}
public HuffmanNode getrChild() {
return this.rChild;
}
public void setrChild(HuffmanNode rChild) {
this.rChild = rChild;
}
}
哈弗曼树类:
package 哈弗曼树;
import java.util.ArrayList;
public class HuffmanTree {
private String str = "";
private HuffmanNode root;
private ArrayList<String> charList;
private ArrayList<HuffmanNode> nodeList;
private boolean flag;
//构造哈弗曼树
public void createHuffmanTree(String str) {
this.str = str;
charList = new ArrayList<String>();
nodeList = new ArrayList<HuffmanNode>();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
flag = true;
for (int j = 0; j < charList.size(); j++) {
if(charList.get(j).charAt(0) == ch) {
String s = charList.get(j) + ch;
charList.set(j, s);
flag = false;
break;
}
}
if(flag) {
charList.add(charList.size(), ch + "");
}
}
for (int i = 0; i < charList.size(); i++) {
Object data = charList.get(i).charAt(0);
int weight = charList.get(i).length();
HuffmanNode node = new HuffmanNode(data, weight);
nodeList.add(node);
}
while(nodeList.size() > 1) {
this.sortOrder(nodeList);
HuffmanNode left = nodeList.remove(0);
HuffmanNode right = nodeList.remove(0);
int parentWeight = left.getWeight() + right.getWeight();
HuffmanNode parent = new HuffmanNode(null, parentWeight, left, right);
nodeList.add(parent);
}
root = nodeList.get(0);
}
//升序排序
private void sortOrder(ArrayList<HuffmanNode> nodeList) {
for (int i = 0; i < nodeList.size() - 1; i++) {
for (int j = i + 1; j < nodeList.size(); j++) {
HuffmanNode node;
if(nodeList.get(i).getWeight() > nodeList.get(j).getWeight()) {
node = nodeList.get(i);
nodeList.set(i, nodeList.get(j));
nodeList.set(j, node);
}
}
}
}
//中序遍历二叉树
public void print() {
output(root);
}
private void output(HuffmanNode root) {
if(root != null) {
System.out.print(root.getData() + " , ");
output(root.getlChild());
output(root.getrChild());
}
}
public static void main(String[] args) {
HuffmanTree tree = new HuffmanTree();
tree.createHuffmanTree("aabbbcccc");
tree.print();
}
}
哈弗曼树的理解和实现(Java)的更多相关文章
- java实现哈弗曼树
O(∩_∩)O~~ 概述 我想学过数据结构的小伙伴一定都认识哈弗曼,这位大神发明了大名鼎鼎的“最优二叉树”,为了纪念他呢,我们称之为“哈弗曼树”.哈弗曼树可以用于哈弗曼编码,编码的话学问可就大了,比如 ...
- java实现哈弗曼树和哈夫曼树压缩
本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...
- K:哈弗曼树
相关介绍: 树形结构除了应用于查找和排序等操作时能调高效率,它在信息通讯领域也有着广泛的应用.哈弗曼(Huffman)树就是一种在编码技术方面得到广泛应用的二叉树,它同时也是一种最优二叉树. 哈弗曼 ...
- HDU2527:Safe Or Unsafe(哈弗曼树)
Problem Description Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当 ...
- SLT 优先队列 哈弗曼树最小带权路径
与普通的队列不同,普通的队列是先进先出的,而优先队列出队的顺序不是先进先出,而是大(或者小)元素先出队,需要#include <queue> 成员函数 成员函数 作用 empty() 判断 ...
- PKU 1521 Entropy(简单哈弗曼树_水过)
题目大意:原题链接 给你一个字符串,首先是计算出一个按正常编码的编码长度,其次是计算出一个用霍夫曼编码的编码长度,最后求正常编码的长度除以霍夫曼编码长度的比值,保留一位小数. 解题思路:需要知道 1. ...
- POJ 3253 Fence Repair(简单哈弗曼树_水过)
题目大意:原题链接 锯木板,锯木板的长度就是花费.比如你要锯成长度为8 5 8的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5 ...
- Python 数据结构与算法 —— 哈弗曼树
1. 从扩充二叉树到哈弗曼树 扩充二叉树:对二叉树 T,加入足够多的新叶节点(而不是任意),使 T 的原有结点都变成度数为 2 的分支节点,得到的二叉树称为 T 的扩充二叉树. 对于扩充二叉树而言, ...
- POJ 3253 Fence Repair【哈弗曼树/贪心/优先队列】
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 53645 Accepted: 17670 De ...
随机推荐
- c#获取本地IP和MAC地址
1>通过wmi获取 using System; using System.Management; using System.Net; public class Program { static ...
- Eclipse下生成.dll动态库及.a静态库使用 for Windows [z]
以后的主要工作就是做库了,将我们的C或者C++写的接口做成库,给客户端使用,因此有必要知道库的使用和制作方法.主要是在Eclipse下搞了搞,公司用的是Carbide,也差不多.库做好了,用SVN已提 ...
- Golang之struct
1.用来定义复杂数据结构 2.struct里面可以包含多个字段(属性) 3.struct类型可以定义方法,注意和函数的区分. 4.struct类型是值类型 5.struct类型可以嵌套 6.Go语言没 ...
- Android系统编译与测试
1.Android系统分析 2.下载Android源代码(不包括Linux内核部分) 下载好了的Android_5.01.tar.gz,通过samba复制到ubuntu里,再解压之. 可以看到Andr ...
- view是视图层+action是控制层+service是业务层+dao是数据访问层。
- SpringMVC源码解析- HandlerAdapter - ModelFactory
ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...
- B-spline Curves 学习之B样条曲线的移动控制点、修改节点分析(7)
B-spline Curves: Moving Control Points 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习 ...
- [leetcode] 6. Balanced Binary Tree
这个题目纠结了一会儿,终于从二叉树转化到AVL了.题目如下: Given a binary tree, determine if it is height-balanced. For this pro ...
- Flask数据库
一 数据库的设置 Web应用中普遍使用的是关系模型的数据库,关系型数据库把所有的数据都存储在表中,表用来给应用的实体建模,表的列数是固定的,行数是可变的.它使用结构化的查询语言.关系型数据库的列定义了 ...
- CentOS6.4 X86_64 kvm+PXE备忘
Install 安装 1 2 3 4 5 # yum install qemu-kvm qemu-img # 使用kvm至少要安装的包,一个提供用户级别kvm模拟器,一个提供磁盘镜像的管理 # 安装虚 ...