基于Java实现的huffman编码

来源:互联网 发布:淘宝小号注册 编辑:程序博客网 时间:2024/06/11 15:16

Huffman的应用背景:

在信息的编码中,由于信息表示使用的每个字母的使用频率不一样,若是每个字母都使用相同长度的编码,对于那些用的不多的字符,但是占据空间又较大的字符,就会造成很大的空间浪费,由此,想出了一种新的编码方式,根据字符的使用频率,平率较大的使用较短的编码,反之,使用较大的编码,但是,就又会出现一种新的问题,若是有的字符的编码是另外一个字符的前缀怎么办?例如a的编码是“001”,而b的编码是“0010”,对于这种情况,计算机怎么能辨别是a还是b呢,就此,就提出了Huffman编码。

Huffman的实现:

Huffman编码基于贪心思想,每次挑选权值最小的两个值进行组合成新的权值,参与下一轮的挑选,一次一次自底向上形成一棵树,根据占据树的左右填写对应的Huffman编码

为了方便实现每次选择最小值,自己定义了一个排序算法,实现了Comparable接口

public class MyPoint implements Comparable<MyPoint> {private int freq ;private String tag;public int getFreq() {return freq;}public void setFreq(int freq) {this.freq = freq;}public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public int compareTo(MyPoint o) {if(freq>o.freq){return 1;}else if (freq<o.freq) {return -1;}return 0;}}

Huffman测试程序:

import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;public class Huffman {public static void main(String []args){//每个节点的权值(频率)int freq[] = new int[]{16,9,5,13,12,45};//每个节点的标记String tg[] = {"A","B","C","D","E","F"};List<MyPoint> points =new ArrayList<MyPoint>();//初始化每个节点,使其加在list中for(int i=0;i<tg.length;i++){MyPoint point = new MyPoint();point.setFreq(freq[i]);point.setTag(tg[i]);points.add(point);}Collections.sort(points);huffman(points);}public static void huffman(List<MyPoint> points){//存放每个节点的Huffman编码    Map<String,String> map = new HashMap<String, String>();    map.put("A", "");    map.put("B", "");    map.put("C", "");    map.put("D", "");    map.put("E", "");    map.put("F", "");int newfreq = 0;String newtag = "";while(points.size()>1){MyPoint newpoint = new MyPoint();int minfreq = points.get(0).getFreq();for(char c : points.get(0).getTag().toCharArray()){if(map.containsKey(c+"")){String value =map.get(c+"");map.put(c+"", "0"+value);}}int minfreq2 = points.get(1).getFreq();for(char c : points.get(1).getTag().toCharArray()){if(map.containsKey(c+"")){String value =map.get(c+"");map.put(c+"", "1"+value);}}System.out.println(points.get(0).getTag()+"和"+points.get(1).getTag()+"合并成"+points.get(0).getTag()+points.get(1).getTag());newfreq = minfreq + minfreq2;newtag = points.get(0).getTag()+points.get(1).getTag();newpoint.setFreq(newfreq);newpoint.setTag(newtag);//移除后第二个就变成第一个points.remove(0);points.remove(0);points.add(newpoint);//重新进行排序,保证每次循环时使得List中第一和第二个的权值都是最小的Collections.sort(points);}for(Map.Entry<String, String>entry:map.entrySet()){System.out.println(entry.getKey()+"--->"+entry.getValue());}}}

运行结果:

C和B合并成CB
E和D合并成ED
CB和A合并成CBA
ED和CBA合并成EDCBA
F和EDCBA合并成FEDCBA
A--->111
B--->1101
C--->1100
D--->101
E--->100
F--->0



0 0
原创粉丝点击