哈弗曼树概述

哈弗曼树又称最优树,是一种带权路径长度最短的树,在实际中有广泛的用途。哈弗曼树的定义,涉及路径、路径长度、权等概念。哈弗曼树可以用于哈弗曼编码,用于压缩,用于密码学等。

哈弗曼树的一些定义

路径:从树中的一个结点到另一个结点之间的分支构成这两个结点的路径,

路径长度:路径上的分支数目称为路径长度。

树的路径长度:从树根到每一个结点的路径长度之和,我们所说的完全二叉树就是这种路径长度最短的二叉树。

权:赋予某个实体一个量,是对实体的某个或某些属性的数值化描述。

节点的带权路径长度:从该节点到树根之间的路径长度与节点上权的乘积。

树的带权路径长度:如果在树的每一个叶子结点上赋上一个权值,那么树的带权路径长度就等于根结点到所有叶子结点的路径长度与叶子结点权值乘积的总和。

最优二叉树:从已给出的目标带权结点(单独的结点) 经过一种方式的组合形成一棵树.使树的权值最小.。最优二叉树是带权路径长度最短的二叉树。根据结点的个数,权值的不同,最优二叉树的形状也各不相同。它们的共同点是:带权值的结点都是叶子结点。权值越小的结点,其到根结点的路径越长。

他们的带权长度分别为:

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)的更多相关文章

  1. java实现哈弗曼树

    O(∩_∩)O~~ 概述 我想学过数据结构的小伙伴一定都认识哈弗曼,这位大神发明了大名鼎鼎的“最优二叉树”,为了纪念他呢,我们称之为“哈弗曼树”.哈弗曼树可以用于哈弗曼编码,编码的话学问可就大了,比如 ...

  2. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  3. K:哈弗曼树

    相关介绍:  树形结构除了应用于查找和排序等操作时能调高效率,它在信息通讯领域也有着广泛的应用.哈弗曼(Huffman)树就是一种在编码技术方面得到广泛应用的二叉树,它同时也是一种最优二叉树. 哈弗曼 ...

  4. HDU2527:Safe Or Unsafe(哈弗曼树)

    Problem Description Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当 ...

  5. SLT 优先队列 哈弗曼树最小带权路径

    与普通的队列不同,普通的队列是先进先出的,而优先队列出队的顺序不是先进先出,而是大(或者小)元素先出队,需要#include <queue> 成员函数 成员函数 作用 empty() 判断 ...

  6. PKU 1521 Entropy(简单哈弗曼树_水过)

    题目大意:原题链接 给你一个字符串,首先是计算出一个按正常编码的编码长度,其次是计算出一个用霍夫曼编码的编码长度,最后求正常编码的长度除以霍夫曼编码长度的比值,保留一位小数. 解题思路:需要知道 1. ...

  7. POJ 3253 Fence Repair(简单哈弗曼树_水过)

    题目大意:原题链接 锯木板,锯木板的长度就是花费.比如你要锯成长度为8 5 8的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5 ...

  8. Python 数据结构与算法 —— 哈弗曼树

    1. 从扩充二叉树到哈弗曼树 扩充二叉树:对二叉树 T,加入足够多的新叶节点(而不是任意),使 T 的原有结点都变成度数为 2 的分支节点,得到的二叉树称为 T 的扩充二叉树. 对于扩充二叉树而言, ...

  9. POJ 3253 Fence Repair【哈弗曼树/贪心/优先队列】

    Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 53645   Accepted: 17670 De ...

随机推荐

  1. Pwdump v7.1

    提取windows系统密码  和 hash值

  2. 07Mendel's First Law

    Problem Figure 2. The probability of any outcome (leaf) in a probability tree diagram is given by th ...

  3. wcf服务编程(第3版)文摘

    第1章 wcf基础 什么是wcf: System.ServiceModel.dll 服务 服务的执行边界: proxy 地址:http/https,tcp,ipc,peer newwork,msmq, ...

  4. java类加载器的一些测试

    package classloader; import java.lang.reflect.Method; import org.junit.Test; import com.example.Samp ...

  5. 以json格式打印实体类信息

    1.pom.xml <dependency> <groupId>com.google.code.gson</groupId> <artifactId>g ...

  6. 【转】java遍历实体类的属性和数据类型以及属性值

    和同学接了个外包的活,由于项目中很多地方要用到poi导出excel,而每次导出都要写很多相同的代码,因为poi的cell.setCellValue();每次设置的都是不同实体bean的属性值,导致代码 ...

  7. System.Web.HttpUtility VS System.Web.HttpServerUtility VS System.Net.WebUtility

    HttpUtility 类作为 HttpServerUtility 类的内部使用,HttpServerUtility 通过System.Web.UI.Page.Server属性(WebForm)/Co ...

  8. linux每天一小步---cat命令详解

    1 命令功能 cat命令是linux系统下的一个文本输出命令,通常用于查看文件的内容. 2 命令语法 cat  [选项参数]  文件名 3 命令参数 -n  由1开始对所有输出的内容行数编号 -b   ...

  9. 23 DesignPatterns学习笔记:C++语言实现 --- 2.6 Facade

    23 DesignPatterns学习笔记:C++语言实现 --- 2.6 Facade 2016-07-22 (www.cnblogs.com/icmzn) 模式理解

  10. Computer

    Computer 1. Ctrl+N .根据惯例,“Control”.“Shift” 以及 “Alternate” 按键将以 Ctrl.Shift 以及 Alt 来表示,需要特别指出的是,其中第一个按 ...