//哈夫曼树类
public class HaffmanTree {
//最大权值
static final int MAXVALUE=;
int nodeNum ; //叶子结点个数 public HaffmanTree(int n)
{
this.nodeNum = n;
} //构造哈夫曼树算法
public void haffman(int[] weight,HaffNode[] nodes)//权值数组,所有节点数组
{
int n = this.nodeNum;
//m1,m2,表示最小的两个权值,x1,x2,表示最小两个权值对应的编号,m1表示最小,m2表示次小
int m1,m2,x1,x2; //初始化所有的结点,对应有n个叶子结点的哈夫曼树,有2n-1个结点。
for(int i=;i < *n-;i++)
{
HaffNode temp = new HaffNode();
//初始化n个叶子结点,就是输入的节点。0、1、2、3是叶子节点也是输入的节点
if(i < n)
{
temp.weight = weight[i];
}
else
{
temp.weight = ;
}
temp.parent = ;
temp.flag = ;
temp.leftChild = -;
temp.rightChild = -;
nodes[i] = temp;
} for(int i=;i<n-;i++){//初始化n-1个非叶子结点,n-1表示要循环n-1次求的n-1个数。
m1 = m2 = MAXVALUE;
x1 = x2 =;
for(int j=;j< n+i;j++)//求得这n-1个数时,每次都是从0到n+i-1,并且flag=0的,flag=1表示已经加入到二叉树。
{ //以下2步是找出权值最小的2个
if(nodes[j].weight<m1 && nodes[j].flag==)//if成立了else、else if就不进去了。
{
//m1,x1初始值为第一个元素,后面如果比m1要小,则m1指向更小的,原来m1指向的现在由m2指向,
//如果后面比m1大比m2小,则m2指向这个比m1大比m2小的,
//也就是说m1指向最小的,m2指向第2小的。
m2 = m1;
x2 = x1;
m1 = nodes[j].weight;
x1 = j;
}
else if(nodes[j].weight<m2 && nodes[j].flag ==)
{
m2 = nodes[j].weight;
x2 = j;
}
}
//将权值最小的2个组合成一个2插树
nodes[x1].parent = n+i;
nodes[x2].parent = n+i;
nodes[x1].flag = ;
nodes[x2].flag = ;
nodes[n+i].weight = nodes[x1].weight + nodes[x2].weight;
nodes[n+i].leftChild = x1;
nodes[n+i].rightChild = x2;
}
/*
初始化数组之后:[1,3,5,7,4,9,16]
编码:100、101、11、0
*/
} //哈弗曼编码算法
public void haffmanCode(HaffNode[] nodes,Code[] haffCode)
{
int n = this.nodeNum;
Code code = new Code(n);//
int child,parent; for(int i=;i<n; i++)//给前面n个输入的节点进行编码
{
code.start = n-;//
code.weight = nodes[i].weight;//
child = i;//
parent = nodes[child].parent;
//从叶子节点向上走来生成编码,画图即可。
while(parent!=)
{
if(nodes[parent].leftChild == child)
{
code.bit[code.start] = ;
}
else
{
code.bit[code.start] = ;
} code.start--;
child = parent;
parent = nodes[child].parent;
} Code temp = new Code(n);
for(int j=code.start+;j < n;j++)
{
temp.bit[j] = code.bit[j];
}
temp.weight = code.weight;
temp.start = code.start;
haffCode[i] = temp;
}
}
} //哈夫曼树的结点类
public class HaffNode { int weight; //权值
int parent ;//他的双亲
int flag ;//标志,是否为叶子节点
int leftChild; //他的左孩子
int rightChild;//他的右孩子 HaffNode()
{ } } //哈夫曼编码类
public class Code { int[] bit; //编码的数组
int start; //编码的开始下标
int weight; //权值
Code(int n){
bit = new int[n];
start = n-;
}
} public class Test { public static void main(String[] args) { int n = ;
int[] weight = {,,,};
HaffmanTree haffTree = new HaffmanTree(n);
HaffNode[] nodes = new HaffNode[*n-];
Code[] codes = new Code[n];
//构造哈夫曼树
haffTree.haffman(weight, nodes);
//生成哈夫曼编码
haffTree.haffmanCode(nodes, codes); //打印哈夫曼编码
for(int i=;i<n;i++)
{
System.out.print("Weight="+codes[i].weight+" Code=");
for(int j=codes[i].start+;j<n;j++)
{
System.out.print(codes[i].bit[j]);
}
System.out.println();
}
} }

哈夫曼树:

