【数据结构与算法】赫夫曼编码

赫夫曼编码

基本介绍

  1. 赫夫曼编码也翻译为哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,属于一种程序算法。
  2. 赫夫曼编码是赫夫曼树在电讯通信中的经典应用之一,
  3. 赫夫曼编码广泛地应用于数据文件压缩,其压缩率通常在 20%~90% 之间。
  4. 赫夫曼编码是可变字长编码(VLC)的一种,Huffman 于 1952 年提出的一种编码。

注意:这个赫夫曼树根据排序方法不同,也可能不太一样,这样对应的赫夫曼编码也不完全一样,但是 wpl 是一样的,都是最小的。

数据压缩

思路分析

功能:根据赫夫曼编码压缩数据的原理,需要创建"i like like like java do you like a java"对应的赫夫曼树

思路:

  1. Node {data(存放数据),weight(权值),left,right}
  2. 得到"i like like like java do you like a java"对应的 byte[] 数组
  3. 编写一个方法将准备构建赫夫曼树的 Node 节点放到 List,形式:[Node[data = 97,weight = 5],…],体现 d:1 y:1 u:1 j:2 v:2 o:2 l:4 k:4 e:4 i:5 a:5 [空格]:9
  4. 可以通过 List 创建对应的赫夫曼树
  5. 将字符和权值加入到 List 集合
  6. 将得到的赫夫曼树的所有叶子结点的赫夫曼编码得到,并放入到 huffmanCodes 集合,得到赫夫曼编码表(规定:左子节点的路径为 0,右子节点的路径为 1)
  7. 将字符串对应的数组,通过生成的赫夫曼编码表,返回一个赫夫曼编码压缩后的数组
代码实现
public class HuffmanCode {
   
   
    public static void main(String[] args) {
   
   
        String content = "i like like like java do you like a java";
        byte[] contentBytes = content.getBytes();

        byte[] huffmanCodeBytes = huffmanZip(contentBytes);
        System.out.println(Arrays.toString(huffmanCodeBytes));
    }

    /**
     * 封装方法,便于调用
     *
     * @param bytes 原始的字符串对应的字节数组
     * @return 是经过赫夫曼编码压缩过后的字节数组
     */
    private static byte[] huffmanZip(byte[] bytes) {
   
   
        // 将字符和权值加入到 List 集合
        List<Node> nodes = getNodes(bytes);
        // 通过 List 创建对应的赫夫曼树
        Node huffmanTreeRoot = createHuffmanTree(nodes);
        // 生成赫夫曼编码
        Map<Byte, String> huffmanCodes = getCodes(huffmanTreeRoot);
        // 根据生成的赫夫曼编码,将字符数组进行压缩,得到压缩后的字符数组
        return zip(bytes, huffmanCodes);
    }

    /**
     * 编写方法,将字符串对应的 byte[] 数组,通过生成的赫夫曼编码表,返回一个赫夫曼编码压缩后的 byte[]
     *
     * @param bytes        原始字符串对应的 byte[]
     * @param huffmanCodes 生成的赫夫曼编码 map
     * @return 返回赫夫曼编码处理后的 byte[]
     */
    private static byte[] zip(byte[] bytes, Map<Byte, String> huffmanCodes) {
   
   
        // 1. 利用 StringBuilder 将 bytes 转成赫夫曼编码
        StringBuilder stringBuilder = new StringBuilder();
        // 遍历 bytes
        for (byte b : bytes) {
   
   
            stringBuilder.append(huffmanCodes.get(b));
        }
        // 将拼接的字符串转为 byte[]
        // 统计返回 byte[] huffmanCodeBytes 长度
        int len;
        if (stringBuilder.length() % 8 == 0) {
   
   
            len = stringBuilder.length() / 8;
        } else {
   
   
            len = stringBuilder.length() / 8 + 1;
        }
        // 创建存储压缩后的 byte 数组
        byte[] huffmanCodeBytes = new byte[len];
        int index = 0; // 记录是第几个 byte
        for (int i = 0; i < stringBuilder.length(); i += 8) {
   
    // 因为是每 8 位对应一个 byte,所以步长为 8
            String stByte;
            if (i + 8 > stringBuilder.length()) {
   
    // 不够 8 位
                stByte = stringBuilder.substring(i);
            } else {
   
   
                stByte = stringBuilder.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superLango

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值