java实现哈夫曼编码压缩文件和解压文件

我是根据B站尚硅谷韩顺平老师讲解的哈夫曼编码代码改写的

b站数据结构和算法
ps:虽然经常翻车(手动狗头) 但还是讲的不错的
因为老韩的解压二进制数组最后一位有bug 我改了一下,增加了一个约定,在要压缩的字符串对应的byte[]数组转为的二进制数组中首位加入了保存最后一位的长度(1-8) 并且约定解码的时候首位不用动 然后判断如果是最后一位了 不管是正数还是负数都要进行补位和截取 截取的长度取决于传入的最后一位的长度(1-8) 经过我的测试暂时是没有问题的 如果有更好的想法可以交流一下

public class Node implements Comparable<Node>{

    Byte data;  //存放数据的ASCII 'a' => 97
   int weight;  //权值 该数据出现的次数
   Node left;
   Node right;

    public Node(Byte data, int weight) {
        this.data = data;
        this.weight = weight;
    }

    //前序遍历
    public void preorderTraversal(){
       System.out.println(this);
       if (this.left != null){
           this.left.preorderTraversal();
       }
       if (this.right != null){
           this.right.preorderTraversal();
       }
   }

    @Override
    public int compareTo(Node o) {
        return this.weight - o.weight;
    }

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                ", weight=" + weight +
                '}';
    }
}
public class HuffmanCode {
   

    //哈夫曼编码表
    public static Map<Byte,String> codeTable = new HashMap<Byte,String>();


        //将字节数组转为Node结点集合
        public static List<Node> getNodes(byte[] bytes){
   
            List<Node> nodes = new ArrayList<>();

            //遍历传入的bytes 放入map集合中
            Map<Byte,Integer> counts = new HashMap<>();
            for (byte b:bytes) {
   
                Integer count = counts.get(b);

                if (count == null){
   
                    counts.put(b,1);
                }else {
   
                    counts.put(b,++count);
                }
            }

            //遍历map集合
            for (Map.Entry<Byte,Integer> entry: counts.entrySet()){
   
                nodes.add(new Node(entry.getKey(),entry.getValue()));
            }


            return nodes;
        }

     //根据Node结点集合 创建Huffman树
    public static Node createHuffmanTree(List<Node> nodes){
   


        //当数组只剩一个值时代表构建哈夫曼树完毕
        while (nodes.size() > 1) {
   
            //排序(升序)
            Collections.sort(nodes);

            //取出权值最小的两个结点
            Node leftNode = nodes.get(0);
          Node rightNode = nodes.get(1);

            //构建一个新的二叉树
            Node parentNode = new Node(null,leftNode.weight + rightNode.weight);
            parentNode.left = leftNode;
            parentNode.right = rightNode;

            //删除权值最小的两个结点
            nodes.remove(leftNode);
            nodes.remove(rightNode);

            nodes.add(parentNode);

        }

        return nodes.get(0);
    }


    
    public static Map<Byte,
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值