`
hh.凝望
  • 浏览: 64030 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

哈弗曼算法简介及应用

阅读更多

        哈夫曼算法就是应用哈夫曼树对对象进行编码的方法,哈夫曼算法的主要应用是文件压缩与解压。在介绍如何用java实现哈夫曼算之前先说一下路径和路径长度、结点的权及带权路径长度,树的带权路径,哈夫曼树的构造和哈夫曼编码。

1、路径和路径长度

  在一棵树中,从一个结点往下可以达到的孩子或子孙结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1

2、结点的权及带权路径长度

  若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

3、树的带权路径长度

  树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL

4、哈夫曼树的构造

  

   假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1wn,则哈夫曼树的构造规则为:

  (1) w1w2wn看成是有n 棵树的森林(每棵树仅有一个结点)

  (2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

  (3)从森林中删除选取的两棵树,并将新树加入森林;

(4)重复(2)(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。[

5、哈夫曼的编码

   哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。uffman1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。

6、用java实现哈夫曼树的建立

1.给定一段字符串,统计每一个字符出现的频率

2.根据这个频率,生成一个哈树,

3.当输入其中一个字符时,输出其在哈树上对应的哈码

 

1.首先构建数中的元素

//哈夫曼树的结点类型

 

public class HTreeNode<E> {

public HTreeNode parent;//父节点

public HTreeNode left;  //左节点

public HTreeNode right; //右节点

public  E Hdata;  //数据

}

1.  指定数据类型的内容

//树节点上的数据对象

public class TreeData {

 

public String s;//字符

  public int count;//出现频率

  }

3.import java.util.ArrayList;

import java.util.List;

public class HTreeTest {

//1.给定一段字符串,统计每一个字符出现的频率

public List<TreeData> getDatas(String s){

      List<TreeData>  datas=new ArrayList();

     

       for(int i=0;i<s.length();i++){

             char c=s.charAt(i);

             String cs=""+c;

             boolean exits=false;

             for(int t=0;t<datas.size();t++){

                   TreeData tem=datas.get(t);

                   if(tem.s.equals(cs)){//队中己有啦!

                        tem.count++;//出现了一次,累加吧

                        exits=true;

                        break;

                   }

             }

             if(!exits){

             //在创建对象,向队列中加入之前,要先查看队中是否己有?

             TreeData data=new TreeData();

             data.count=1;

             data.s=cs;

             datas.add(data);

             }

             

             

       }

     

      return datas;

}

public static void main(String[] args) {

      HTreeTest ht=new HTreeTest();

       String s="abcdefgaaaaaabbcccccccccccceff";

       List<TreeData> datas= ht.getDatas(s);

       System.out.println("排序前: ");

       for(int i=0;i<datas.size();i++){

             TreeData d=datas.get(i);

             System.out.println(d);

       }

       System.out.println("**********排序后: ");

       List<TreeNode> nods= ht.getNodes(datas);//转为节点队列了

       

       

         ht.sortNodes(nods);//排序

       for(int i=0;i<nods.size();i++){

             TreeNode<TreeData> td=nods.get(i);

             System.out.println(" "+td.data.s+" -- "+td.data.count);

         }

       //创建树:

       TreeNode root =ht.createHTree(nods);

       //打印哈码输出

       ht.pt(root,"");

       

 

        }

//将统计的Treedata对象队列,转为treeNode对象队列

public List<TreeNode> getNodes(List<TreeData> datas){

       List<TreeNode> nodes=new ArrayList();

      for(int i=0;i<datas.size();i++){

            TreeData data=datas.get(i);

             //创建node对象,data加入这个node

            TreeNode node=new TreeNode();

            node.data=data;

            //node(包含有data)放入队列中

            nodes.add(node);

      }

      return nodes;

}

//对节点对象队列根据权值排序,由小到大

public void sortNodes(List<TreeNode> nods){

      for(int i=0;i<nods.size();i++){

            for(int j=i+1;j<nods.size();j++){

                  TreeNode<TreeData> ni=nods.get(i);

                  TreeNode<TreeData> nj=nods.get(j);

                  //临时变量

//                     TreeNode<TreeData> tem=new TreeNode<TreeData>();

//                     TreeData temData=new TreeData();

//                     temData.s=nj.data.s;

//                     temData.count=nj.data.count;

//                     tem.data=temData;

                  int count=nj.data.count;

                  String s=nj.data.s;

                 

                  if(ni.data.count>nj.data.count){

                       nj.data.count=ni.data.count;

                       nj.data.s=ni.data.s;

                      

                       ni.data.count=count;

                       ni.data.s=s;

                  }

            }

      }

     

}

//根据生成的数据对象,创建一个哈树,返回树的根节点

public TreeNode createHTree(List<TreeNode> datas){

          while(true){

               //先要对节点队列排序

               sortNodes(datas);

              

      //假设传入队列数据权值都己排好了序,而且不用二次排序

      TreeNode<TreeData> left=datas.remove(0);

      TreeNode<TreeData> right=datas.remove(0);

      //创建一个父节点

      TreeNode<TreeData> root=new TreeNode();

      //给父节点设数据:

      TreeData td=new TreeData();

      td.count=left.data.count+right.data.count;

      td.s="父节";

      root.data=td;

      //关联关系

      root.left=left;

      root.right=right;

      left.parent=root;

      right.parent=root;

      if(datas.size()==0){//是最后一个了,根节点,反回

            return root;

      }

      //将父节放入队中首位:

      datas.add(0, root);

      }

       

}

/**

 * 根据输入的字符input,取得其在哈树上的哈码返回

 * @param input:输入的字符

 * @param hRoot:哈树的根节点

 * @return:从树上取得的哈夫曼编码

 */

public String getHM(String input,TreeNode hRoot){

      return null;

}

//遍历树来打印,输出叶的哈码

public void pt(TreeNode<TreeData> root,String hm){

       if(null!=root){

             if(root.left==null&&root.right==null){

             TreeData d=root.data;

             System.out.println(d+" 哈码是:"+hm);//打印

             }

             TreeNode<TreeData> left=root.left;

             String m=hm+="0";

             pt(left,m);

             

             TreeNode<TreeData> right=root.right;

             pt(right,hm+="1");

       }

}

}

 

 

 

 

分享到:
评论

相关推荐

    哈弗曼算法及其实现

    ### 哈弗曼算法及其实现 哈弗曼算法是一种在数据压缩领域广泛应用的算法,主要用于构建一种称为哈弗曼...以上分析涵盖了哈弗曼算法的核心概念、实现原理及具体的C语言代码实现细节,有助于深入理解该算法的工作机制。

    树 哈弗曼算法。二叉树遍历的应用。矩阵的相乘

    哈弗曼算法的核心思想在于构建一棵哈弗曼树,这是一种根据字符出现的频率来建立的二叉树。在哈弗曼树中,字符以叶子节点的形式出现,频率越高的字符离根节点越近。如此一来,高频字符被赋予更短的编码,而低频字符则...

    哈弗曼算法的一个应用小程序

    对输入的一串点文字符实现哈弗曼编码,在对哈弗曼编码生成代码串进行译码,输出电文字符串

    C++哈弗曼算法实现

    在提供的压缩包文件中,很可能是包含了一个C++实现哈弗曼算法的源代码文件,可能包括了以上提到的各种功能。通过阅读和理解这段代码,你可以学习到哈弗曼编码的实现细节,并了解如何在C++中进行数据压缩。如果你想要...

    哈弗曼算法[参照].pdf

    通过实验,学生可以深入理解二叉树的概念,掌握哈弗曼编码算法的原理及其实际应用。实验结果分析通常涉及编码效率的评估,如压缩率的计算,以及编码过程的优化可能。此外,对于哈弗曼编码的实际应用,例如在图像和...

    哈弗曼编码哈弗曼编码

    文件名列表中的"Huffman"可能是一个与哈弗曼编码相关的程序、工具或者示例数据集,用于学习或实践哈弗曼编码算法。在处理这样的文件时,用户可能需要了解如何读取文件,解析字符频率,构建哈弗曼树,以及如何根据...

    哈弗曼算法实现压缩和解压

    通过分析和理解这些代码,我们可以学习如何在实际应用中构建和使用哈弗曼编码。同时,这个工具可能是以命令行或者图形用户界面的形式存在,方便用户输入数据进行压缩和解压缩操作。 总的来说,哈弗曼编码是一种有效...

    C++ 哈弗曼算法

    哈弗曼编码(Huffman Coding)是一种用于数据压缩的高效算法,由大卫·艾伦·赫夫曼在1952年提出。这种算法利用了字符出现频率的不均匀性,构建了一种特殊的二叉树——哈弗曼树(Huffman Tree),也称为最优二叉树,...

    哈弗曼编码算法设计

    本实验涉及的主要内容是利用哈弗曼算法来构造一个最短的不等长编码方案。假设我们有一个字符集`{d1,d2,…,dn}`,每个字符的出现频率分别为`{w1,w2,…,wn}`。实验的具体步骤如下: 1. **哈弗曼算法**: - **初始...

    数据结构 prim算法、哈弗曼算法、拓扑排序算法。

    这三种算法都是在C++环境下实现的,C++是一种广泛应用的面向对象编程语言,具有高效性和灵活性。 1. Prim算法: Prim算法是一种用于寻找图中最小生成树的算法,特别适用于解决网络连接优化的问题。它从一个顶点开始...

    哈弗曼算法实现

    哈弗曼编码(Huffman Coding)是一种用于数据压缩的高效算法,由大卫·艾伦·哈弗曼在...通过理解和掌握哈弗曼算法,我们可以优化数据存储,提高传输效率,尤其在文本、图像和音频等大数据量的领域中具有广泛应用价值。

    哈弗曼编码及应用 数据结构

    在这个课程设计中,我们将深入探讨哈弗曼编码的原理、解码过程以及其在实际应用中的价值。 首先,哈弗曼编码的基本思想是通过构建一个特殊的二叉树(哈弗曼树)来为每个字符或符号分配一个唯一的二进制编码。构建...

    哈弗曼编码算法源代码

    在实际应用中,哈弗曼编码被广泛用于文本压缩、图像压缩等领域。例如,在JPEG图像压缩标准中,哈弗曼编码被用来压缩颜色分量。同时,它也是通信领域中一种重要的数据传输编码方式,可以减少传输时间并降低错误率。 ...

    哈弗曼编码 贪心算法课程设计

    哈弗曼编码(Huffman Coding)是一种广泛应用于数据压缩领域的编码技术,由David A. Huffman于1952年提出。它是一种基于字符出现频率进行编码的变长编码方式,能够有效地减少数据的存储空间和传输时间。本次实验旨在...

    HaffmanCode.rar_哈弗曼 压缩算法_哈弗曼c++_数据压缩

    总的来说,哈弗曼编码是数据结构和算法中的一个重要概念,它不仅理论性强,而且具有实际应用价值。学习和理解哈弗曼编码能够帮助我们深入理解数据压缩的原理,提升我们在处理大量数据时的效率。

    关于哈弗曼树的一个算法

    哈弗曼树,又称最优二叉树,是一种带权路径长度最短的二叉树,由美国计算机科学家哈弗曼在1952年提出...了解并掌握哈弗曼树的原理和实现,对于理解数据压缩技术,优化算法效率,以及进行相关的编程实践都是非常有益的。

    哈弗曼压缩解压算法代码.rar

    在实际应用中,哈弗曼编码通常与其他压缩技术结合使用,如在ZIP和GZIP等压缩格式中,哈弗曼编码是作为LZ77或LZ78等滑动窗口压缩算法的后续步骤,以进一步提升压缩率。 从提供的压缩文件"201121421219072"中,我们...

    利用哈弗曼编码做的压缩程序 源代码

    哈弗曼编码在实际应用中广泛用于文本、图像和音频等数据的压缩,比如在JPEG图像压缩标准和MP3音频压缩标准中都有其身影。虽然本压缩程序的压缩比可能并不高,但它的算法设计和实现技巧仍然具有学习价值,可以帮助...

Global site tag (gtag.js) - Google Analytics