哈弗曼树的理解和实现(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 ...
随机推荐
- PLSQL启动很慢的问题
最近重新做了系统,win7 64位系统上装了oracle10g,plsql10.发现plsql启动比较慢. 解决方法: 首先停止打印机服务:Print Spooler,然后将这个服务设置为手动模式.
- 19-python 自己建立词库并实现文章汉语词频统计
首先在网上下载一个汉语词典的txt文件, 汉语词典 1.用正则去掉词语的解释,即提取出所有汉语词语: import re def getHanYuCi(st): p = re.compile(r'[. ...
- Multithreading in C
Multithreading in C, POSIX(可移植操作系统接口Portable Operating System Interface X ) style Multithreading - A ...
- WebService超时
1.web.config配置,<system.web></system.web>里面增加:<httpRuntime maxRequestLength="1024 ...
- git best practice
1. https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud (atlassian家的git) 2. https: ...
- <<高级计算机网络>>(Advaned Computer Networks) 徐恪 徐明伟 陈文龙 马东超
目录 第1章 计算机网络与Internet1 1.1 引言1 1.2 Internet发展历史2 1.2.1 互联网发展的主要阶段4 1.2.2 互联网在中国的发展5 1.2.3 互联网主要创新5 1 ...
- ubuntu库文件路径pkgconfig
settings--->compiler and bug settings -->link settings 在左边添加libpthread.a ,右边添加 -lpthread即可. u ...
- velocity在html中换行符转换
<td colspan="3" class="tdContent2">$!obj.getDealInfo().replaceAll("\r ...
- Mac下eclipse 启动时出现An error has occurred. See the log file的问题
eclipse原来可以使用的好好的,装了多个版本的jdk后,打开eclipse出现An error has occurred. See the log file的问题,经过查找,可能原因之一是机子装了 ...
- android 播放视频时切换全屏隐藏状态栏
1. Demo: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...