带权路径长度是做小的,要使一棵二叉树的带权路径长度WPL值最小,必须使权值越大的叶结点越靠近根结点。哈夫曼提出的构造哈夫曼树构造算法为:
(1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根 结点的二叉树,从而得到一个二叉树森林F={T1,T2,…,Tn}。
(2)在二叉树森林F中选取根结点的权值最小和次小的两棵二叉树作为新的二叉树的左右子树构造新的二叉树,新的二叉树的根结点权值为左右子树根结点权值之和。
(3)在二叉树森林F中删除作为新二叉树左右子树的两棵二叉树,将新二叉树加入到二叉树森林F中。
(4)重复步骤(2)和(3),当二叉树森林F中只剩下一棵二叉树时,这棵二叉树就是所构造的哈夫曼树。

哈夫曼编码问题:

哈夫曼树可用于构造代码总长度最短的编码方案。具体构造方法如下:
设需要编码的字符集合为{d1,d2,…,dn},各个字符在电文中出现的次数集合为{w1,w2,…,wn},以d1,d2,…,dn作为叶结点,以w1,w2,…,wn作为各叶结点的权值构造一棵二叉树,规定哈夫曼树中的左分支为0,右分支为1,则从根结点到每个叶结点所经过的分支对应的0和1组成的序列便为该结点对应字符的编码。这样的代码总长度最短的不等长编码称之为哈夫曼编码。

java 哈夫曼编码的更多相关文章

  1. 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码

    20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...

  2. java实现哈夫曼编码

    java实现哈夫曼编码 哈夫曼树   既然是学习哈夫曼编码,我们首先需要知道什么是哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫 ...

  3. Java实现哈夫曼编码和解码

    最近无意中想到关于api返回值加密的问题,譬如我们的api需要返回一些比较敏感或者重要不想让截获者得到的信息,像如果是做原创图文的,文章明文返回的话则有可能被抓包者窃取. 关于请求时加密的方式比较多, ...

  4. java使用优先级队列实现哈夫曼编码

    思路: 构建小根堆 根据小根堆实现哈夫曼树 根据哈夫曼树对数据进行编码 代码实现如下: /** * @Author: DaleyZou * @Description: 使用java实现一个哈夫曼编码的 ...

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

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

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

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

  7. 2018.2.14 Java中的哈夫曼编码

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

  8. 10: java数据结构和算法: 构建哈夫曼树, 获取哈夫曼编码, 使用哈夫曼编码原理对文件压缩和解压

    最终结果哈夫曼树,如图所示: 直接上代码: public class HuffmanCode { public static void main(String[] args) { //获取哈夫曼树并显 ...

  9. HDU2527 哈夫曼编码

    Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. MVC同一页面循环显示数据库记录(答题/投票系统)

    ) { //int id = 1; list newlist = db.lists.Find(id); //var q = from p in db.lists where p.id==1 selec ...

  2. xdebug初步

    ;加载xdebug模块. 根据PHP版本来选择是zend_extension还是zend_extension_ts  ts代表线程安全  被坑过1次zend_extension="\web\ ...

  3. Hibernate学习笔记(三)Hibernate生成表单ID主键生成策略

    一. Xml方式 <id>标签必须配置在<class>标签内第一个位置.由一个字段构成主键,如果是复杂主键<composite-id>标签 被映射的类必须定义对应数 ...

  4. Java基础 —— DOM

    DOM:文档对象模型(Document Object Model) 定义: 文档:标记型文档:html,xml 对象:将文档或文档中的标签等内容都封装到对象中 模型:只要是标记型文档都通用 将html ...

  5. 第二百三十三天 how can I 坚持

    刚才看了场球,亚冠恒大和迪拜阿尔阿赫利,1:0,刚打开电脑就看到了进球,还是很幸运的. 在家待了一天,阴天,预报明天又中到大雪 啊,下吧.好希望下场大雪啊. 最近一直感觉好累,写代码不容易啊 ,还是因 ...

  6. Matlab 图像画在坐标轴下

    >> x=linspace(,*pi,); >> y=sin(x); >> figure;plot(x,y,'r-') >> set(gca,'xaxi ...

  7. JXSE and Equinox Tutorial, Part 1

    http://java.dzone.com/articles/jxse-and-equinox-tutorial-part —————————————————————————————————————— ...

  8. Oracle中INT、FLOAT、NUMBER区别

    Oracle里的int等于number(长度,0) float也类似,number要定义小数部分的位数,而float不用定义后边小数有几位  因为NUMBER要确定长度,后边确定小数位. 所以,如果不 ...

  9. xib上拖拽scrollview的自动布局方法

    http://www.cocoachina.com/ios/20150104/10810.html

  10. JVM的内存管理机制

    在做Java开发的时候常用的JVM内存管理有两种,一种是堆内存,一种是栈内存.堆内存主要用来存储程序在运行时创建或实例化的对象与变量,例如:我们通过new MyClass()创建的类MyClass的对 ...