实验3 贪心算法.docx
- 文档编号:26994263
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:18
- 大小:44.93KB
实验3 贪心算法.docx
《实验3 贪心算法.docx》由会员分享,可在线阅读,更多相关《实验3 贪心算法.docx(18页珍藏版)》请在冰豆网上搜索。
实验3贪心算法
南京信息工程大学算法设计与分析实验(实习)报告
实验(实习)名称实验3贪心算法实验(实习)日期2016.10得分指导老师宣文霞
系计算机专业网络工程班级2姓名刘信言学号20142346074
1)哈夫曼编码。
(以P116表4-1中所列的字符出现的概率,采用贪心算法构造哈夫曼树,并给出哈夫曼编码)
哈夫曼编码广泛的用于数据文件压缩的十分有效的编码方法。
其压缩率通常在20%~90%之间。
哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。
基本思想:
给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。
C:
编码字符集, C中任一字符以频率f(c)在数据文件中出现.前缀编码方案对应于二叉树T,字符c在T中的深度为dT(c)
(编码方案)平均码长定义为:
使平均码长达到最小的前缀码编码方案称为给定编码字符集C的最优前缀码。
表示最优前缀码的二叉树总是一棵完全二叉树,即树中任一结点都有2个孩子结点。
Node.java
packagesuanfa.huffman;
publicclassNodeimplementsComparable
privateNodeleftChild=null;
privateDatadata=null;
privateNoderightChild=null;
publicNodegetLeftChild(){
returnleftChild;
}
publicvoidsetLeftChild(NodeleftChild){
this.leftChild=leftChild;
}
publicDatagetData(){
returndata;
}
publicvoidsetData(Datadata){
this.data=data;
}
publicNodegetRightChild(){
returnrightChild;
}
publicvoidsetRightChild(NoderightChild){
this.rightChild=rightChild;
}
@Override
publicStringtoString(){
return"Node[leftChild="+leftChild+",data="+data
+",rightChild="+rightChild+"]";
}
@Override
publicintcompareTo(Nodeo){
returnpareTo(o.getData());
}
}
Data.java
packagesuanfa.huffman;
publicclassDataimplementsComparable{
//字符
privatecharc=0;
//字符出现的次数
privateintfrequency=0;
publicchargetC(){
returnc;
}
publicvoidsetC(charc){
this.c=c;
}
publicintgetFrequency(){
returnfrequency;
}
publicvoidsetFrequency(intfrequency){
this.frequency=frequency;
}
@Override
publicStringtoString(){
return"Data[c="+c+",frequency="+frequency+"]";
}
@Override
publicintcompareTo(Datao){
if(this.frequency return-1; }elseif(this.frequency>o.getFrequency()){ return1; }else{ return0; } } } EncodeResult.java packagesuanfa.huffman; importjava.util.Map; publicclassEncodeResult{ //字符串编码后的结果 privateStringencode; //字符编码对 privateMap publicEncodeResult(Stringencode,Map super(); this.encode=encode; this.letterCode=letterCode; } publicStringgetEncode(){ returnencode; } publicMap returnletterCode; } } HuffmanAlgorithm.java publicinterfaceHuffmanAlgorithm{ publicEncodeResultencode(Stringstr); publicStringdecode(EncodeResultencodeResult); } HuffmanAlgorithmAbstract.java packagesuanfa.huffman; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.Map; importjava.util.Set; publicabstractclassHuffmanAlgorithmAbstractimplementsHuffmanAlgorithm{ @Override publicEncodeResultencode(Stringstr){ ArrayList NoderootNode=createTree(letterList); Map EncodeResultresult=encode(letterCode,str); returnresult; } /** *把一个字符串转化为节点列表 *@paramletters *@return */ privateArrayList ArrayList Map for(inti=0;i Charactercharacter=letters.charAt(i); if(! ci.keySet().contains(character)){ ci.put(character,1); }else{ IntegeroldValue=ci.get(character); ci.put(character,oldValue+1); } } Set for(Characterkey: keys){ Nodenode=newNode(); Datadata=newData(); data.setC(key); data.setFrequency(ci.get(key)); node.setData(data); letterList.add(node); } returnletterList; } protectedabstractNodecreateTree(ArrayList /** *编码字符串。 *@paramletterCode字符/编码对集合。 *@paramletters指定的需要编码的字符串。 *@return编码结果 */ privateEncodeResultencode(Map StringBuilderencode=newStringBuilder(); for(inti=0,length=letters.length();i Charactercharacter=letters.charAt(i); encode.append(letterCode.get(character)); } EncodeResultresult=newEncodeResult(encode.toString(),letterCode); returnresult; } /** *获得所有字符编码对 * *@paramrootNode哈夫曼树的根节点 *@return所有字符编码对 */ privateMap Map //处理只有一个节点的情况 if(rootNode.getLeftChild()==null&&rootNode.getRightChild()==null){ letterCode.put(rootNode.getData().getC(),"1"); returnletterCode; } getLetterCode(rootNode,"",letterCode); returnletterCode; } /** *先序遍历哈夫曼树,获得所有字符编码对。 * *@paramrooNode哈夫曼树根结点 *@paramsuffix编码前缀,也就是编码这个字符时,之前路径上的所有编码 *@paramletterCode用于保存字符编码结果 */ privatevoidgetLetterCode(NoderooNode,Stringsuffix, Map if(rooNode! =null){ if(rooNode.getLeftChild()==null &&rooNode.getRightChild()==null){ Charactercharacter=rooNode.getData().getC(); letterCode.put(character,suffix); } getLetterCode(rooNode.getLeftChild(),suffix+"0",letterCode); getLetterCode(rooNode.getRightChild(),suffix+"1",letterCode); } } publicStringdecode(EncodeResultdecodeResult){ //解码得到的字符串 StringBufferdecodeStr=newStringBuffer(); //获得解码器 Map .getLetterCode()); //解码器键集合 Set //待解码的(被编码的)字符串 Stringencode=decodeResult.getEncode(); //从最短的开始匹配之所以能够成功,是因为哈夫曼编码的唯一前缀性质 //临时的可能的键值 Stringtemp=""; //改变temp值大小的游标 inti=1; while(encode.length()>0){ temp=encode.substring(0,i); if(keys.contains(temp)){ Charactercharacter=decodeMap.get(temp); decodeStr.append(character); encode=encode.substring(i); i=1; }else{ i++; } } returndecodeStr.toString(); } /** *获得解码器,也就是通过字母/编码对得到编码/字符对。 * *@paramletterCode *@return */ privateMap Map Set for(Characterkey: keys){ Stringvalue=letterCode.get(key); decodeMap.put(value,key); } returndecodeMap; } } HuffmanAlgorithmImpl1.java packagesuanfa.huffman; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.Map; importjava.util.Set; publicclassHuffmanAlgorithmImpl1extendsHuffmanAlgorithmAbstract{ @Override protectedNodecreateTree(ArrayList init(letterList); while(letterList.size()! =1){ intsize=letterList.size(); //小的节点放在右边(眼睛看到的左边) NodenodeLeft=letterList.get(size-1); NodenodeRight=letterList.get(size-2); NodenodeParent=newNode(); nodeParent.setLeftChild(nodeLeft); nodeParent.setRightChild(nodeRight); Datadata=newData(); data.setFrequency(nodeRight.getData().getFrequency() +nodeLeft.getData().getFrequency()); nodeParent.setData(data); letterList.set(size-2,nodeParent); letterList.remove(size-1); sort(letterList); } NoderootNode=letterList.get(0); returnrootNode; } privatevoidinit(ArrayList sort(letterList); } privatevoidsort(ArrayList intsize=letterList.size(); if(size==1){ return; } for(inti=0;i for(intj=0;j if(letterList.get(j).getData().getFrequency() .get(j+1).getData().getFrequency()){ NodetempNode=letterList.get(j); letterList.set(j,letterList.get(j+1)); letterList.set(j+1,tempNode); } } } } } HuffmanAlgorithmImpl1Test.java packagesuanfa.huffman; importstaticorg.junit.Assert.*; importorg.junit.Test; publicclassHuffmanAlgorithmImpl1Test{ @Test publicvoidtestEncodeString(){ HuffmanAlgorithmImpl1huffmanImpl1=newHuffmanAlgorithmImpl1(); EncodeResultresult=huffmanImpl1.encode("abcdda"); System.out.println(result.getEncode()); } @Test publicvoidtestDecode(){ HuffmanAlgorithmImpl1huffmanImpl1=newHuffmanAlgorithmImpl1(); EncodeResultresult=huffmanImpl1.encode("abcdda"); Stringdecode=huffmanImpl1.decode(result); System.out.println(decode); } } 【运行结果】 2)多机调度问题。 设7个独立作业{1,2,3,4,5,6,7}由3台机器M1,M2和M3加工处理。 各作业所需的处理时间分别为{2,14,4,16,6,5,3}。 采用贪心算法给出作业的调度方案以及所需要的加工时间。 (P133,图4-11) 贪心选择策略: 最长处理时间作业优先选择。 然后依此顺序将作业分配给空闲的处理机。 取出最大的未分配任务,放入总时间最小的机器队列。 importjava.util.ArrayList; importjava.util.Collections; importjava.util.LinkedList; importjava.util.List; /** *多机调度问题--贪心算法 *@authorLican * */ publicclassJobMachine{ publicstaticclassJobNodeimplementsComparable{ intid;//作业的标号 inttime;//作业时间 publicJobNode(intid,inttime){ this.id=id; this.time=time; } @Override publicintcompareTo(Objectx){//按时间从大到小排列 inttimes=((JobNode)x).time; if(time>times)return-1; if(time==times)return0; return1; } } publicstaticclassMachineNodeimplementsComparable{ intid;//机器的标号 intavail;//机器空闲的时间(即机器做完某一项工作的时间) publicMachineNode(intid,intavail){ this.id=id; this.avail=avail; } @Override publicintcompareTo(Objecto){//升序排序,LinkedList的first为最小的 intxs=((MachineNode)o).avail; if(avail if(avail==xs)return0; return1; } } publicstaticint
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验3 贪心算法 实验 贪心 算法
![提示](https://static.bdocx.com/images/bang_tan.gif)