- 浏览: 8981 次
- 性别:
- 来自: 安徽
文章分类
最新评论
-
luchi0000:
今年毕业打算写关于socket通讯的论文刚好看到楼主的qq!楼 ...
Socket通信小项目--大山QQ(简易版本)附源码 -
lastSeries:
人才呀。。。不多说。。。继续奋斗
Socket通信小项目--大山QQ(简易版本)附源码 -
xugou123456:
不错,大神,神一样的存在着。我也在学习中,向你学习!
Socket通信小项目--大山QQ(简易版本)附源码 -
yzj578492228:
[u][/u][i][/i]louzhu niu ren
Socket通信小项目--大山QQ(简易版本)附源码 -
luliangy:
牛人啊
Socket通信小项目--大山QQ(简易版本)附源码
哈夫曼算法一般用来实现数据压缩,以另外一种规则存储数据,从而达到压缩的功能。
以下是我编写的一个哈夫曼树的例子:
程序描述:1.传入一个字符串,将之分解,得到每个字符的个数,个数即为权值
2.将每一个字符和他的权值传入一个HFMNode对象中, 再将该对象传入一个队列中
3.将队列中的HFMNode对象按权值大小排序,每次取其中权值最小的两个对象,生成一个二叉树,
向array中删除这两个权值最小的节点,同时添加该两对象的父节点
4.编码 按规则:从根节点开始,向左走一步编码加+1,向右走一步编码+0
以下为源码:
哈夫曼节点的类
package tree;
public class HFMNode {
//节点一共有三种:
//1.根节点 根节点没有父节点
//2.叶节点 没有子节点
//3.中间节点 有父节点和子节点
private HFMNode parent ;
private HFMNode leftChild ;
private HFMNode rightChild;
private char s ;//节点所储存的字符
private int weight=0 ;//所储存节点的权值
private String code="" ;//字符对应的哈夫曼编码
public void setParent(HFMNode parent){
this.parent = parent ;
}
public HFMNode getParent(){
return this.parent ;
}
public void setLeftChild(HFMNode leftChild){
this.leftChild = leftChild ;
}
public HFMNode getLeftChild(){
return this.leftChild ;
}
public void setRightChild(HFMNode rightChild){
this.rightChild = rightChild ;
}
public HFMNode getRightChild(){
return this.rightChild ;
}
public void setWeight(int weight){
this.weight = weight ;
}
public int getWeight(){
return this.weight ;
}
public void setChar(char s){
this.s = s ;
}
public char getChar(){
return this.s ;
}
public void setCode(String code){
this.code = code ;
}
public String getCode(){
return this.code ;
}
}
哈夫曼树的类
package tree;
import java.util.ArrayList;
public class ConstructHFM {
private String data ;//传入的字符串
private ArrayList<HFMNode> array = new ArrayList<HFMNode>();
private ArrayList<HFMNode> nodeArray = new ArrayList<HFMNode>();//储存所有的节点
public ConstructHFM(String data){
this.data = data ;
}
/**
*得到字符串的编码
*/
public void getStringCode(){
this.setTreeNode();
this.sortAndConsTree();
this.setEveryCharCode(array.get(0));
String allCode = this.getAllCode();
System.out.println("*******************************************************");
System.out.println(data+"的哈夫曼编码是:"+allCode);
}
/**
* 得到不同的字符总数,
* 将每一个字符和他的权值传入一个HFMNode对象中,
* 将此对象添加入队列中
*/
public void setTreeNode(){
char[] s = data.toCharArray();
int[] charCount = new int[s.length];//与字符数组相对应,记录对应字符的个数
for(int i=0 ;i<charCount.length ;i++){
charCount[i] = 1 ;
}
//得到字符的数目,以及每个字符的个数
for(int i=0 ; i<s.length ;i++){
for(int j=0 ; j<i ;j++){
if(s[i]==s[j]){
charCount[j]++;
charCount[i]=0;
break;
}
}
}
//将字符传入及节点对象
for(int i=0 ;i<s.length ;i++){
if(charCount[i]!=0){
HFMNode h = new HFMNode();
h.setChar(s[i]) ;
h.setWeight(charCount[i]);
array.add(h);
nodeArray.add(h);
}
}
}
/**
* 将队列array中的每个HFMNode对象按权值排序 ,
* 取得最后两个对象生成二叉树,
* 删除这2个节点,添加其构成的父节点
* 且当array中只有一个元素时,该元素为根节点
*/
public void sortAndConsTree(){
while(array.size()>=2){//冒泡排序
for(int i=0;i<array.size();i++){
HFMNode tem = array.get(i) ;
for(int j=i+1;j<array.size();j++){
if(array.get(j).getWeight()>tem.getWeight()){
array.set(i, array.get(j));
array.set(j, tem);
tem = array.get(i);
}
}
}
HFMNode parent = new HFMNode();
int len = array.size();
HFMNode last = array.get(len-1) ;
HFMNode lastSecond = array.get(len-2);
parent.setLeftChild(last);
last.setParent(parent);
parent.setRightChild(lastSecond);
lastSecond.setParent(parent);
int leftWeight = last.getWeight() ;
int rightWeight = lastSecond.getWeight() ;
parent.setWeight(leftWeight + rightWeight);
array.remove(len-1);
array.remove(len-2);
array.add(parent);
nodeArray.add(parent);
}
}
/**
* 打印每个字符的哈夫曼编码
* 从根节点开始,向左走一步编码为1,向右为0
*/
public void setEveryCharCode(HFMNode node){
if(node.getLeftChild()!=null&&node.getRightChild()!=null){//判断为叶节点
node.getLeftChild().setCode(node.getCode() + 1);
node.getRightChild().setCode(node.getCode() + 0);
setEveryCharCode(node.getLeftChild());
setEveryCharCode(node.getRightChild());
}
}
/**
* 得到字符串的编码
*/
public String getAllCode(){
//按权值顺序打印所有叶节点的字符和编码
for(int i=0;i<nodeArray.size();i++){
HFMNode tem = nodeArray.get(i);
for(int j=i+1;j<nodeArray.size();j++){
if(nodeArray.get(j).getWeight()>tem.getWeight()){
nodeArray.set(i, nodeArray.get(j));
nodeArray.set(j, tem);
tem = nodeArray.get(i);
}
}
}
//打印所有的字符的HFM编码
System.out.println("******************以下是传入字符串的权值和哈夫曼编码");
for(int j=0 ;j<nodeArray.size();j++){
HFMNode h = nodeArray.get(j);
if(h.getChar()!='\u0000'){//char型变量的默认值为'\u0000'
System.out.println(h.getChar()+"的权值:"+h.getWeight()+" 哈夫曼编码:"+h.getCode());
}
}
System.out.println("*******************以下是生成的哈夫曼树的结构");
//打印生成HFM树的结构
for(int k=0;k<nodeArray.size();k++){
HFMNode hfm = nodeArray.get(k);
if(hfm.getParent()==null){
System.out.println("第"+k+"个节点为根节点,其权值为:"+hfm.getWeight());
}
else if(hfm.getLeftChild()==null&&hfm.getRightChild()==null){
System.out.println("第"+k+"个节点为叶节点 字符为:"+hfm.getChar()+" 权值:"+hfm.getWeight()+" 哈夫曼编码为:"+hfm.getCode());
}
else{
System.out.println("第"+k+"个节点为中间节点,其权值为:"+hfm.getWeight());
}
}
String allCode="" ;
char[] c = data.toCharArray();
for(int i=0;i<c.length;i++){
for(int j=0;j<nodeArray.size();j++){//nodeArray中储存有所有的节点,包括根节点和中间节点
if(c[i]==nodeArray.get(j).getChar()){
allCode+=nodeArray.get(j).getCode();
break ;
}
}
}
return allCode ;
}
public ArrayList<HFMNode> getArray(){
return this.array ;
}
}
测试类
测试描述: 传入一个字符串 String s = "abbcccddddeeeeeffffff"
打印个字符的权值和哈夫曼编码,以及生成哈夫曼树的结构
package tree;
public class TestApp {
public static void main(String[] args){
String s = "abbcccddddeeeeeffffff" ;
ConstructHFM h = new ConstructHFM(s);
h.getStringCode();
}
}
测试结果
******************以下是传入字符串的权值和哈夫曼编码
f的权值:6 哈夫曼编码:01
e的权值:5 哈夫曼编码:10
d的权值:4 哈夫曼编码:11
c的权值:3 哈夫曼编码:000
b的权值:2 哈夫曼编码:0010
a的权值:1 哈夫曼编码:0011
*******************以下是生成的哈夫曼树的结构
第0个节点为根节点,其权值为:21
第1个节点为中间节点,其权值为:12
第2个节点为中间节点,其权值为:9
第3个节点为中间节点,其权值为:6
第4个节点为叶节点 字符为:f 权值:6 哈夫曼编码为:01
第5个节点为叶节点 字符为:e 权值:5 哈夫曼编码为:10
第6个节点为叶节点 字符为:d 权值:4 哈夫曼编码为:11
第7个节点为叶节点 字符为:c 权值:3 哈夫曼编码为:000
第8个节点为中间节点,其权值为:3
第9个节点为叶节点 字符为:b 权值:2 哈夫曼编码为:0010
第10个节点为叶节点 字符为:a 权值:1 哈夫曼编码为:0011
*******************************************************
abbcccddddeeeeeffffff的哈夫曼编码是:001100100010000000000111111111010101010010101010101
相关推荐
### 哈夫曼树建立及编码 #### 一、哈夫曼树简介 哈夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树,在数据压缩编码领域有着广泛的应用。哈夫曼树是由David A. Huffman于1952年提出的,其...
《哈夫曼树建立与哈夫曼编码算法的实现》 哈夫曼树,又称为最优二叉树或最小带权路径长度树,是一种特殊的二叉树,广泛应用于数据压缩、编码等领域。哈夫曼编码是基于哈夫曼树的一种前缀编码方法,能够有效地提高...
下面我们将详细解析通过C语言实现哈夫曼树建立过程中所涉及到的知识点。 ### 标题解析 标题“哈夫曼树建立C语言.pdf”明确指出了文档的核心内容,即如何使用C语言来实现哈夫曼树的构建。 ### 描述解析 描述中提及...
哈夫曼树是一种在计算机科学中广泛使用的数据结构,尤其在数据压缩领域有着重要的应用。本实验报告主要探讨了如何运用哈夫曼树对文本文件进行编码和解压缩,以实现无损数据压缩。 首先,我们需要理解哈夫曼树的基本...
C++关于哈夫曼树的建立 哈夫曼树是一种特殊的二叉树,它的每个叶子结点都有一个权值,而非叶子结点的权值是其左右子树的权值之和。哈夫曼树的建立是数据压缩和编码中非常重要的一步。 哈夫曼树的建立可以使用贪心...
从终端读入字符集大小n , 以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 (2)E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读人),对文件ToBeTran中的正文进行编码,...
哈夫曼树(Huffman Tree),也称为最优二叉树,是一种带权路径长度最短的二叉树,常用于数据编码,特别是数据压缩。它通过构建一棵特殊的二叉树来实现字符编码,使得出现频率高的字符具有较短的编码,从而在整体上...
在给定的描述中,我们不仅要建立哈夫曼树,还需要展示每个节点的相关信息,包括: - **结点序号**:每个节点在树中的唯一编号,通常从1开始,按深度优先搜索或广度优先搜索顺序分配。 - **双亲结点**:对于非根节点...
在哈夫曼树建立完成后,我们可以使用哈夫曼树对文件ToBeTran中的正文进行编码。编码过程中,我们将使用哈夫曼树对每个字符进行编码,并将编码后的结果写入文件CodeFile中。 哈夫曼树的译码 在哈夫曼树建立完成后,...
1. 建立哈夫曼树:从用户输入的字符集和权值构建哈夫曼树,并将其存储在文件中。 2. 哈夫曼编码:利用哈夫曼树对文本文件进行编码,结果存储在CodeFile中,并在终端上以紧凑格式展示,每行显示50个编码。 3. 哈夫曼...
哈夫曼树是一种特殊的二叉树,用于解决数据压缩中的编码问题。它的构建基于贪心策略,通过将权值最小的节点不断合并来构建最小带权路径长度(Minimum Weight Path Length,MWPL)的二叉树。哈夫曼编码则是哈夫曼树的...
哈夫曼树的构建与C语言实现 哈夫曼树是一种特殊的二叉树,它的权值越小,越靠近根节点。哈夫曼树的构建是数据压缩和编码的重要组件。下面是哈夫曼树的构建与C语言实现的相关知识点: 一、哈夫曼树的定义 哈夫曼...
输入字符串,生成对应的哈弗曼数编码……大一数据结构课程实验。
哈夫曼树及哈夫曼编码译码的实现 哈夫曼树是一种特殊的二叉树,它的每个节点的权重是其所有子节点...通过本实验,我们掌握了哈夫曼树的建立和哈夫曼编码的算法,并了解了哈夫曼树在数据压缩、编码、译码等领域的应用。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上; 2.利用已经建好的哈夫曼树(如不在内存,则从文件htmTree中读入...
数据结构课设 哈夫曼树 C++源码 需要的拿去
### 哈夫曼树的应用:哈夫曼树的建立、编码与解码 #### 一、哈夫曼树的基本概念 哈夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树。在数据压缩领域有着广泛的应用,特别是在无损数据...
在本文中,我们将使用 C 语言实现哈夫曼树的编译码器,包括建立哈夫曼树、哈夫曼编码和哈夫曼解码三个部分。 一、哈夫曼树的建立 哈夫曼树的建立是通过利用堆排序和树合并的方法来实现的。首先,我们需要从终端...
- 建立哈夫曼树模块:基于输入数据构造哈夫曼树。 - 哈夫曼编码模块:遍历哈夫曼树生成编码,并输出编码规则。 - 译码模块:接收编码,根据编码规则进行解码并输出。 在实验结果部分,会展示具体实现的代码,以及对...