java使用优先级队列实现哈夫曼编码

思路:
  1. 构建小根堆
  2. 根据小根堆实现哈夫曼树
  3. 根据哈夫曼树对数据进行编码
代码实现如下:
/**
 * @Author: DaleyZou
 * @Description: 使用java实现一个哈夫曼编码的小程序
 * @Date: Created in 19:45 2018-9-27
 * @Modified By:
 */
public class HuffmanCode {
    private class Node implements Comparable<Node>{
        char ch; // 字符
        int freq; // 权值
        boolean isLeaf;  // 是否是叶子节点
        Node left, right;  // 父节点的左节点和右节点

        // 初始化一个带权值的叶子节点
        public Node(char ch, int freq){
            this.ch = ch;
            this.freq = freq;
            this.isLeaf = true;
        }

        // 构建一个节点,带左右节点
        public Node(Node left, Node right, int freq){
            this.left = left;
            this.right = right;
            this.freq = freq;
            this.isLeaf = false;
        }

        @Override
        public int compareTo(Node node) {
            return this.freq - node.freq;
        }
    }

    // 构建一颗哈夫曼树
    public Map<Character, String> encode(Map<Character, Integer> frequencyForChar){
        PriorityQueue<Node> priorityQueue = new PriorityQueue<>();
        for (Character ch : frequencyForChar.keySet()){
            priorityQueue.add(new Node(ch,frequencyForChar.get(ch)));
        }
        while (priorityQueue.size() != 1){ // 构建小根堆
            Node left = priorityQueue.poll();
            Node right = priorityQueue.poll();
            priorityQueue.add(new Node(left, right, left.freq + right.freq));
        }
        return encode(priorityQueue.poll());
    }

    public Map<Character, String> encode(Node root){
        HashMap<Character, String> hashMap = new HashMap<>();
        encode(root, "", hashMap);
        return hashMap;
    }

    public void encode(Node root, String encoding, HashMap<Character,String> hashMap) {
        if (root.isLeaf){ // 已经到叶子节点,递归结束
            hashMap.put(root.ch, encoding);
            return;
        }
        encode(root.left, encoding + "0" ,hashMap);     // 编码左节点
        encode(root.right, encoding + "1", hashMap);    // 编码右节点
    }

    // 测试结果是否正确
    public static void main(String[] args){
        Map<Character, Integer> frequencyForChar = new HashMap<>();
        frequencyForChar.put(‘a‘, 10);
        frequencyForChar.put(‘b‘, 20);
        frequencyForChar.put(‘c‘, 40);
        frequencyForChar.put(‘d‘, 80);

        HuffmanCode huffmanCode = new HuffmanCode();
        Map<Character, String> encode = huffmanCode.encode(frequencyForChar);
        for (Character ch : encode.keySet()){
            System.out.println(ch + " : " + encode.get(ch));
        }
    }

}

不使用优先级队列,自己手动实现小根堆

原文地址:https://www.cnblogs.com/daleyzou/p/9715493.html

时间: 2024-11-09 04:50:20

java使用优先级队列实现哈夫曼编码的相关文章

项目实战——基于LZ77变形和哈夫曼编码的GZIP压缩

文件压缩: 日常生活中有很多压缩的例子,比如给很长的名字取一个缩写--西安交通大学简称西交大,这样就给我们的生活提供了很大的便捷,那么什么又是文件压缩呢?文件压缩就是将文件通过一些方法变得更小,解压缩就是将文件还原,文件压缩将文件变得更小节省了内存,并且在网络上传输起来也变得很快,还具有一定的保密性,所以这个项目就是为了实现这个目的. 基于哈夫曼树的文件压缩 一.思想:众所周知在32位平台下一个字节占八个bit位,假如我们文件中的数据是abbbcccccddddddd时,每个字节占用八个比特位,

优先级队列优化的霍夫曼编码(带中文压缩)

