huffman编码详解与java代码实现

13人阅读 评论(0) 收藏 举报
分类:

huffman编码

字符编码

编码分为定长编码和不定长编码。定长编码实现简单,效率高。不定长编码是为了压缩数据而提出的编码方式:给使用频率高的字符短的编码。那么到底如何给字符编码,而使平均长度最短呢?huffman就是解决这个问题的。

不定长编码

先介绍一下前缀编码

在一个编码系统中,任何一个编码都不是其他编码的前缀,则称该编码系统的编码是前缀码。例如: 01, 10, 110, 111, 101 就不是前缀编码,因为 10 是 101 的前缀,如果去掉 10或101就是前缀编码。当在一个编码系统中采用定长编码时,可以不需要分隔符;如果采用不定长编码时,必须使用前缀编码或分隔符,否则在解码时会产生歧义。所谓解码就是由二进制位串还原字符数据的过程。而使用分隔符会加大编码长度,因此一般采用前缀编码。

前缀编码可以通过二叉树来实现:
使用二叉树对字符集中的字符进行编码的方法是,将字符集中的所有字符作为二叉树的叶子结点;在二叉树中,每一个“父亲—左孩子”关系对应一位二进制位 0,每一个“父亲—右孩子”关系对应一位二进制位 1;于是从根结点通往每个叶子结点的路径,就对应于相应字符的二进制编码。每个字符编码的长度 L 等于对应路径的长度,也等于该叶子结点的层次数。
这里写图片描述

huffman编码

而如何使得二叉树得到的编码是最优的,也就是平均编码长度,也可以说树的叶子结点的平均深度最小?huffman编码解决了这一问题。其编码步骤如下:
1. 根据给定的 n 个权值,构造 n 棵只有一个根结点的二叉树, n 个权值分别是这些二叉树根结点的权, F 是由这 n 棵二叉树构成的集合;
2. 在 F 中选取两棵根结点树值最小的树作为左、右子树,构造一颗新的二叉树,置新二叉树根的权值=左子树根结点权值+右子树根结点权值;
3. 从 F 中删除这两颗树,并将新树加入 F;
4. 重复以上步骤,直到只剩下最后一颗树。
如下图所示(图截自java数据结构与算法 作者:周鹏):
这里写图片描述

huffman编码正确性证明

个人理解:
通过huffman编码构造的树,每一步都满足这样一个性质:权值最小的节点层数最大。由这个性质可以推断,无论如何,都无法构造出一颗总权值更小的树。所以huffman编码是最优的。

java代码实现

二叉树节点:

package dataStructureAndAlgorithms;

public class HuffmanTreeNode implements Comparable<HuffmanTreeNode>{
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public HuffmanTreeNode getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(HuffmanTreeNode leftChild) {
        this.leftChild = leftChild;
    }

    public HuffmanTreeNode getRightChild() {
        return rightChild;
    }

    public void setRightChild(HuffmanTreeNode rightChild) {
        this.rightChild = rightChild;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    private String content = null;
    private int weight;
    private String code = "";
    private HuffmanTreeNode leftChild = null;
    private HuffmanTreeNode rightChild = null;


    public HuffmanTreeNode(int weight){
        this.weight = weight;
    }

    //Returns:a negative integer, zero, or a positive integer as this object is
    //less than, equal to, or greater than the specified object.
    public int compareTo(HuffmanTreeNode o) {
        if(weight<o.getWeight()){
            return -1;
        }else if(weight > o.getWeight()){
            return 1;
        }else{
            return 0;
        }
    }
}

哈夫曼编码:

package dataStructureAndAlgorithms;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;


public class HuffmanCode {
    public static HuffmanTreeNode buildHuffmanTree(List<HuffmanTreeNode> nodes){
        int n = nodes.size();
        //n-1次
        for(int i=1;i<n;i++){
            Collections.sort(nodes);

            HuffmanTreeNode min1 = nodes.remove(0);
            HuffmanTreeNode min2 = nodes.remove(0);
            HuffmanTreeNode newNode = new HuffmanTreeNode(min1.getWeight()+min2.getWeight());
            newNode.setLeftChild(min1);
            newNode.setRightChild(min2);
            nodes.add(newNode);
        }
        return nodes.get(0);
    }

