E81086713E446D36F62B2AA2A3502B5EB155

Java杂家

杂七杂八。。。一家之言

BlogJava 首页 新随笔 联系 聚合 管理
  141 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
外部排序实现使用堆来生成若干个顺串,然后使用多路归并算法来生成最终排序好的内容。

本来打算使用败者树,结果发现败者树当参与的竞赛者相对较多的情况下,没有全部完成就被空节点充满了。
这个按照它的严格算法,其实也是可以知道不能保证总是能排完的。天快亮了,才彻底放弃使用败者树。改成实现赢者树,结果发现赢者树能保证不出错,实现竟也顺手。

最后整了个测试文件500M的随机内容,2~3分钟排序完成了(应该还可以优化),感觉还行。

代码较多,最要考虑到以后可能要重用。

package algorithms.extsort;

import java.io.IOException;

import algorithms.MinHeap;

/**
 * 
@author yovn
 *
 
*/
public class ExternalSorter {
    
        
    
    
public void sort(int heapSize,RecordStore source,RunAcceptor mediator ,ResultAcceptor ra)throws IOException
    {
        MinHeap
<Record> heap=new MinHeap<Record>(Record.class,heapSize);
        
for(int i=0;i<heapSize;i++)
        {
            Record r
=source.readNextRecord();
            
if(r.isNull())break;
            heap.insert(r);
        }
        
        Record readR
=source.readNextRecord();
        
while(!readR.isNull()||!heap.isEmpty())
        {
        
            Record curR
=null;
            
//begin output one run
            mediator.startNewRun();
            
while(!heap.isEmpty())
            {
                curR
=heap.removeMin();
            
                mediator.acceptRecord(curR);
                
                
if (!readR.isNull()) {
                    
if (readR.compareTo(curR) < 0) {
                        heap.addToTail(readR);
                    } 
else
                        heap.insert(readR);
                }
                readR
=source.readNextRecord();
                
            }
            
//done one run
            mediator.closeRun();
            
            
//prepare for next run
            heap.reverse();
            
while(!heap.isFull()&&!readR.isNull())
            {
                
                heap.insert(readR);
                readR
=source.readNextRecord();
                
            }
            
            
        }
        RecordStore[] stores
=mediator.getProductedStores();
//        LoserTree  lt=new LoserTree(stores);
        WinnerTree  lt=new WinnerTree(stores);
        
        Record least
=lt.nextLeastRecord();
        ra.start();
        
while(!least.isNull())
        {
            ra.acceptRecord(least);
            least
=lt.nextLeastRecord();
        }
        ra.end();
        
        
for(int i=0;i<stores.length;i++)
        {
            stores[i].destroy();
        }
    }
    
    
    
public static void main(String[] args) throws IOException
    {
//        RecordStore store=new MemRecordStore(60004,true);
//        RunAcceptor mediator=new MemRunAcceptor();
//        ResultAcceptor ra=new MemResultAcceptor();
        ExternalSorter sorter=new ExternalSorter();
            
        RecordStore store
=new FileRecordStore("test_sort.txt");
        RunAcceptor mediator
=new FileRunAcceptor("test_sort");
        ResultAcceptor ra
=new FileRecordStore("test_sorted.txt");
        
        
        sorter.sort(
70000, store, mediator, ra);
    }
    
}

其余的都打包在此!

源码

posted on 2007-12-16 08:08 DoubleH 阅读(3334) 评论(3)  编辑  收藏 所属分类: Memorandum

Feedback

# re: 使用赢者树的外部排序[未登录] 2008-10-08 20:52 jason
请问 这个排序怎么用?  回复  更多评论
  

# re: 使用赢者树的外部排序 2013-01-13 17:40 YorkTsai
把源码都下载下来,把项目导入Eclipse中,CreateFile(含有main方法)用来生成随机数据到一个文件,大小达4GB;ExternalSorter(含有main方法)用来对前面生成的文件进行外排序。@jason
  回复  更多评论
  

# re: 使用赢者树的外部排序 2013-01-13 17:41 YorkTsai
拜读完毕,写的太棒了,很多细节处理的很妙啊。。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: