- 浏览: 91430 次
- 性别:
文章分类
最新评论
-
freezingsky:
人生从来没有害怕过走下坡,可惜的是,大多数夫妻或者情侣,一到挫 ...
我从11楼跳下去 -
胡旭个人博客:
哈哈,这个早就看过了!
我从11楼跳下去 -
砺雪凝霜:
跳下去自己就后悔了,可是后悔已经来不及了,我们关注的不 ...
我从11楼跳下去 -
kuchaguangjie:
最后没摔死?
我从11楼跳下去 -
无心:
加油!
File类(目录遍历)
实现Huffman树的创建,统计输入的字符串的个数,每个字符的哈弗曼编码,以及整个字符的哈弗曼编码,并将编码转换成byte类型。
1.构建节点:
package Huffman;
public class Node implements Comparable{
private int weight;//权重
private int data;//数据
//private String code;
private Node leftNode;//左子树
private Node rightNode;//右子树
//向节点中传入权重和数据
public Node(int data,int weight) {
this.data = data;
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getData() {
return data;
}
public void setData(char data) {
this.data = data;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
/**
* 构建一个比较两个对象大小的方法
*/
public int compareTo(Object o){
int k=0;
if(o instanceof Node){
Node node=(Node)o;
if(weight>node.weight){
k=1;
}
if(weight<node.weight){
k=-1;
}
if(weight==node.weight){
if(data>node.data){
k=1;
}
if(data<node.data){
k=-1;
}
}
}
return k;
}
}
2.构建Huffman树:
package Huffman;
import java.util.PriorityQueue;
public class hfmTree {
//定义一个存储编码的字符串型数组,长度为256
protected String[] SaveCode=new String[256];
protected Node root;//定义一个根节点
//定义一个数组记录该储存单元字符出现的次数,长度为256
private int[] ascii=new int[256];
private String str;
//构造函数,将储存了数据的数组传进来
public hfmTree(int[] a,String str){
this.ascii=a;
this.str=str;
}
/**
* 用ascii数组中的数据来创建哈弗曼树
*/
public void createhfmTree(){
//用优先队列,实例化一个优先队列
PriorityQueue<Node> queue=new PriorityQueue<Node>();
//将ascii中的数据储存到节点中,然后将节点添加到队列中
for(int i=0;i<ascii.length;i++){
if(ascii[i]!=0){
//实例化一个哈弗曼节点
Node node=new Node(i,ascii[i]);//i表示数据,ascii表示数据出现的次数(权重)
queue.add(node);//将节点添加到队列中
}
}
//优先队列将节点按照数据的出现次数weight大小来排序
while(queue.size()>1){
//获取队列中的头元素,并将其删除
Node node1=queue.poll();
Node node2=queue.poll();//获取并移除次队列
//实例化一个合并的节点
Node result=new Node(Math.max(node1.getData(), node2.getData()),node1.getWeight()+node2.getWeight());
result.setLeftNode(node1);
result.setRightNode(node2);
queue.add(result);//将合并节点添加到队列中
}
root=queue.peek();//获取根节点,但不移除此节点的头
}
/**
* @param node:根节点
* @param s:储存节点数据中哈弗曼编码(即01字符串)
* 生成哈弗曼编码(获取编码)
* 哈弗曼编码储存在String中的SaveCode数组中
*/
public void getBM(Node node,String s){
//node左节点不为空赋值为0,右节点不为空则赋值为1
if (node.getLeftNode()!=null){
getBM(node.getLeftNode(),s+"0");
}
if(node.getRightNode()!=null){
getBM(node.getRightNode(),s+"1");
}
if(node.getLeftNode()==null&&node.getRightNode()==null)//说明该节点为叶子节点
{
//输出哈弗曼编码
System.out.println("字符:"+(char)node.getData()+"的hfm编码为"+s);
//存储哈弗曼编码
SaveCode[node.getData()]=s;
}
}
/**
* 构造方法
* 将整个字符串的哈弗曼编码由01字符串转换成byte型
*/
public byte[] ChangeCode(){
String temp="";//用来临时存放哈弗曼编码
for(int i=0;i<str.length();i++){
temp=temp+this.SaveCode[str.charAt(i)];
}
int length=temp.length();
int zero=length%8;//zero表示要添加零的个数
//利用for循环在temp尾部添加zero个零
for(int i=0;i<zero;i++){
temp=temp+"0";
}
//定义一个byte型数组来储存转换之后的值
byte[] array=new byte[temp.length()/8];
for(int i=0;i<temp.length()/8;i++){
array[i]=(byte)(-Integer.parseInt(String.valueOf(temp.charAt(8*i)))*128+
Integer.parseInt(String.valueOf(temp.charAt(8*i+1)))*64+
Integer.parseInt(String.valueOf(temp.charAt(8*i+2)))*32+
Integer.parseInt(String.valueOf(temp.charAt(8*i+3)))*16+
Integer.parseInt(String.valueOf(temp.charAt(8*i+4)))*8+
Integer.parseInt(String.valueOf(temp.charAt(8*i+5)))*4+
Integer.parseInt(String.valueOf(temp.charAt(8*i+6)))*2+
Integer.parseInt(String.valueOf(temp.charAt(8*i+7)))*1);
}
return array;
}
}
3.定义主函数入口:
package Huffman;
import java.util.Scanner;
public class Shuzu {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("请输入一串字符串:");
//输入要转换的字符串(实例化一个浏览器对象)
Scanner scanner=new Scanner(System.in);
String s=scanner.next();
//将字符串存放到数组中
int [] array=new int [256];
for(int i=0;i<s.length();i++){
array[s.charAt(i)]++;
}
for(int i=0;i<array.length;i++){
if(array[i]!=0){
System.out.println(""+(char)i+array[i]);
}
}
//创建一个哈弗曼树对象,将数组和字符传入该对象
hfmTree tree=new hfmTree(array,s);
//构建哈弗曼树
tree.createhfmTree();
//输出每个字符的哈弗曼编码
tree.getBM(tree.root,"");
System.out.println("整个字符串的哈弗曼编码为:");
//数组遍历编码
for(int i=0;i<s.length();i++){
System.out.print(tree.SaveCode[s.charAt(i)]);
}
System.out.println();
//转换为byte类型
byte[] b=tree.ChangeCode();
System.out.println("转换为byte型后:");
for(int i=0;i<b.length;i++){
System.out.print(b[i]+" ");
}
}
}
如有不足欢迎指正!
1.构建节点:
package Huffman;
public class Node implements Comparable{
private int weight;//权重
private int data;//数据
//private String code;
private Node leftNode;//左子树
private Node rightNode;//右子树
//向节点中传入权重和数据
public Node(int data,int weight) {
this.data = data;
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getData() {
return data;
}
public void setData(char data) {
this.data = data;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
/**
* 构建一个比较两个对象大小的方法
*/
public int compareTo(Object o){
int k=0;
if(o instanceof Node){
Node node=(Node)o;
if(weight>node.weight){
k=1;
}
if(weight<node.weight){
k=-1;
}
if(weight==node.weight){
if(data>node.data){
k=1;
}
if(data<node.data){
k=-1;
}
}
}
return k;
}
}
2.构建Huffman树:
package Huffman;
import java.util.PriorityQueue;
public class hfmTree {
//定义一个存储编码的字符串型数组,长度为256
protected String[] SaveCode=new String[256];
protected Node root;//定义一个根节点
//定义一个数组记录该储存单元字符出现的次数,长度为256
private int[] ascii=new int[256];
private String str;
//构造函数,将储存了数据的数组传进来
public hfmTree(int[] a,String str){
this.ascii=a;
this.str=str;
}
/**
* 用ascii数组中的数据来创建哈弗曼树
*/
public void createhfmTree(){
//用优先队列,实例化一个优先队列
PriorityQueue<Node> queue=new PriorityQueue<Node>();
//将ascii中的数据储存到节点中,然后将节点添加到队列中
for(int i=0;i<ascii.length;i++){
if(ascii[i]!=0){
//实例化一个哈弗曼节点
Node node=new Node(i,ascii[i]);//i表示数据,ascii表示数据出现的次数(权重)
queue.add(node);//将节点添加到队列中
}
}
//优先队列将节点按照数据的出现次数weight大小来排序
while(queue.size()>1){
//获取队列中的头元素,并将其删除
Node node1=queue.poll();
Node node2=queue.poll();//获取并移除次队列
//实例化一个合并的节点
Node result=new Node(Math.max(node1.getData(), node2.getData()),node1.getWeight()+node2.getWeight());
result.setLeftNode(node1);
result.setRightNode(node2);
queue.add(result);//将合并节点添加到队列中
}
root=queue.peek();//获取根节点,但不移除此节点的头
}
/**
* @param node:根节点
* @param s:储存节点数据中哈弗曼编码(即01字符串)
* 生成哈弗曼编码(获取编码)
* 哈弗曼编码储存在String中的SaveCode数组中
*/
public void getBM(Node node,String s){
//node左节点不为空赋值为0,右节点不为空则赋值为1
if (node.getLeftNode()!=null){
getBM(node.getLeftNode(),s+"0");
}
if(node.getRightNode()!=null){
getBM(node.getRightNode(),s+"1");
}
if(node.getLeftNode()==null&&node.getRightNode()==null)//说明该节点为叶子节点
{
//输出哈弗曼编码
System.out.println("字符:"+(char)node.getData()+"的hfm编码为"+s);
//存储哈弗曼编码
SaveCode[node.getData()]=s;
}
}
/**
* 构造方法
* 将整个字符串的哈弗曼编码由01字符串转换成byte型
*/
public byte[] ChangeCode(){
String temp="";//用来临时存放哈弗曼编码
for(int i=0;i<str.length();i++){
temp=temp+this.SaveCode[str.charAt(i)];
}
int length=temp.length();
int zero=length%8;//zero表示要添加零的个数
//利用for循环在temp尾部添加zero个零
for(int i=0;i<zero;i++){
temp=temp+"0";
}
//定义一个byte型数组来储存转换之后的值
byte[] array=new byte[temp.length()/8];
for(int i=0;i<temp.length()/8;i++){
array[i]=(byte)(-Integer.parseInt(String.valueOf(temp.charAt(8*i)))*128+
Integer.parseInt(String.valueOf(temp.charAt(8*i+1)))*64+
Integer.parseInt(String.valueOf(temp.charAt(8*i+2)))*32+
Integer.parseInt(String.valueOf(temp.charAt(8*i+3)))*16+
Integer.parseInt(String.valueOf(temp.charAt(8*i+4)))*8+
Integer.parseInt(String.valueOf(temp.charAt(8*i+5)))*4+
Integer.parseInt(String.valueOf(temp.charAt(8*i+6)))*2+
Integer.parseInt(String.valueOf(temp.charAt(8*i+7)))*1);
}
return array;
}
}
3.定义主函数入口:
package Huffman;
import java.util.Scanner;
public class Shuzu {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("请输入一串字符串:");
//输入要转换的字符串(实例化一个浏览器对象)
Scanner scanner=new Scanner(System.in);
String s=scanner.next();
//将字符串存放到数组中
int [] array=new int [256];
for(int i=0;i<s.length();i++){
array[s.charAt(i)]++;
}
for(int i=0;i<array.length;i++){
if(array[i]!=0){
System.out.println(""+(char)i+array[i]);
}
}
//创建一个哈弗曼树对象,将数组和字符传入该对象
hfmTree tree=new hfmTree(array,s);
//构建哈弗曼树
tree.createhfmTree();
//输出每个字符的哈弗曼编码
tree.getBM(tree.root,"");
System.out.println("整个字符串的哈弗曼编码为:");
//数组遍历编码
for(int i=0;i<s.length();i++){
System.out.print(tree.SaveCode[s.charAt(i)]);
}
System.out.println();
//转换为byte类型
byte[] b=tree.ChangeCode();
System.out.println("转换为byte型后:");
for(int i=0;i<b.length;i++){
System.out.print(b[i]+" ");
}
}
}
如有不足欢迎指正!
发表评论
-
jmeter的下载、安装、启动
2017-09-06 13:08 6221.http://jmeter.apache.org/down ... -
SimpleDateFormat转换时间 12,24时间格式
2016-11-09 13:09 593在使用SimpleDateFormat时格式化时间的 yyy ... -
Mysql权限控制 - 允许用户远程连接
2016-08-10 23:59 578Mysql权限控制 - 允许用户远程连接 -
了解泛型
2016-08-07 00:55 349Java 理论和实践: 了解泛型 识别和避免学习使用泛型过程中 ... -
关于内部类的几点认识
2016-08-05 23:54 3181、非静态内部类:内部类可以访问外部类的成员变量,甚至是私有 ... -
java IO流文件的读写具体实例
2016-07-20 22:28 451参考http://www.jb51.net/article/4 ... -
Helo I have similar problem when I start eclipse. An internal error occurred dur
2016-07-15 23:41 1323打开eclipse出现下面的错误信息: An inter ... -
对象的序列化及反序列化
2016-07-10 23:01 409可参考: Java基础学习总结——Jav ... -
this与super
2016-04-18 21:53 4121、this和super都代表了什么 this: ... -
面向对象之继承
2016-04-18 21:35 4221、继承: 让类与类之间产生关系,子父类关系。 ... -
代码块的概述和分类
2016-04-18 20:48 496A:代码块概述 在Java中使用{}括起来的代 ... -
static关键字
2016-04-11 19:40 3361.static 关键字的特点 >随着类的加载而加载 ... -
main方法结构的详细解释
2016-04-11 17:11 509A格式: public static void main ... -
mai方法格式详细解释
2016-04-11 17:06 01、内存中的五大内存 栈:存储局变量。 堆:允许程序员手 ... -
面向对象-封装
2016-04-01 10:11 36807.01_面向对象(构造方 ... -
面向对象-类与对象
2016-04-01 09:53 33606.01_面向对象(面向对象思想概述)(了解) A ... -
java枚举的7大用法
2014-06-23 11:10 376DK1.5引入了新的类型——枚举。在 Java 中它虽然算个 ... -
文件流的读与写
2014-05-28 00:43 1027文件流的读取有很方法,下面介绍一种文件读与写的方法。 读某一路 ... -
讲的很清晰的HashMap算法
2014-05-12 09:59 506HashMap 和 HashSet 是 Java Collec ... -
for循环遍历的几种方法
2014-05-12 09:38 795J2SE 1.5提供了另一种形式的for循环。借助这种形式的f ...
相关推荐
哈夫曼树(Huffman Tree),也称为最优二叉树,是数据压缩中的一种关键数据结构,由哈夫曼在1952年提出。它是一种带权路径长度最短的二叉树,用于实现哈夫曼编码,这是一种高效的无损数据压缩方法。在哈夫曼编码中,...
在Huffman树构建完成后,我们可以从根节点到每个叶子节点遍历一次,为每个叶子节点(代表字符)分配从根到叶子的路径作为它的编码。路径方向右代表0,左代表1,这样就得到了每个字符的前缀码。前缀码的特性是任何...
构建Huffman树的基本思想是:将频率最低的两个节点合并成一个新的节点,新节点的频率是这两个子节点的频率之和,然后将新节点插入到当前的节点集合中,重复此过程直到只剩下一个节点,即为Huffman树。 在C语言中...
2. **构建Huffman树**:基于字符频率,使用贪心算法构建Huffman树。初始时,每个字符都是一个叶节点,且树中只有一个根节点。每次选择两个频率最小的节点合并成一个新的节点,新节点的频率是其子节点的频率之和,...
- 在Huffman树构建完成后,从根节点到每个叶子节点的路径就对应了字符的Huffman编码。通常,向左走表示0,向右走表示1。这样,每个字符都有了一个唯一的二进制编码。 3. **文件压缩过程** - 首先读取待压缩文件...
在Huffman树构建完成后,自底向上遍历树,从根节点到每个叶子节点的路径代表了该叶子节点对应字符的Huffman编码。左分支表示0,右分支表示1。这样,每个字符都得到了唯一的二进制码。例如,如果'f'是最频繁的字符,...
《构建Huffman树及其编码应用》 Huffman树,又称为最优二叉树或霍夫曼树,是一种特殊的二叉树,广泛应用于数据压缩中,尤其是文本压缩。它的构造原则是基于最小带权路径长度(Minimum Spanning Tree,MST)的概念,...
首先,你需要输入一段英文短文,统计每个字母出现的频率,这些频率将作为构建Huffman树的权值。接着,基于这些权值,使用贪心算法构建Huffman树。在构造过程中,每次都选择两个权值最小的节点合并,形成一个新的节点...
程序代码,希望能帮得到大家,有些不全,可以我意见或建议
Huffman树的构建通常采用贪心算法,通过不断地合并频率最小的两个节点,直到所有节点都被合并成一个大树,这就是Huffman树。在图形界面上,这个过程可以以动态的方式呈现,用户可以看到每个步骤的变化,从而加深对...
- **性能提升**:使用优先队列(如`std::priority_queue`)替代循环搜索最小值,可显著加快Huffman树构建速度。 - **注释规范**:代码中的注释应统一语言(建议使用英文),且注释应清晰描述功能而非代码细节,提高...
哈夫曼树(Huffman Tree),也称为最优二叉树,是数据压缩中常用的一种数据结构。它是一种带权路径长度最短的二叉树,由哈夫曼在1952年提出,用于解决“最小带权路径长度”问题。在哈夫曼树中,频率较高的字符对应的...
其核心思想是通过构建一棵特殊的二叉树——Huffman树(也称为最优二叉树或最小带权路径长度树),来为数据中的每个符号分配唯一的二进制编码,使得最频繁出现的符号拥有最短的编码,从而达到高效压缩的目的。...
本实验报告主要关注使用Huffman编码对BMP格式图片进行压缩的过程,涉及了树的存储结构、二叉树遍历、Huffman树构建以及文件操作等多个重要知识点。 一、实验目标与内容 实验旨在让学生通过实际编程加深对Huffman...
3. **Huffman树构建**:不断合并堆中最小频率的两个节点,直到构建出完整的Huffman树。 4. **编码表生成**:遍历Huffman树,为每个像素值生成对应的Huffman编码。 5. **图像压缩**:使用生成的Huffman编码对图像进行...
3. Huffman树构建:根据上述Huffman编码原理,实现合并节点和构建树的过程。 4. 编码生成:从Huffman树根节点开始,遍历树生成编码,并存储到字典或数组中,便于解码时使用。 5. 压缩与解压缩:编码完成后,按照编码...
而`HuffmanTree`可能是Java实现Huffman编码的源代码文件,其中可能包括了字符频率计算、最小堆实现、Huffman树构建、编码表生成、编码与解码等关键功能。 总之,Huffman编码是数据压缩领域的一个重要技术,它通过...
提供的压缩包文件"**Huffman**"可能包含了实现上述功能的C源代码,包括字符频率统计函数、Huffman树构建函数、编码和解码函数等。通过阅读和学习这些源代码,可以更深入地理解Huffman编码的实现细节。对于学习C语言...