一、     什么是哈夫曼树

是一种带权路径长度最短的二叉树,也称最优二叉树

带权路径长度:WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln)

N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树。对应的叶结点的路径长度为Li(i=1,2,...n)。

二、     建立哈夫曼树

已知的一组叶子的权值w1,w2,w3……wn; 

①首先把 n 个叶子结点看做 n 棵树(仅有一个结点的二叉树)。把它们看做一个森林。

②在森林中把权值最小和次小的两棵树合并成一棵树。该树根结点的权值是两棵子树权值之和。

这时森林中还有 n-1 棵树。

③反复第②步直到森林中仅仅有一棵为止。此树就是哈夫曼树。

现给一组 (n=4) 详细的权值: 2 , 4 , 5 。 8 ,下边是构造详细过程:

n 个叶子构成的哈夫曼树其带权路径长度是唯一的。但树形是不唯一的。由于将森林中两棵权值最小和次小的子棵合并时,哪棵做左子树,哪棵做右子树并不严格限制。

三、     哈夫曼树的应用



a)       哈夫曼编码

 利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每一个叶子节点都有一条路径,对路径上的各分支约定指向左子树的分支表示”0”码,指向右子树的分支表示“1”码。取每条路径上的“0”或“1”的序列作为各个叶子节点相应的字符编码,即是哈夫曼编码。

当中A,B,C,D相应的哈夫曼编码分别为:111。10,110。0



b)      二路归并排序

如果如今有n个已经排序的文件{d1,d2,….dn}。每一个文件包括的记录个数相应是{w1,w2,w3…..wn};能够採用两两合并的方法,把所有文件的记录合并到一个大文件里,使得这个文件里的记录所有排序。

问:採用什么合并次序才干使移动个数最少?

答:依照哈夫曼树的结构从外部结点到根节点逐层进行合并,一定是一种最佳的合并顺序。

 





四、      哈夫曼树的代码实现

用java实现的哈夫曼树
public class Huffman {
public static void main(String[] args){
Huffman huffman = new Huffman();
int[] a = {2,3,5,7,11,13,17,19,23,29,31,37,41};
System.out.println(a.length);
HfTree tree = huffman.createHfTree(a.length , a);
System.out.println("ht ww parent lchild rchild ");
for(int i=0;i<tree.node.length;i++){
System.out.println(i +" "+ tree.node[i].ww +" "+ tree.node[i].parent +" "+ tree.node[i].lchild +" "+ tree.node[i].rchild);
} } private static int MAXINT=10000;
public HfTree createHfTree(int m , int a[]){
HfTree hfTree = new HfTree(m);
/*初始化哈夫曼树*/
for(int i=0;i<2*m-1;i++){
hfTree.node[i].lchild = -1;
hfTree.node[i].rchild = -1;
hfTree.node[i].parent = -1;
if(i<m){
hfTree.node[i].ww = a[i];
}
}
/*開始生成哈夫曼树*/
for(int i=0; i<m-1;i++){
int x1 = 0;
int x2 = 0;
int m1 = MAXINT;
int m2 = MAXINT;
for(int j=0; j<m+i;j++){
if(hfTree.node[j].ww < m1 && hfTree.node[j].parent == -1){
m2 = m1;
x2 = x1;
m1 = hfTree.node[j].ww;
x1 = j;
}
else if(hfTree.node[j].ww < m2 && hfTree.node[j].parent == -1){
m2 = hfTree.node[j].ww;
x2 = j;
}
}
hfTree.node[x1].parent = m+i;
hfTree.node[x2].parent = m+i;
hfTree.node[m+i].ww = m1+m2;
hfTree.node[m+i].lchild = x1;
hfTree.node[m+i].rchild = x2;
}
hfTree.root = 2*m-2;
return hfTree;
} } class HfNode{
public int ww;
public int parent;
public int lchild;
public int rchild; } class HfTree{
public HfNode[] node;
public int root;
public int m; HfTree(int m){
this.m = m;
this.node = new HfNode[2*m-1];
//初始化对象数组是必须每一个对象都创建
for(int i=0;i<2*m-1;i++){
node[i] = new HfNode();
}
} }

