Java 霍夫曼编码(Huffman Coding)

标签: 霍夫曼编码 Java 信息论编码
12人阅读 评论(2) 收藏 举报
分类:

霍夫曼编码的具体步骤如下

1)将信源符号的概率按减小的顺序排队。

2)把两个最小的概率相加,并继续这一步骤,始终将较高的概率分支放在右边,直到最后变成概率1。

3)画出由概率1处到每个信源符号的路径,顺序记下沿路径的0和1,所得就是该符号的霍夫曼码字。   

4)将每对组合的左边一个指定为0,右边一个指定为1(或相反)
  1. 思路:一个节点类包括权重,父亲左儿子,右儿子节点,flag 的false表示已经使用过了,下次找两个最小的不会再找这个false掉的了,parentPath表示儿子到父亲的路径上的数字,左边为0,右边为1(我这个里面设置了左边儿子比右边儿子小),存储哈夫曼节点;然后一个list存储刚输入的码的权重生成的节点,每次查找flag为true的两个最小的权重的节点,生成父节点,设置相关节点的属性值;最后输出编码,不用遍历树,直接找到要编码的码,然后一路向上查找parentPath的值就是编码的倒序,故采用栈来保存,最后输出编码就是正确的编码格式。
  2. 话不多说,上代码:
package com.leibobo;

/**
 * Created by bobolei 18/4/13
 *哈夫曼节点定义
 */

public class NodeHuffman {

    //权重,标志位,父节点,左右儿子
    //flag = false表示还没有进行合并,即还是一个没有归类的节点
    //创建树的过程中直接标记哈夫曼编码,根节点父路劲为-1,其他父路径自己是左儿子,则为0,右儿子,则为1,后面直接找到要编码的数,向上查找即是哈夫曼编码的反路劲,翻转即可。。。哈哈哈哈,我号机智
    private int weight;
    private boolean flag; //默认false
    private int parentPath;  //默认是0
    public int getParentPath() {
        return parentPath;
    }

    public void setParentPath(int parentPath) {
        this.parentPath = parentPath;
    }

    private NodeHuffman parent,lChild,rChild;

    public NodeHuffman(){

    }

    public NodeHuffman(int weight){
        this.weight = weight;
        flag = true;
        parent = lChild = rChild = null;
    }

    public int getWeight() {
        return weight;
    }

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

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public NodeHuffman getParent() {
        return parent;
    }

    public void setParent(NodeHuffman parent) {
        this.parent = parent;
    }

    public NodeHuffman getlChild() {
        return lChild;
    }

    public void setlChild(NodeHuffman lChild) {
        this.lChild = lChild;
    }

    public NodeHuffman getrChild() {
        return rChild;
    }

    public void setrChild(NodeHuffman rChild) {
        this.rChild = rChild;
    }


}
package com.leibobo;

import java.util.List;

/**
 * Created by bobolei 18/4/13
 *哈夫曼节点定义
 */

public class SelectTwoMin {
    //获取节点list中权重最小的两个,并返回,0,1大
        public NodeHuffman[] getMinTwo(List<NodeHuffman> listHuffman){
            NodeHuffman big = null;
            NodeHuffman small = null;

            for(int i = 0;i < listHuffman.size();i++){
                if(listHuffman.get(i).isFlag()){
                    if(small == null){
                        small = listHuffman.get(i);
                        continue;
                    }
                    if(small != null && big == null){
                        if(small.getWeight() > listHuffman.get(i).getWeight()){
                            big = small;
                            small = listHuffman.get(i);
                        }else{
                            big = listHuffman.get(i);
                        }
                        continue;
                    }
                    if(small != null && big != null){
                        if(listHuffman.get(i).getWeight() < big.getWeight() && listHuffman.get(i).getWeight() > small.getWeight()){
                            big = listHuffman.get(i);
                        }
                        if(listHuffman.get(i).getWeight() < small.getWeight()){
                            big = small;
                            small = listHuffman.get(i);
                        }
                    }
                }else{
                    continue;
                }
            }
            NodeHuffman[] minTwoHuffman = {small,big};
            return minTwoHuffman;       
        }
}
package com.leibobo;

import java.util.ArrayList;
import java.util.List;
/**
 * Created by bobolei 18/4/13
 *哈夫曼节点定义
 */

public class TreeHuffman {

    public List<NodeHuffman> getHuffmanTreeList(int[] weight,List<NodeHuffman> huffmanTreeList){
        int m=2*weight.length-1;
        //生成原始的Huffman节点
        for(int i = 0;i < weight.length;i++){
            NodeHuffman nodeHuffman = new NodeHuffman(weight[i]);
            huffmanTreeList.add(nodeHuffman);
        }

        SelectTwoMin selectTwoMin = new SelectTwoMin();
        for(int j = weight.length;j < m;j++){
            NodeHuffman[] minTwoHuffman = selectTwoMin.getMinTwo(huffmanTreeList);
            System.out.println("最小的两个:"+minTwoHuffman[0].getWeight()+"  "+minTwoHuffman[1].getWeight());
            minTwoHuffman[0].setFlag(false);
            minTwoHuffman[0].setParentPath(0);
            minTwoHuffman[1].setFlag(false);
            minTwoHuffman[1].setParentPath(1);

            NodeHuffman newNode = new NodeHuffman();
            newNode.setFlag(true);
            newNode.setlChild(minTwoHuffman[0]);
            newNode.setrChild(minTwoHuffman[1]);
            newNode.setWeight(minTwoHuffman[0].getWeight()+minTwoHuffman[1].getWeight());
            newNode.setParentPath(-1);
            newNode.setParent(null);

            huffmanTreeList.add(newNode);

            minTwoHuffman[0].setParent(huffmanTreeList.get(j));
            minTwoHuffman[1].setParent(huffmanTreeList.get(j));
        }
        return  huffmanTreeList;        
    }   
}
package com.leibobo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;

