基本介绍
哈夫曼树的创建
/**
* 哈夫曼树的创建
* @param nodes 一个树结点组成的集合
* @return 创建的书的根结点
*/
public static HuffmanNode creatHuffmanTree (ArrayList<HuffmanNode> nodes){
while (nodes.size()>1){
//对节点集合进行排序由小到大
nodes.sort((o1, o2) ->{
return o1.value-o2.value;
});
//取出集合前两个元素 组成新的节点
HuffmanNode left = nodes.remove(0);
HuffmanNode right = nodes.remove(0);
//新的节点添加到节点集合中
HuffmanNode father = new HuffmanNode(left.value + right.value);
father.right=right;
father.left=left;
nodes.add(father);
}
//返回哈夫曼树的根结点
return nodes.get(0);
}
哈夫曼编码是一种前缀编码
前缀编码:是指对字符集进行编码时,要求字符集中任一字符的编码都不是其它字符的编码的前缀,例如:设有abcd需要编码表示(其中,a=0、b=10、c=110、d=11,则表示110的前缀可以是c或者da,不唯一)
根据权值,构建以一个哈夫曼树。 向左的路径为0向右的路径为1
压缩
//用于存储生成的哈夫曼编码
public static Map<Character,String> codeMap=new HashMap<>();
public static void main(String[] args) {
String s="sjdbfsakjfhadbdsfdkjfbkrytnbvyjvblzgvflkvbigadbvklvo";
char[] chars = s.toCharArray();
//统计出权重
Map<Character, Integer> map = calculateWeight(chars);
//创建哈夫曼结点集合
ArrayList<HuffmanNode> nodes = new ArrayList<>();
map.forEach((k,v)-> {
nodes.add(new HuffmanNode(k,v));
});
//创建哈夫曼树
HuffmanNode root = HuffmanTree.creatHuffmanTree(nodes);
//生成哈夫曼编码
creatHuffmanCode(root,"",new StringBuffer());
codeMap.forEach((k,v)-> System.out.println("字母:"+k+"-编码:"+v));
}
public static Map<Character,Integer> calculateWeight(char[] arr){
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (Character s : arr) {
Integer weight = map.get(s);
if (weight==null){
map.put(s,1);
}else {
map.put(s,++weight);
}
}
return map;
}
public static void creatHuffmanCode(HuffmanNode node, String code,StringBuffer stringBuffer){
stringBuffer.append(code);
if (node!=null){
if (node.value==null){
creatHuffmanCode(node.left,"0",stringBuffer);
creatHuffmanCode(node.right,"1",stringBuffer);
}else {
codeMap.put(node.value,stringBuffer.toString());
}
}
}
原文:https://www.cnblogs.com/huangshen/p/13374860.html