基于huffman树的压缩和解压算法实现

博客围绕基于Huffman树的压缩和解压算法展开,重点在于算法的实现。Huffman树在数据压缩领域有重要应用,通过该树可实现高效的数据压缩与解压,在信息技术中对数据存储和传输有积极意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * @author geyuegui
 * @DATE 2020/12/5 0005 17:11
 * DESCRIPT
 **/
public class HuffmanCode {

    private Map<Byte,StringBuffer> huffmancode=new HashMap<Byte, StringBuffer>();

    public static void main(String[] args) {
        HuffmanCode huffmanCode=new HuffmanCode();
        String inputFile="E:\\bigdata\\psdata.txt";
        String outputZipFile="E:\\bigdata\\code.zip";
        huffmanCode.zipFile(inputFile,outputZipFile);
        String unzipFile="E:\\bigdata\\bb.txt";
        huffmanCode.unzipFile(outputZipFile,unzipFile);
    }
    public void unzipFile(String zipFile,String dstFile){
        InputStream is=null;
        ObjectInputStream ois=null;
        OutputStream os =null;
        try {
            is=new FileInputStream(zipFile);
            ois=new ObjectInputStream(is);
            byte[] huffmanBytes=(byte[])ois.readObject();
            Map<Byte,StringBuffer> huffmap=(Map<Byte,StringBuffer>)ois.readObject();
            byte[] unzipdata=unzipHuffman(huffmanBytes,huffmap);
            os=new FileOutputStream(dstFile);
            os.write(unzipdata);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
                ois.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public  void zipFile(String srcFile,String dstFile){
        FileInputStream is=null;
        OutputStream os = null;
        ObjectOutputStream oos = null;
        try {
            is=new FileInputStream(srcFile);
            byte[] datas=new byte[is.available()];
            is.read(datas);
            byte[] zipdata=huffmanZip(datas);
            for(byte bts:zipdata){
                System.out.print(bts+" ");
            }
            os=new FileOutputStream(dstFile);
            oos=new ObjectOutputStream(os);
            oos.writeObject(zipdata);
            oos.writeObject(huffmancode);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
                oos.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    public byte[] unzipHuffman(byte[] bytes,Map<Byte,StringBuffer> huffmanCodes){
        StringBuffer stringBuffer=new StringBuffer();
        for(int i=0;i<bytes.length;i++){
            byte b=bytes[i];
            boolean flag=(i==bytes.length-1);
            String temp=byteToBinaryString(!flag,b);
            stringBuffer.append(temp);
        }
        Map<String,Byte> maps=new HashMap<String,Byte>();
        for(Map.Entry<Byte,StringBuffer> entry:huffmanCodes.entrySet()){
            maps.put(entry.getValue().toString(),entry.getKey());
        }
        List<Byte> lists=new ArrayList<Byte>();
        for(int i=0;i<stringBuffer.length();){
            int tempIndex=1;
            boolean flag=true;
            Byte huffmanByte=null;
            while(flag){
                String temp=stringBuffer.substring(i,i+tempIndex);
                huffmanByte=maps.get(temp);
                if(huffmanByte==null){
                    tempIndex++;
                }else {
                    flag=false;
                }
            }
            lists.add(huffmanByte);
            i+=tempIndex;
        }
        byte[] bs=new byte[lists.size()];
        for(int i=0;i<lists.size();i++){
            bs[i]=lists.get(i);
        }
        return bs;
    }

    private String byteToBinaryString(boolean flag,byte b){
        int temp=b;
        if(flag){
            temp |= 256;
        }
        String str=Integer.toBinaryString(temp);
        if(flag){
            str=str.substring(str.length()-8);
        }
        return str;
    }

    public byte[] huffmanZip(byte[] datas){
        Node node=huffmanTree(datas);
        huffmancode(node,"",new StringBuffer());
        Map<Byte,StringBuffer> huffmancode=getHuffmancode();
        if(huffmancode.size()==0){
            new Exception("获取赫夫曼编码失败");
        }
        StringBuffer stringBuffer =new StringBuffer();
        for(byte data:datas){
            stringBuffer.append(huffmancode.get(data));
        }
        int len;
        System.out.println(stringBuffer.toString());
        if(stringBuffer.length()%8==0){
            len=stringBuffer.length()/8;
        }else{
            len=stringBuffer.length()/8+1;
        }
        System.out.println("len"+len);
        byte[] zipbyte=new byte[len];
        int index=0;
        for(int i=0;i<stringBuffer.length();i+=8){
            String temp;
            if(i+8>stringBuffer.length()){
                temp=stringBuffer.substring(i);
            }else{
                temp=stringBuffer.substring(i,i+8);
            }
            zipbyte[index]=(byte)Integer.parseInt(temp,2);
            index++;
        }
        System.out.println("index"+index);
        return zipbyte;
    }

    public Map<Byte, StringBuffer> getHuffmancode() {
        return huffmancode;
    }

    public void huffmancode(Node node, String code, StringBuffer stringBuffer){
        StringBuffer stringBuffer1=new StringBuffer(stringBuffer);
        stringBuffer1.append(code);
        if(node!=null){
            if(node.getBytes()==null){
                huffmancode(node.getLeft(),"0",stringBuffer1);
                huffmancode(node.getRight(),"1",stringBuffer1);
            }else{
                huffmancode.put(node.getBytes(),stringBuffer1);
            }
        }
    }
    public Node huffmanTree(byte[] datas){
        List<Node> nodes=new ArrayList<Node>();
        Map<Byte,Integer>  maps=new HashMap<Byte,Integer>();
        for(byte data:datas){
            Integer count=maps.get(data);
            if(count==null){
                maps.put(data,1);
            }else{
                maps.put(data,count+1);
            }
        }
        for(Map.Entry<Byte,Integer> entry:maps.entrySet()){
            nodes.add(new Node(entry.getKey(),entry.getValue()));
        }
        while(nodes.size()>1){
            Collections.sort(nodes);
            Node childLeft = nodes.get(0);
            Node chilRight = nodes.get(1);
            Integer tempCount=childLeft.getWeight()+chilRight.getWeight();
            Node parent=new Node(tempCount);
            parent.setLeft(childLeft);
            parent.setRight(chilRight);
            nodes.add(parent);
            nodes.remove(childLeft);
            nodes.remove(chilRight);
        }
       return nodes.get(0);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值