14.Huffman(哈夫曼)编码

首先声明一下,我感觉这个算法它的代码有点复杂,等一下我写的时候你就知道了。但是在理解上来说很简单,这就是它最矛盾的地方!!

1.问题解析

由上图可以看出每个字符在文件中出现的次数(频率)以及编码方式,本题研究的就是实现最优字符编码,要求编码文件所需比特数目最少。就像上图,对于定长编码字来说:(45+13+12+16+9+5)*3=300;对于变长编码字来说:(45*1+13*3+12*3+16*3+9*4+5*4)=224;所以变长编码的所需总比特数比定长编码更优

2.编码定义

图中所示:每个字母旁边的数字为其频数,两个父母的父节点数值由两个子节点数值相加得到。同时一个父节点的左边子节点编号为0,右边子节点编号为1,如图中所示,a编码为:000,或0,。

3.贪婪选择

由上图所示,先选取字符中频数最小的两个组合成二叉树,其父节点数值为两频数之和,然后以父节点的数值来替代原来两个点,放入原字符频数数组中,再选取字符中频数最小的两个组合成二叉树,直到所有的字符都在同一棵二叉树上。然后由字符所在位置的编码就是题目要求的最优编码

输入:字符集C及频数f(C)

输出:实现最优编码方式时的各字符编码

算法伪代码:

HUFFMAN(C)

1.    n<-|C|

2.    Q<-C

3.    for i<- 1 to n-1

4.      do 分配新的节点z

5.          left[z]<-x<-EXTRACT-MIN(Q)

6.          right[z]<-y<-EXTRACT-MIN(Q)

7.          f[z]<-f[x]+f[y]

8.          INSERT(Q,z)

9.    return EXTRACT-MIN(Q) //返回树的根

JAVA:

Binarytree.java

package Jamin;

public class Binarytree implements Comparable<Binarytree>{
int key;
char data;
Binarytree left;
Binarytree right;
public Binarytree() {}
public Binarytree(int k,char d,Binarytree l,Binarytree r) {//将输入的值赋值到建立的结构变量中
    key=k;
    data=d;
    left=l;
    right=r;
}
public String toString() {//用来做后期打印
    return "Character:"+data+" frequency:"+key; 
}
public int compareTo(Binarytree x) {// 比较
    if(key>x.key)
        return 1;
    if(key<x.key)
        return -1;
    return 0;
}
public void inorderwalk() {//调用遍历输出
    if(left!=null)
        left.inorderwalk();
    System.out.print(toString());
    if(right!=null)
        right.inorderwalk();
}
}
 

Huffman.java

package Jamin;
import java.util.PriorityQueue;
public class Huffman {
public static Binarytree huffman(int[] f,char[] d) {
    int i,n=f.length;
    PriorityQueue<Binarytree> Q=new PriorityQueue<Binarytree>(n);
    for(i=0;i<n;i++) {
        Binarytree t=new Binarytree(f[i],d[i],null,null);
        Q.add(t);
    }
    for(i=0;i<n-1;i++) {
        Binarytree x,y,z;
        x=Q.poll();//从优先队列中弹出最小值
        y=Q.poll();
        z=new Binarytree(x.key+y.key,'*',x,y);
        Q.add(z);
    }
    return Q.poll();    
}
public static void printcode(Binarytree t,String c) {
    if(t.left!=null)//向左边搜索,变0
        printcode(t.left,c+"0");
    if(t.right!=null)//向右边搜索,变1
        printcode(t.right,c+"1");
    if(t.left==null&&t.right==null)
        System.out.println(t+" code:"+c+" ");
}
}
 

Test.java

package Jamin;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
int f[]= {45,13,12,16,9,5},i;
char d[]= {'a','b','c','d','e','f'};
Binarytree h=Huffman.huffman(f, d);
Huffman.printcode(h, "");
System.out.println();
}
}
输出结果:

Character:a frequency:45 code:0 
Character:c frequency:12 code:100 
Character:b frequency:13 code:101 
Character:f frequency:5 code:1100 
Character:e frequency:9 code:1101 
Character:d frequency:16 code:111 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值