/**
 * Created by bobolei 18/4/13
 *哈夫曼节点定义
 */
//java中方法传递的只是引用,不是对象,即一个对象通过方法操作返回的还是这个对象,只不过两个地方是不同的引用而已
public class Main {

    public static void main(String[] args) {

        // TODO Auto-generated method stub  

        Scanner sc=new Scanner(System.in);  
        System.out.println("输入编码的字符:");
        String code = sc.nextLine();
        System.out.println("请输入以此对应的次数:");
        String[] nums = null;   
        nums = sc.nextLine().split(" ");   
        int inputInt[]=new int[nums.length];  
        for(int i=0;i<inputInt.length;i++){  
            inputInt[i]=Integer.valueOf(nums[i]);  
        } 

        for(int j = 0;j < inputInt.length;j++){
            System.out.print(inputInt[j]+" ");
        }
        System.out.println(" ");

        //int[] inputInt={23,11,5,3,29,14,7,8};
        //int[] inputInt={12,6,2,18};
        System.out.println("输出:");
        Map<Integer,Stack<Integer>> map = new HashMap<Integer,Stack<Integer>>();
        List<NodeHuffman> huffmanTreeList = new ArrayList<NodeHuffman>();
        TreeHuffman treeHuffman = new TreeHuffman();
        treeHuffman.getHuffmanTreeList(inputInt, huffmanTreeList);

        for(int j = 0;j < inputInt.length;j++){
            boolean mark = true;
            Stack<Integer> stack = new Stack<Integer>();
            NodeHuffman node = huffmanTreeList.get(j);
            System.out.print("code:"+code.charAt(j)+" 权重:"+huffmanTreeList.get(j).getWeight() + "编码 :");
            while(mark){
                if(node.getParentPath() != -1){
                    System.out.print(node.getParentPath());
                    stack.push(node.getParentPath());
                    node = node.getParent();
                }else{
                    mark = false;
                }
            }
            System.out.println(" ");
            map.put(huffmanTreeList.get(j).getWeight(), stack);
        }
    }
}
查看评论

J2ME (Java 2 Micro Edition) 简介

■前言      如果您曾经到http://www.javasoft.com 网站上查询有关Java 2 Micro Edition 的资料,十之八九会被一大堆的技术名词搞的一头雾水。什么 KVM ,...
  • jiangtao
  • jiangtao
  • 2001-04-13 09:39:00
  • 3592

霍夫曼编码(Huffman Coding)原理及MATLAB程序实现

霍夫曼编码(Huffman Coding)是一种编码方法,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码...
  • C_1_2_3
  • C_1_2_3
  • 2017-12-30 23:07:11
  • 238

Huffman编码算法之Java实现

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

用PriorityQueue实现哈夫曼编码

哈夫曼编码(Huffman Coding) 哈夫曼编码是一种被广泛应用而且非常有效的数据压缩技术,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文...
  • shuxiangxingkong
  • shuxiangxingkong
  • 2014-02-21 10:27:14
  • 938

ZOJ2339 Hyperhuffman(霍夫曼编码长度)

题目: Hyperhuffman Time Limit: 5 Seconds      Memory Limit: 32768 KB You might have heard a...
  • riba2534
  • riba2534
  • 2017-04-20 21:02:34
  • 247

霍夫曼编码(Huffman Coding)

霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种。 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符...
  • xgf415
  • xgf415
  • 2016-09-22 21:44:16
  • 32278

基于matlab的huffman编解码

  • qingkongyeyue
  • qingkongyeyue
  • 2017-06-22 14:44:43
  • 1054

java实现霍夫曼编码的小程序

输入的数字之间只能有一个空格!package codeTest; import java.awt.Color; import java.awt.GridBagConstraints; import ...
  • qizihappy
  • qizihappy
  • 2013-12-17 14:45:48
  • 1055

[python]Huffman Encoding哈夫曼编码

#Huffman Encoding#Tree-Node Type class Node: def __init__(self,freq): self.left = None ...
  • sinat_16968575
  • sinat_16968575
  • 2015-03-25 19:13:42
  • 2940

huffman编码 数字图像处理 霍夫曼编码matlab源代码及解释

  • 2010年02月05日 23:07
  • 5KB
  • 下载
    个人资料
    持之以恒
    等级:
    访问量: 989
    积分: 152
    排名: 110万+
    文章存档
    最新评论