没有合适的资源?快使用搜索试试~ 我知道了~
哈夫曼编码算法与分析(java实现)
5星 · 超过95%的资源 需积分: 50 85 下载量 120 浏览量
2012-11-26
15:23:38
上传
评论 4
收藏 98KB DOC 举报
温馨提示
试读
12页
1.哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。给出文件中各个字符出现的频率,求各个字符的哈夫曼编码方案。
资源推荐
资源详情
资源评论
算 法 与 分 析
1. 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。给出文件中各个字符
出现的频率,求各个字符的哈夫曼编码方案。
2. 给定带权有向图 G =(V,E),其中每条边的权是非负实数。另外,还给定 V 中的一个
顶点,称为源。现在要计算从源到所有其他各顶点的最短路长度。这里路的长度是指
路上各边权之和。
3. 设 G =(V,E)是无向连通带权图,即一个网络。E 中每条边(v,w)的权为 c[v][w]。如
果 G 的子图 G’是一棵包含 G 的所有顶点的树,则称 G’为 G 的生成树。生成树上各边
权的总和称为该生成树的耗费。在 G 的所有生成树中,耗费最小的生成树称为 G 的最
小生成树。求 G 的最小生成树。
求解问题的算法原理:
1.最优装载哈夫曼编码
1.1 前缀码
对每一个字符规定一个 0,1 串作为其代码,并要求任一字符的代码都不是其它字符代码
的前缀,这种编码称为前缀码。
编码的前缀性质可以使译码方法非常简单。
表示最优前缀码的二叉树总是一棵完全二叉树,即树中任一结点都有 2 个儿子结点。
平均码长定义为:
B(T)=
f(c):c 的码长,dt(c):c 的深度
使平均码长达到最小的前缀码编码方案称为给定编码字符集 C 的最优前缀码。
1.2 构造哈夫曼编码
哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。
哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树 T。
算法以|C|个叶结点开始,执行|C|-1 次的“合并”运算后产生最终所要求的树 T。
编码字符集中每一字符 c 的频率是 f(c)。以 f 为键值的优先队列 Q 用在贪心选择时有效
地确定算法当前要合并的 2 棵具有最小频率的树。一旦 2 棵具有最小频率的树合并后,产
生一棵新的树,其频率为合并的 2 棵树的频率之和,并将新树插入优先队列 Q。经过 n-1
次的合并后,优先队列中只剩下一棵树,即所要求的树 T。
可用最小堆实现优先队列 Q。
2.单源最短路径
Dijkstra 算法是解单源最短路径问题的贪心算法。
其基本思想是,设置顶点集合 S 并不断地作贪心选择来扩充这个集合。一个顶点属于集
合 S 当且仅当从源到该顶点的最短路径长度已知。
初始时,S 中仅含有源。设 u 是 G 的某一个顶点,把从源到 u 且中间只经过 S 中顶点
的路称为从源到 u 的特殊路径,并用数组 dist 记录当前每个顶点所对应的最短特殊路径长
度。Dijkstra 算法每次从 V-S 中取出具有最短特殊路长度的顶点 u,将 u 添加到 S 中,同
时对数组 dist 作必要的修改。一旦 S 包含了所有 V 中顶点,dist 就记录了从源到所有其它
顶点之间的最短路径长度。
3.最小生成树
设 G=(V,E)是连通带权图,V={1,2,…,n}。
构造 G 的最小生成树的 Prim 算法的基本思想是:首先置 S={1},然后,只要 S 是 V
的真子集,就作如下的贪心选择:选取满足条件 i∈S,j∈V-S,且 c[i][j]最小的边,将顶
点 j 添加到 S 中。这个过程一直进行到 S=V 时为止。
在这个过程中选取到的所有边恰好构成 G 的一棵最小生成树。
利用最小生成树性质和数学归纳法容易证明,上述算法中的边集合 T 始终包含 G 的某棵
最小生成树中的边。因此,在算法结束时,T 中的所有边构成 G 的一棵最小生成树。
编程实现:
1.最优装载哈夫曼编码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Huffman {
private List<Double> nums;
private List<Double> numsMo;
private List<Tree> trees;
private String temp;
public Huffman() {
nums = new ArrayList<Double>();
numsMo = new ArrayList<Double>();
trees = new ArrayList<Tree>();
temp="";
}
public void addNums() {// 给定一组数
System.out.println("请输入一组数,中间用空格分隔:");
Scanner sca = new Scanner(System.in);
String str = sca.nextLine();
String[] strs = str.split(" ");
for (int i = 0; i < strs.length; i++) {
nums.add(Double.parseDouble(strs[i]));
numsMo.add(Double.parseDouble(strs[i])); }
}
public void compareNum(List<Double> nums,List<Tree> trees) {//
递归算法
double[] min = new double[2];
if(nums.size()>1){
min = minTwo(nums);
Tree t = new Tree();
nums.remove(Double.valueOf(min[0]));
nums.remove(Double.valueOf(min[1]));
nums.add(min[0]+min[1]);
trees.add(t);
compareNum(nums,trees);
}
}
public void print(double num) {// 递归打印编码
for(Tree t : trees){
if(num == t.getRchild()){
temp = 1+temp;
print(t.getParents());
break;
}else if(num == t.getRchild()){
temp = 0+temp;
print(t.getParents());
break;
}
}
}
public void write(double d){
temp =" ";
剩余11页未读,继续阅读
资源评论
- u0102728742015-05-22很好的资源,值得下载!!
- 小小葡萄干2016-03-05代码可以 值得参考,在写Android版的哈夫曼中加以修改应用
- qq_257149292015-11-21可以参考算法。
- jintianmingtianyiran2013-07-12程序有点BUG,运行不起,不过可以参考算法
wei509085
- 粉丝: 10
- 资源: 123
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功