利用STL中的优先级队列进行优化 我将压缩和解压分为两部分,其实一些还是是一样的 压缩的时候通过bitset将每8个01串压缩成一个字节,如果最后一个不满足8个,用0补齐,但是要记录最后一个字节实际有多少个有效位,将其存入文件最后一个字节,解压的时候先将文件定位到最后一个字节,取出有效位的个数,压缩文件真正有效的是倒数第二个字节,倒数第一个字节只是记录倒数第二个字节中有几位是有效的,解压的时候根据密码本(记录每个字节的权值)建立哈夫曼树,然后更具哈夫曼树解压文件 压缩代码部分: #include

数据结构(java语言描述)哈夫曼编码

原理:哈夫曼编码是根据将已给出的权值作为叶子结点,生成一颗哈夫曼树,然后使得权重最小. 首先生成已给权重的所有的叶子结点,然后取所有节点中最小和次小的结点作为左右孩子生成一个哈夫曼树,计算出父节点的权重放入给出的权重森林中,并把之前的最小和次小的结点从森林中删除,再在种种森林中找最小和次小的结点生成权重树....直到最终只剩下一个树为止. 哈夫曼树的结点用如下结点表示: (有权重,左右孩子,父节点,然后设置一个标识符标志结点是否已经放入哈夫曼树) package tree;/**********

java 哈夫曼编码

//哈夫曼树类 public class HaffmanTree { //最大权值 static final int MAXVALUE=1000; int nodeNum ; //叶子结点个数 public HaffmanTree(int n) { this.nodeNum = n; } //构造哈夫曼树算法 public void haffman(int[] weight,HaffNode[] nodes)//权值数组,所有节点数组 { int n = this.nodeNum; //m1,m

哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)

前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Method for the Construction of Minimum-Redundancy Codes>的文章.编码这种编码的过程叫做哈夫曼编码,它是一种普遍的熵编码技术,包括用于无损数据压缩领域.由于哈夫曼编码的运用广泛,本文将简要介绍: 哈夫曼编码的编码(不包含解码)原理 代码(java)实现过程 一

哈夫曼(Huffman)树与哈夫曼编码

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289610.html 哈夫曼树又称最优二叉树,是一种带权路径长最短的树.树的路径长度是从树根到每一个叶子之间的路径长度之和.节点的带树路径长度为从该节点到树根之间的路径长度与该节点权(比如字符在某串中的使用频率)的乘积. 比如有一串字符串如

霍夫曼编码求节省空间

霍夫曼编码将频繁出现的字符采用短编码,出现频率较低的字符采用长编码.具体的操作过程为:i)以每个字符的出现频率作为关键字构建最小优先级队列:ii)取出关键字最小的两个结点生成子树,根节点的关键字为孩子节点关键字之和,并将根节点插入到最小优先级队列中,直至得到一棵最优编码树. 霍夫曼编码方案是基于______策略的.用该方案对包含a到f6个字符的文件进行编码,文件包含100000个字符,每个字符的出现频率(用百分比表示)如表1-3所示,则与固定长度编码相比,该编码方案节省了______存储空间.

数据压缩算法之哈夫曼编码(HUFFMAN)的实现

HUFFMAN编码可以很有效的压缩数据,通常可以压缩20%到90%的空间(算法导论).具体的压缩率取决于数据的特性(词频).如果采取标准的语料库进行编码,一般可以得到比较满意的编码结果(对不同文件产生不同压缩率的折中方法). 本文采取对单独一个文件进行编码的方式来演示此压缩算法的使用. 分为下面几个步骤: 1.统计词频数据 2.词频数据转换成HUFFMAN算法能够处理的类型(本文为HuffmanNode,内部有存储词频和树节点的结构) (1)由输入的HuffmanNode[]数组创建最小优先级队

霍夫曼编码/译码器

赫夫曼树的应用 1.哈夫曼编码 在数据通信中,需要将传送的文字转换成二进制的字符串,用0,1码的不同排列来表示字符.例如,需传送的报文为"AFTER DATA EAR ARE ART AREA",这里用到的字符集为"A,E,R,T,F,D",各字母出现的次数为{8,4,5,3,1,1}.现要求为这些字母设计编码.要区别6个字母,最简单的二进制编码方式是等长编码,固定采用3位二进制,可分别用000.001.010.011.100.101对"A,E,R,T,F