java 哈夫曼编码
//哈夫曼树类
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 哈夫曼编码的更多相关文章
- 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码
20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...
- java实现哈夫曼编码
java实现哈夫曼编码 哈夫曼树 既然是学习哈夫曼编码,我们首先需要知道什么是哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫 ...
- Java实现哈夫曼编码和解码
最近无意中想到关于api返回值加密的问题,譬如我们的api需要返回一些比较敏感或者重要不想让截获者得到的信息,像如果是做原创图文的,文章明文返回的话则有可能被抓包者窃取. 关于请求时加密的方式比较多, ...
- java使用优先级队列实现哈夫曼编码
思路: 构建小根堆 根据小根堆实现哈夫曼树 根据哈夫曼树对数据进行编码 代码实现如下: /** * @Author: DaleyZou * @Description: 使用java实现一个哈夫曼编码的 ...
- Java数据结构(十二)—— 霍夫曼树及霍夫曼编码
霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...
- Java 树结构实际应用 二(哈夫曼树和哈夫曼编码)
赫夫曼树 1 基本介绍 1) 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), ...
- 2018.2.14 Java中的哈夫曼编码
概念 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造 ...
- 10: java数据结构和算法: 构建哈夫曼树, 获取哈夫曼编码, 使用哈夫曼编码原理对文件压缩和解压
最终结果哈夫曼树,如图所示: 直接上代码: public class HuffmanCode { public static void main(String[] args) { //获取哈夫曼树并显 ...
- HDU2527 哈夫曼编码
Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- C字符串和C++中string的区别 &&&&C++中int型与string型互相转换
在C++中则把字符串封装成了一种数据类型string,可以直接声明变量并进行赋值等字符串操作.以下是C字符串和C++中string的区别: C字符串 string对象(C++) 所需的头文件名称 ...
- 50+ 响应式的Prestashop电商主题
PrestaShop是一款针对web2.0设计的全功能.跨平台的免费开源电子商务解决方案,自08年1.0版本发布,短短两年时间,发展迅速,全球已超过四万家网店采用Prestashop进行部署.Pres ...
- sql-labs 分享
前段时间在网上发现了一个阿三同学托管在github上的sql注入入门科普项目,感觉挺不错,在此分享一下.虽然现在有很多工具比如sqlmap可以实现自动化的sql注入,但是个人感觉如果只知其然而不知其所 ...
- Who is the best at Dataset X?
推荐一个关于分类.目标检测.姿态估计的数据集收藏的网页. Did you ever want to quickly learn?which paper provides the best result ...
- SharePoint咨询师之路:备份和恢复系列--制定备份计划
本来想研究下如何做数据库服务器的集群,然而突然被同事问起如何在部署SharePoint服务场的时候做备份和恢复的计划,就先来复习和研究一下. 本系列包括: 备份服务器场和配置 备份web和服务应用程序 ...
- 第三百三十天 how can I 坚持
今天是姥姥二周年,不是忘了,是根本就没不知道,没放在心上,正月十九,记下了,人这一辈子. 搞不懂,搞不懂那签. 锥地求泉,先难后易,顺其自然,偶遇知己,携手同行,是签文的关键,我逐个解释给你听.锥地求 ...
- vim之pydiction插件
[vim之pydiction插件] It consists of three main files: python_pydiction.vim -- Vim plugin. complete-dict ...
- servlet-3_0-final-spec
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://w ...
- 如何在C#中模拟C++的联合(Union)?[C#, C++] How To Simulate C++ Union In C#?
1 什么是联合? 联合(Union)是一种特殊的类,一个联合中的数据成员在内存中的存储是互相重叠的.每个数据成员都在相同的内存地址开始.分配给联合的存储区数量是“要包含它最大的数据成员”所需的内存数. ...
- C#POP3协议实现SSL验证登陆GMAIL
最近在折腾POP3协议,登陆pop.qq.com和pop.163.com没有什么问题,于是就想着登陆pop.gmail.com,结果失败了.经查,发现gmail的pop3端口不是110,而是995.于 ...