    public static void generateHuffmanCode(HuffmanTreeNode root){
        if(root.getLeftChild() != null){
            root.getLeftChild().setCode(root.getCode() + "0");
            generateHuffmanCode(root.getLeftChild());
        }

        if(root.getRightChild() != null){
            root.getRightChild().setCode(root.getCode() + "1");
            generateHuffmanCode(root.getRightChild());
        }
    }

    public static void main(String[] args) {
        HuffmanTreeNode node1 = new HuffmanTreeNode(3);
        node1.setContent("A");
        HuffmanTreeNode node2 = new HuffmanTreeNode(1);
        node2.setContent("B");
        HuffmanTreeNode node3 = new HuffmanTreeNode(2);
        node3.setContent("C");
        HuffmanTreeNode node4 = new HuffmanTreeNode(1);
        node4.setContent("D");

        List<HuffmanTreeNode>nodes = new LinkedList<HuffmanTreeNode>();
        nodes.add(node1);
        nodes.add(node2);
        nodes.add(node3);
        nodes.add(node4);

        List<HuffmanTreeNode>nodeCopy = new ArrayList<HuffmanTreeNode>();
        nodeCopy.addAll(nodes);


        HuffmanTreeNode root = buildHuffmanTree(nodes);
        generateHuffmanCode(root);


        for(HuffmanTreeNode node:nodeCopy){
            System.out.println(node.getContent() + "->" + node.getCode());
        }
    }
}

结果:

A->0
B->110
C->10
D->111

查看评论

利用DPCM&Huffman编码实现数据压缩_C语言实现

一、实验原理        DPCM是差分预测编码调制的缩写,它利用过去的抽样值来预测当前的抽样值,对它们的差值进行编码。差值编码可以提高编码频率,这种技术已应用于模拟信号的数字通信之中。图像内的像...
  • vacu_um
  • vacu_um
  • 2017-05-22 14:51:34
  • 188

Huffman编码算法之Java实现

Huffman编码介绍 Huffman编码处理的是字符以及字符对应的二进制的编码配对问题,分为编码和解码,目的是压缩字符对应的二进制数据长度。我们知道字符存贮和传输的时候都是二进制的(计算机只认识0/...
  • kimylrong
  • kimylrong
  • 2013-11-29 11:55:15
  • 25250

Huffman编码---java实现

算法是准确的,目前程序还有一点点小bug
  • u010481185
  • u010481185
  • 2014-08-22 22:44:56
  • 1126

[信息论]Huffman编码的JAVA实现

Huffman编码的JAVA实现 (这里算法就不给出了,有兴趣的读者可以参考相关书籍,这里只给出JAVA实现的思路,仅供参考,毕竟水平有限)。 该实验降低了复杂度,仅仅研究二元码,不考虑的编码,所以不...
  • u010536377
  • u010536377
  • 2015-04-03 23:42:03
  • 896

Huffman 压缩解压缩java实现

本文介绍了利用Huffman编码对文件进行压缩和解压缩的过程。其中使用了java做为编程语言。为大家提供参考。本文只实现了对文本文件进行压缩和解压缩,对二进制文件压缩解压缩留待大家研究。完整工程留待以...
  • u010485034
  • u010485034
  • 2014-06-14 16:14:16
  • 1950

课件 Huffman 树编码

  • 2010年07月12日 08:51
  • 691KB
  • 下载

Huffman编码的C语言实现

Huffman 编码(1) Huffman Coding (霍夫曼编码)是一种无失真编码的编码方式,Huffman 编码是可变字长编码(VLC)的一种。 (2)Huffman 编码基于信源的概率统计...
  • yingqi_lok
  • yingqi_lok
  • 2017-04-19 22:12:30
  • 1487

Huffman 压缩解压缩 Java实现

  • 2014年08月31日 19:24
  • 6.41MB
  • 下载

Huffman编码实现压缩解压缩

Huffman编码实现压缩解压缩 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明 Huffm...
  • u013290075
  • u013290075
  • 2016-04-04 23:22:05
  • 1990

【数据压缩】Huffman原理与代码实现

Huffman算法也是一种无损压缩算法,但与上篇文章LZW压缩算法不同,Huffman需要得到每种字符出现概率的先验知识。通过计算字符序列中每种字符出现的频率,为每种字符进行唯一的编码设计,使得频率高...
  • luoshixian099
  • luoshixian099
  • 2015-12-21 23:00:14
  • 7084
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 1119
    排名: 4万+
    最新评论