Huffman的概念:
以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
[size=large][color=darkblue]1.Node.java[/color][/size]
package cn.com.Huffman;
/**
* 二叉树的节点的实现
* @author Administrator
*2013.3.31
*/
public class Node {
public String data;//保存的字符
public int a; //字符个数
public String huffmandata;//哈夫曼编码
public Node leftchild; //左孩子
public Node rightchild;//右孩子
/**
* 构造器的实现
* @param data 字符
* @param a data字符个数
*/
public Node(String data,int a){
this.data = data;
this.a = a;
huffmandata = null;
leftchild = null;
rightchild = null;
}
/**
* 构造器的实现
* @param a 字符的个数
*/
public Node(int a){
this.a = a;
}
}
[size=large][color=darkblue]2.HuffmanCode.java[/color][/size]
package cn.com.Huffman;
import java.util.ArrayList;
import java.util.List;
/**
* Huffman编码的实现
* @author Administrator
*2013.3.31
*/
public class HuffmanCode {
private Node root; //根节点
List<Node> list = new ArrayList<Node>();
/**
* 默认构造器的实现
*/
public HuffmanCode(){
root = null;
}
/**
* 实现Huffman编码
* @param node 传入的节点数组
*/
public void huffman(Node[] node){
if(node.length==1){
return;
}
if(node.length==2){
int d = node[0].a+node[1].a;
root = new Node(d);
root.leftchild = node[0];
addZeroLeftChild(node[0]);//实现节点内哈夫曼编码的加0
root.rightchild = node[1];
addOneRightChild(node[1]);//实现节点内哈夫曼编码的加1
return;
}
int d = node[0].a+node[1].a;
Node no = new Node(d);
no.leftchild = node[0];
addZeroLeftChild(node[0]);//实现节点内哈夫曼编码的加0
no.rightchild = node[1];
addOneRightChild(node[1]);//实现节点内哈夫曼编码的加1
Node[] c = new Node[node.length-1];
for(int i=0;i<c.length-1;i++){
c[i] = node[i+2];
}
c[c.length-1] = no;
huffman(sort(c));
}
/**
* 对节点数组进行排序
* @param a无序的节点数组
* @return 返回的是有序的节点数组
*/
public Node[] sort(Node[] a){
for(int i=0;i<a.length;i++){
for(int j=i;j<a.length;j++){
if(a[i].a>a[j].a){
Node b = a[i];
a[i] = a[j];
a[j] = b;
}
}
}
return a;
}
/**
* 子节点node作为右孩子,则它以及它的子节点对象中的Huffmancode前加1;
* @param node 孩子节点
*/
public void addOneRightChild(Node node){
if(node!=null){
node.huffmandata ="1"+ node.huffmandata;
addOneRightChild(node.leftchild);
addOneRightChild(node.rightchild);
}
}
/**
* 子节点node作为左孩子,则它以及它的子节点对象中的Huffmancode前加0;
* @param node 孩子节点
*/
public void addZeroLeftChild(Node node){
if(node!=null){
node.huffmandata ="0"+ node.huffmandata;
addZeroLeftChild(node.leftchild);
addZeroLeftChild(node.rightchild);
}
}
/**
* 可传入root根节点,在控制台输出字符的个数和Huffman编码
* @param node
*/
public void get(Node node){
if(node!=null){
System.out.println(node.a+" ,"+node.huffmandata);
get(node.leftchild);
get(node.rightchild);
}
}
/**
* 将字符串转换成Node节点数组
* @param str //传入的字符串
* @return 返回一个有序Node[]
*/
public Node[] formString(String str){
char[] ch = str.toCharArray();
for(int i=0;i<ch.length;i++){
Node node = new Node(String.valueOf(ch[i]),0);
list.add(node);
}
for(int i=0;i<ch.length;i++){
int k = 0;
Node no =null;
for(int j=0;j<list.size();j++){
if(String.valueOf(ch[i]).equals(list.get(j).data) && list.get(j).a==0){
no = list.get(j);
list.remove(j);
k++;
}
}
if(no!=null){
no.a = k;
list.add(no);
}
}
Node[] n = new Node[list.size()];
for(int i=0;i<n.length;i++){
n[i] = list.get(i);
}
return n;
}
/**
* 主函数入口
* @param args
*/
public static void main(String args[]){
HuffmanCode hc = new HuffmanCode();
Node[] node = hc.formString("jiandequn");
for(int i=0;i<hc.list.size();i++){
System.out.println(hc.list.get(i).data+", "+hc.list.get(i).a);
}
System.out.println("====================");
hc.sort(node);
hc.huffman(hc.sort(node));
hc.get(hc.root);
}
}
分享到:
相关推荐
本文将详细介绍如何利用C++来实现哈夫曼算法,帮助读者更好地理解和掌握这一技术。 首先,我们来理解哈夫曼算法的基本原理。哈夫曼算法的目的是将一组数据转换成二进制编码,以达到压缩数据的目的。其核心思想是...
这是学校数据结构与算法设计课程的PJ,旨在实现类似zip软件的压缩与解压功能。我在几乎有空就在写代码的情况下两周完成了这个项目。 目前网上能够搜索到的资料对于单个文件和文本文件的压缩与解压较多,而对文件夹与...
哈夫曼编码算法实现 哈夫曼编码是一种变长编码技术,用于压缩数据,提高信道的利用率,缩短信息传输的时间,降低传输成本。哈夫曼编码的原理是根据字符出现的频率,建立哈夫曼树,然后对各个字符进行哈夫曼编码。 ...
在C++中实现哈夫曼算法通常涉及以下几个步骤: 1. **字符频率统计**:首先,我们需要统计输入文件中每个字符出现的次数。这可以通过读取文件并维护一个字符-频率映射表来完成。例如,我们可以使用`std::map, int>`...
在这个实验报告中,我们将设计和实现哈夫曼算法,并对其进行分析。实验步骤包括:(1)设置结点结构体,里面有权值、结点名称、结点对应的编码、左子节点、右子结点、父结点;(2)在主函数中输入 26 个英文字母和...
在这个项目中,我们将深入探讨哈夫曼算法的原理,并结合具体实现,理解其在压缩软件中的应用。 一、哈夫曼编码的基本概念 哈夫曼编码是一种可变长度的前缀编码,由美国学者大卫·哈夫曼于1952年提出。它通过为每个...
在这个项目中,我们看到的是一个用C++实现的哈夫曼算法,用于图像压缩。这个程序包括了编码和解码两个过程,可以从`in.bmp`输入图像,通过`Compressor.cpp`中的算法进行压缩,将结果保存到`encode.dat`文件中,然后...
哈夫曼算法压缩jpeg算法源码+项目说明.zip哈夫曼算法压缩jpeg算法源码+项目说明.zip哈夫曼算法压缩jpeg算法源码+项目说明.zip哈夫曼算法压缩jpeg算法源码+项目说明.zip哈夫曼算法压缩jpeg算法...
VC6.0 下实现的哈夫曼算法源代码,读完能对哈夫曼算法有深刻的了解。
哈夫曼算法是一种高效的数据压缩方法,主要用于构建最优的前缀编码树,也称为哈夫曼树。在本文中,我们将深入探讨哈夫曼算法的原理、编码与解码过程,并结合提供的源代码文件`Huffman.cpp`和`Huffman.h`进行分析。 ...
通常通过哈夫曼构建算法实现,该算法将频率最低的两个节点合并为一个新的节点,新节点的频率是其子节点频率之和,重复此过程直到只剩下一个节点,即为哈夫曼树的根节点。 3. **生成哈夫曼编码**:从哈夫曼树中生成...
"count25t"可能是对特定统计方法或优化策略的命名,具体细节可能包含在“哈夫曼算法在图像压缩中的具体实现及改进_庄红涛.pdf”文件中,如可能包括对频率统计的改进、树构造的优化或者解码过程的加速等。 在图像...
自适应哈夫曼算法的c++版本 只是实现而已
详细讲述哈夫曼算法的C语言实现过程,值得一看!
哈夫曼编码(Huffman Coding)是一种数据压缩...总之,哈夫曼算法是一种有效的数据压缩方法,尤其适用于那些包含大量重复字符的数据。提供的程序集成了哈夫曼编码和解码的实现,可以用于实际的文件压缩和解压缩操作。
在这个项目中,使用了Microsoft Foundation Classes (MFC) 框架来实现哈夫曼算法对任意文件格式的压缩和解压功能。 MFC是微软提供的一种C++类库,用于构建Windows应用程序,它简化了用户界面的创建、事件处理和文件...
哈夫曼编码算法与分析(java实现) 哈夫曼编码是一种广泛用于数据文件压缩的十分有效的编码方法,它通过对文件中各个字符出现的频率进行分析,生成各个字符的哈夫曼编码方案。哈夫曼编码的主要思想是通过构造一棵...
实现哈夫曼算法的过程中,需要设计数据结构(如优先级队列)来高效管理节点,并通过递归函数遍历哈夫曼树生成编码。核心代码通常涉及创建节点、构建哈夫曼树、生成编码表、编码数据、解码数据等关键步骤。 #### ...
用哈夫曼算法实现字符型文件压缩与解压,采用C语言实现,友好界面,适合初学者参考和模仿。 适合作为数据结构与算法分析的实验对象。