java实现哈夫曼编码(huffman)编码

  这篇博客主要讲解如何用java实现哈夫曼编码(Huffman)。

概念

  首先,我来简单说一下哈夫曼编码(Huffman),它主要是数据编码的一种方式,也是数据压缩的一种方法,将某些特定的字符转化为二进制字符,并在转换过程中降低原有字符串的存储量。其具体方法是先按出现的概率大小排队,把两个最小的概率相加,作为新的概率 和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。每次相 加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的“1”, 将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的哈夫曼编码。

java实现

方法一:

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

import static java.lang.System.out;
/*    设某信源有5种符号x={A1,A2,A3,A4,A5}。在数据中出现的概率p={0.25,0.22,0.20,0.18,0.15},试给出Huffman编码方案,写出每个符号对应的Huffman编码。*/
/*    答案1:A1:10  A2:01  A3:00  A4:111   A5:110
    答案2:A1:01  A2:10  A3:11  A4:000   A5:001*/

/**
 * 哈夫曼树构造类:
 */

public class OtherPersonMethodHuffman {
    public static void main(String[] args) {
        List<Node> nodes = Arrays.asList(
                new Node(0.25d),
                new Node(0.22d),
                new Node(0.20d),
                new Node(0.18d),
                new Node(0.15d)
        );
        Node node = OtherPersonMethodHuffman.build(nodes);
        PrintTree(node);
    }

    /**
     * 构造哈夫曼树
     * @param nodes 结点集合
     * @return 构造出来的树的根结点
     */

    private static Node build(List<Node> nodes) {
        nodes = new ArrayList<Node>(nodes);
        sortList(nodes);
        while (nodes.size() > 1) {
            createAndReplace(nodes);
        }
        return nodes.get(0);
    }

    /**
     * 组合两个权值最小结点,并在结点列表中用它们的父结点替换它们
     * @param nodes 结点集合
     */
    private static void createAndReplace(List<Node> nodes) {
        Node left = nodes.get(0);
        Node right = nodes.get(1);
        Node parent = new Node(left.getValue() + right.getValue());
        parent.setLeftChild(left);
        parent.setRightChild(right);
        nodes.remove(0);
        nodes.remove(0);
        nodes.add(parent);
        sortList(nodes);
    }

    /**
     * 将结点集合由大到小排序
     */

    private static void sortList(List<Node> nodes) {
        Collections.sort(nodes);
    }

    /**
     * 打印树结构,显示的格式是node(left,right)
     * @param node
     */
    static  String[] strs = {"1","1","1","1","1"};
    public static void PrintTree(Node node) {
        Node left = null;
        Node right = null;

        double[] probDoubles={0.25d,0.22d,0.20d,0.18d,0.15d};
        if(node!=null) {
            out.print(node.getValue());
            left = node.getLeftChild();
            right = node.getRightChild();
            out.println("("+(left!=null?left.getValue():" ") +","+ (right!= null?right.getValue():" ")+")");
            if(left!=null){
                for(int i=0;i<strs.length;i++){
                    strs[i]+="0";
                }
            }
            if(right!=null){
                for(int i=0;i<strs.length;i++){
                    strs[i]+="1";
                }
            }
        }
        if(left!=null){ PrintTree(left); }

        if(right!=null){ PrintTree(right); }

        if(left==null&right==null){
            out.println(node.getValue());
            for(int i=0;i<probDoubles.length;i++){
                if(probDoubles[i]==node.getValue()){
                    out.println(strs[i]);
                }
            }
        }
    }
}

/**
 * 二叉树节点
 */

class Node implements Comparable {
    private double value;
    private Node leftChild;
    private Node rightChild;
    public Node(double value) {
        this.value = value;
    }

    public double getValue() {
        return value;
    }

    public void setValue(double value) {
        this.value = value;
    }

    public Node getLeftChild() {
        return leftChild;
    }

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

    public Node getRightChild() {
        return rightChild;
    }

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

    @Override
    public int compareTo(Object o) {
        Node that = (Node) o;
        double result = this.value - that.value;
        return result > 0 ? 1 : result == 0 ? 0 : -1;
    }
}


猜你喜欢

转载自blog.csdn.net/weixin_37610397/article/details/80222991
今日推荐