31、赫夫曼编码

1、赫夫曼编码概念

是一种编码方式,属于一种程序算法。 广泛用于数据文件的压缩,其压缩率在20%~90%左右。

一般的编码流程:字符串 => ASCLL编码 => 二进制

编码发展过程:定长编码(8位,不进行处理)=>变长编码(减少长度,但是有多异性) => Hefuman编码(将频率作为权重,进行哈弗曼编码))

2、赫夫曼编码思路

1、先总结每个字符使用频率,并存入节点(str => bytes => Map => list)

2、将频率作为权值,将每个字符作为叶子节点,构建赫夫曼树

3、将赫夫曼树每个节点(非叶子节点)的左边分支标为0,右边分支标为1。那么,从根节点到叶子节点的分支上的数字组合就是该叶子节点(字符)的赫夫曼编码值。

  • 代码:
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<Byte, StringBuilder> hashMap = new HashMap<Byte, StringBuilder>();
	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(); 
		ArrayList<HuffmanTreeNode1> list = huffmanTreeCode.getList(bytes);

		HuffmanTreeNode1 huffmanTreeNode1 = huffmanTreeCode.buildHuffmanTree(list);
//		System.out.println(Arrays.toString(bytes));
//		System.out.println(list);
//		
		
		
		huffmanTreeCode.preOrder(huffmanTreeNode1);
		
		
		huffmanTreeCode.hfmCode(huffmanTreeNode1,"",stringBuilder);
		System.out.println(hashMap);

	}
	
	
	//将bytes转化为list
	public ArrayList<HuffmanTreeNode1> getList(byte[] bytes){
		ArrayList<HuffmanTreeNode1> list = new ArrayList<HuffmanTreeNode1>();
		Map<Byte, Integer> 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<Byte, Integer> entry : hashMap.entrySet()) {
			list.add(new HuffmanTreeNode1(entry.getKey(),entry.getValue()));
		}
		return list;
	
	}

	
	//构建哈夫曼树
	public HuffmanTreeNode1 buildHuffmanTree(ArrayList<HuffmanTreeNode1> 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);
		}		
	}
	
	
}
class HuffmanTreeNode1 implements Comparable<HuffmanTreeNode1>{
	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();//升序
	}
	
	
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值