哈夫曼树的介绍 ---java实现的更多相关文章

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

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

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

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

  3. Java数据结构(十二)—— 霍夫曼树及霍夫曼编码

    霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...

  4. java实现哈夫曼树进行文件加解压

    目录 1.哈夫曼树简述 2.构造树的节点 3.构造哈夫曼树的类(压缩) 4.构造哈夫曼树的类(解压) 5.整体工程文件(包括测试类) 6.结果 7.参考链接 1.哈夫曼树简述 给定n个权值作为n个叶子 ...

  5. Java实现WUST 1002: 哈夫曼树

    [问题描述] 根据给定的若干权值可以构造出一颗哈夫曼树.构造的哈夫曼树可能不唯一,但是按照下面的选取原则所构造出来的哈夫曼树应该是唯一的. (1)每次选取优先级最低的两个结点,优先级最低的作为左子树, ...

  6. 哈夫曼树(一)之 C语言详解

    本章介绍哈夫曼树.和以往一样,本文会先对哈夫曼树的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可.若 ...

  7. 哈夫曼树(二)之 C++详解

    上一章介绍了哈夫曼树的基本概念,并通过C语言实现了哈夫曼树.本章是哈夫曼树的C++实现. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载 ...

  8. 哈夫曼树——c++

    哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树. 这个定 ...

  9. 数据结构-哈夫曼树(python实现)

    好,前面我们介绍了一般二叉树.完全二叉树.满二叉树,这篇文章呢,我们要介绍的是哈夫曼树. 哈夫曼树也叫最优二叉树,与哈夫曼树相关的概念还有哈夫曼编码,这两者其实是相同的.哈夫曼编码是哈夫曼在1952年 ...

随机推荐

  1. 【Redis哨兵集群】

    目录 开始配置主从复制 开始配置Redis Sentinel @ *** 在开始之前,我们先来看看Redis的主从复制 主从复制原理: 从服务器向主服务器发送SYNC命令. 主服务器接到SYNC命令后 ...

  2. 【Uva 1626】Brackets sequence

    [Link]: [Description] 括号序列由这样的规则生成: 1.空字符是一个括号序列; 2.在括号序列两端加上一对括号也是括号序列; 如(s),[s]; 3.两个括号序列A和B,连在一起, ...

  3. ORACLE-016:ora-01720 授权选项对于&#39;xxxx&#39;不存在

    报错的情形例如以下. A用户:视图V_A B用户:视图V_B,而且用到了V_A C用户:须要用V_B, 授权过程, A用户下: grant select on V_A to B B用户下: grant ...

  4. 76.Nodejs Express目录结构

    转自:https://blog.csdn.net/xiaoxiaoqiye/article/details/51160262 Express是一个基于Node.js平台的极简.灵活的web应用开发框架 ...

  5. call 方法和 apply方法

    1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...

  6. POJ 3170 线段树优化DP

    题意: 思路: 先搞一个vector 存以T2结尾的结构体 (结构体里面有开始工作的时间和花费) f[i]表示取区间[M,i)的代价 易得f[i]=min(f[k]+w,f[i]);T1<=k ...

  7. LuoguP2765 魔术球问题(最大流)

    题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全 ...

  8. 【Django】Form组件

    目录 Form组件介绍 常用字段与插件 Form组件中所有内置字段 从数据库中获取数据 校验示例 检验手机号是否合法 方式一(基本操作) 方式二(自定义验证规则) 方式三(利用钩子) 验证密码一致性 ...

  9. seq---生成随机数

    seq命令用于产生从某个数到另外一个数之间的所有整数. 语法 seq [选项]... 尾数 seq [选项]... 首数 尾数 seq [选项]... 首数 增量 尾数 选项 -f, --format ...

  10. 【Hello 2018 A】 Modular Exponentiation

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 当a<b的时候 a%b==a 显然2^n增长很快的. 当2^n>=1e8的时候,直接输出m就可以了 [代码] #incl ...