霍夫曼编码

作者: 9c0ddf06559c | 来源:发表于2017-10-09 21:05 被阅读19次

问题: 请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短

思路:使用霍夫曼编码构造字符串编码,字符串中字母出现的频率为权重,最后每一个字母的霍夫曼编码长度总和即为最短长度

源码

import java.util.*;

/**
 * Created by gaowenfeng on 2017/10/9.
 */
public class Huffman {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        System.out.println(createHuffman(s));
    }

    private static int createHuffman(String s) {

        //1.构造字符频率集
        Map<Character,Integer> map = new HashMap<>();
        char[] chars = s.toCharArray();
        for(char c:chars){
            if(map.containsKey(c))
                map.put(c,map.get(c)+1);
            else
                map.put(c,1);
        }
        //2.构造由权重值为比较依据的优先队列(最小堆,每次等到weight最小的节点)
        PriorityQueue<HuffmanNode> queue = new PriorityQueue<>(
                map.size(), Comparator.comparingInt(t->t.weight)
        );
        //3.构造霍夫曼树
        for(Map.Entry<Character,Integer> entry:map.entrySet()){
            queue.offer(new HuffmanNode(entry.getValue(),entry.getKey()));
        }
        //构建霍夫曼树并合并两个权重最小的节点,直至只剩根节点
        while (queue.size()>1){
            //1.弹出两个权重最小的节点
            HuffmanNode leftNode = queue.poll();
            HuffmanNode rightNode = queue.poll();
            //2.合并为一个新节点
            HuffmanNode fatherNode = new HuffmanNode(leftNode.weight+rightNode.weight);
            fatherNode.leftChild=leftNode;
            fatherNode.rightChild=rightNode;
            //3.将新节点放入队列
            queue.offer(fatherNode);
        }
        HuffmanNode treeRoot = queue.poll();
        //4.计算霍夫曼树的长度,初始深度为0,因为最后弹出的一定是合并过的
        return getLength(treeRoot,0);
    }

    /**
     * 获取霍夫曼节点的长度
     * @param root 节点
     * @param depth 当前深度
     * @return
     */
    private static int getLength(HuffmanNode root, int depth) {
        if(root==null)
            return 0;
        return (root.ch==null?0:root.weight)*depth+getLength(root.leftChild,depth+1)+getLength(root.rightChild,depth+1);
    }


}
class HuffmanNode{
    int weight;  //字符串中字母出现的频率即为权重;
    Character ch;  //若为组合字符串,则为null,否则为原字符;
    HuffmanNode leftChild;
    HuffmanNode rightChild;

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

    public HuffmanNode(int weight, Character ch) {
        this.weight = weight;
        this.ch = ch;
    }
}

摘自 http://www.cnblogs.com/GumpYan/p/5861605.html

相关文章

  • 霍夫曼编码

    概念 霍夫曼编码(Huffman Coding),又译为哈夫曼编码、赫夫曼编码,是一种用于无损数据压缩的熵编码(权...

  • 霍夫曼编码

    问题: 请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短 思路:使用霍夫曼编码构造字符串编码...

  • 霍夫曼(Huffman)编码

    一、定义 霍夫曼(Huffman)编码是一种编码方式,主要用于数据文件的压缩。它的主要思想是放弃文本文件的普通保存...

  • 构造霍夫曼编码

    最终结果如下:

  • 图解霍夫曼编码

    【转】图解霍夫曼编码 以下文章来源于沉默王二 ,作者沉默王二 今天来给大家普及一下霍夫曼编码(Huffman Co...

  • 哈夫曼树

    戴维·哈夫曼【David Huffman】 著名的“霍夫曼编码”的发明人戴维.霍夫曼 (David Albert ...

  • 学会霍夫曼编码后,再也不用担心硬盘存不下影片了!

    图解霍夫曼编码,教不会我吃一包辣条 大家好,我是沉默王二。 今天来给大家普及一下霍夫曼编码(Huffman Cod...

  • 哈夫曼编码

    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一...

  • 数据结构——哈夫曼(Huffman)树+哈夫曼编码

    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一...

  • 十七. java数据结构 - 赫夫曼编码概述

    1.基本介绍 赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 属...

网友评论

    本文标题:霍夫曼编码

    本文链接:https://www.haomeiwen.com/subject/lqxmyxtx.html