海量数据排序,多路平衡归并算法及实现(外部文件排序算法)

外部文件多路平衡归并类似于内部排序的归并算法。可知增加分段个数k可以减少归并次数s,从而减少外存读写次数,但是单纯增加k将会导致增加内部归并的时间。
对于k-路归并,令u个记录分布在k个归并段上,显然,归并后的第一个记录应该是k个归并段中关键字最小的记录,即应从每个归并段的第一个记录的相互比较中选出最小者,这需要进行k-1次比较。同理,每得到归并后的有序段中的一个记录,就要进行k-1次比较。显然,为得到含u个记录的归并段需要进行(u-1)(k-1)次比较。由此,对n个记录的文件进行外部排序时,在内部归并过程中进行的总的比较次数为s(k-1)*(n-1)。由于随着k的增长,内部归并时间亦会增长,这将抵消掉由于增大k而减少外存信息读写时间所得的收益,这是我们所不希望的。然而,若在k-路归并时利用“败者树”,则可以使在k个记录中选出关键字最小的记录时仅需进行log2k次比较,从而使总的归并时间变小。
对于败者树的定义,请参考相关数据结构书籍,这里不作冗余叙述。
由于各路数据要防止归并过程中提前取空的问题,代码设计会有些变动,详见以下代码:

void k_merge()
{
    unsigned long int no;
    int p;
    double tempd;
    for(int i=0;i<nfrag;i++)
    {
        p=poss[i];
        fsortin.seekg((poss[i])*sizeof(double),std::ios::beg);
        fsortin.read((char*)&tempd,sizeof(double));
        external[i]=tempd;
        poss[i]++;
    }
    create_losertree();
    no=0;
    while (no<maxnum)
    {
        p=losertree[0];
        fsortout.write((char*)&(external[p]),sizeof(double));
        no++;
        if(poss[p]-p*maxnumin>=nums[p]){external[p]=MAXKEY;}
        else
        {
            fsortin.seekg((poss[p])*sizeof(double),std::ios::beg);
            fsortin.read((char*)&tempd,sizeof(double));
            external[p]=tempd;
            poss[p]++;
        }
        adjust(p);
    }
}
void create_losertree()
{
    external[nfrag]=MINKEY;
    for(int i=0;i<nfrag;i++) losertree[i]=nfrag;
    for(int i=nfrag-1;i>=0;i--) adjust(i);
}

void adjust(int s)
{
    int t=(s+nfrag)/2;
    int temp;
    while (t>0)
    {
        if(external[s]>external[losertree[t]])
        {
            temp=s;
            s=losertree[t];
            losertree[t]=temp;
        }
        t=t/2;
    }
    losertree[0]=s;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值