32、哈夫曼编码之数据压缩

  • 前言:

前面讲了如何如何生成哈夫曼树,如何用哈夫曼树进行编码,进而得到哈夫曼哈希表,本节主要讲实例,如何对字符串进行压缩展示。

  • 思路:

1、将字符串用生成哈夫曼树,生成哈夫曼哈希表

2、将原byte[]通过哈夫曼哈希表,生成新的byte[],进而压缩了数据

  • 代码:
//数据压缩:将字符串压缩
	public byte[] zip(byte[] bytes, Map hfmMap) {
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			stringBuilder.append(hfmMap.get(bytes[i]));
		}
		System.out.println(stringBuilder.toString());
		//按照8位一个字节进行压缩
		int len = (stringBuilder.length()+7)/8;
		byte[] bytes1 = new byte[len];
		int index = 0;
		for(int i = 0; i < stringBuilder.length(); i += 8) {
			if(i+8 < stringBuilder.length()) {
				bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, i+8), 2);
			}else {
				bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, stringBuilder.length()), 2);
			}		
		}
		return bytes1;
		
	}
  • 完整代码
package tree.huffmanTree;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.activation.MailcapCommandMap;

public class HuffmanTreeCode {
	static Map hashMap = new HashMap();
	static StringBuilder stringBuilder  = new StringBuilder();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//哈夫曼编码:
		//构建哈夫曼树节点,包括data(byte),weigth(频率),leftNode,rightNode等
		//然后待编译的字符串存放在bytes数组中,并通过map将byte存放在list数组中。
		//构建赫夫曼树
		HuffmanTreeCode huffmanTreeCode = new HuffmanTreeCode();
		
		String string = "I like like like like like java and do you like it";
		byte[] bytes = string.getBytes(); 
		System.out.println(Arrays.toString(bytes));
		ArrayList list = huffmanTreeCode.getList(bytes);

		HuffmanTreeNode1 huffmanTreeNode1 = huffmanTreeCode.buildHuffmanTree(list);
		
		//前序
//		huffmanTreeCode.preOrder(huffmanTreeNode1);
		
		//hfm编码
		huffmanTreeCode.hfmCode(huffmanTreeNode1,"",stringBuilder);
//		System.out.println(hashMap);
		
		byte[] byte1 = huffmanTreeCode.zip(bytes, hashMap);
		System.out.println(Arrays.toString(byte1));

	}
	
	
	//将bytes转化为list
	public ArrayList getList(byte[] bytes){
		ArrayList list = new ArrayList();
		Map hashMap = new HashMap<>();
		Integer lenght;
		for (int i = 0; i < bytes.length; i++) {
			lenght = hashMap.get(bytes[i]);
			
			if(lenght == null) {
				hashMap.put(bytes[i], 1);
			}else {				
				hashMap.put(bytes[i], lenght+1);
			}
		}
		
		for(Map.Entry entry : hashMap.entrySet()) {
			list.add(new HuffmanTreeNode1(entry.getKey(),entry.getValue()));
		}
		return list;
	
	}

	
	//构建哈夫曼树
	public HuffmanTreeNode1 buildHuffmanTree(ArrayList list) {
		HuffmanTreeNode1 pareNode;
		while(list.size() > 1) {
			
			//排序
			Collections.sort(list);
			//先取出两个最小的元素
		    pareNode = new HuffmanTreeNode1(null, list.get(0).getWeigth()+list.get(1).getWeigth());
			pareNode.setLeftNode(list.get(0));
			pareNode.setRightNode(list.get(1));
			list.remove(0);
			list.remove(0);
			list.add(pareNode);	
//			System.out.println(pareNode.toString());
		}
		return list.get(0);
	}
	
	//前序遍历
	public void preOrder(HuffmanTreeNode1 node) {
		if(node == null) {
			return;
		}
		node.preOrder();
	}
//	
	
	
	//hfm编码
	public void hfmCode(HuffmanTreeNode1 node, String aString, StringBuilder stringBuilder) {
		StringBuilder stringBuilder2 = new StringBuilder(stringBuilder);
		stringBuilder2.append(aString);
		//判断是不是叶子节点
		if(node.getData() == null) {//非叶子节点
			hfmCode(node.getLeftNode(), "0", stringBuilder2);
			hfmCode(node.getRightNode(), "1", stringBuilder2);
		}else {
			hashMap.put(node.getData(), stringBuilder2);
		}		
	}
	
	//数据压缩:将字符串压缩
	public byte[] zip(byte[] bytes, Map hfmMap) {
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			stringBuilder.append(hfmMap.get(bytes[i]));
		}
		System.out.println(stringBuilder.toString());
		//按照8位一个字节进行压缩
		int len = (stringBuilder.length()+7)/8;
		byte[] bytes1 = new byte[len];
		int index = 0;
		for(int i = 0; i < stringBuilder.length(); i += 8) {
			if(i+8 < stringBuilder.length()) {
				bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, i+8), 2);
			}else {
				bytes1[index++] = (byte) Integer.parseInt(stringBuilder.substring(i, stringBuilder.length()), 2);
			}		
		}
		return bytes1;
		
	}
	
	
	
}
class HuffmanTreeNode1 implements Comparable{
	private Byte data;
	private Integer weigth;
	private HuffmanTreeNode1 leftNode;
	private HuffmanTreeNode1 rightNode;
	
	public HuffmanTreeNode1(Byte data, int weigth ) {
		this.data = data;
		this.weigth = weigth;		
	}

	public Byte getData() {
		return data;
	}

	public void setData(byte data) {
		this.data = data;
	}

	public int getWeigth() {
		return weigth;
	}

	public void setWeigth(int weigth) {
		this.weigth = weigth;
	}

	public HuffmanTreeNode1 getLeftNode() {
		return leftNode;
	}

	public void setLeftNode(HuffmanTreeNode1 leftNode) {
		this.leftNode = leftNode;
	}

	public HuffmanTreeNode1 getRightNode() {
		return rightNode;
	}

	public void setRightNode(HuffmanTreeNode1 rightNode) {
		this.rightNode = rightNode;
	}

	@Override
	public String toString() {
		return "HuffmanTreeNode1 [data=" + data + ", weigth=" + weigth + "]";
	}
	
	
	//前序遍历
	public void preOrder() {
		System.out.println(this.toString());
		if(this.leftNode != null) {
			this.leftNode.preOrder();
		}
		if(this.rightNode != null) {
			this.rightNode.preOrder();
		}
	}

	@Override
	public int compareTo(HuffmanTreeNode1 o) {
		// TODO Auto-generated method stub
		return this.getWeigth() - o.getWeigth();//升序
	}
	
	
	
}

你可能感兴趣的:(数据结构和算法,算法,赫夫曼编码)