多路归并—败者树—简单实现

特点:败者树每一趟,两节点比较,失败的放在父节点处,胜利者继续跟父节点的父节点比较,相当于拿最小的节点去与根节点交换。

优点:从叶子处新加入一个有结构的败者树,只需要Log2 k次比较即完成了下一轮的数据。

下面代码是一个简单实例,需要将a[0],a[1],a[2],a[3],三行有序列进行归并输出,mark[4]用于标记行数据是否已经读完。

#include <iostream>
#define MAXKEY 10000000
using namespace std;
int k = 4;
int a[4][5] = {1,3,5,7,9,
                2,4,6,8,10,
                11,13,15,17,19,
                12,14,16,18,20};

int mark[4] = {0};
// 获取第i行的下一个数据
int getnext(int i)
{
    if(mark[i] == 5)
        return MAXKEY;
    else
        return a[i][mark[i]++];
}
// 调整从叶子s出发的到根的一个序列
void Adjust(int *ls,int *b,int s)
{
    int t = (s+k)/2;
    while(t>0){
        if(b[s]>b[ls[t]]){
            int temp = s;
            s = ls[t];
            ls[t] = temp;
        }
        t = t/2;
    }
    ls[0] = s;
}
// 合并算法
void KMerge(int *ls)
{
    int b[k+1],i,q;
    for(i = 0; i < k; ++i)
        b[i] = getnext(i);
    // 让b[k]等于-1,让ls[i]都指向这个负数,也就是初始,让这些数字取得胜利,让叶子成为败者而覆盖其父节点。
    b[k] = -1;
    for(i=0;i<k;++i)
        ls[i] = k;
    for(i=k-1;i>=0;--i)
        Adjust(ls,b,i);
    while(b[ls[0]]!=MAXKEY){
        q=ls[0];
        printf("%d ",b[q]);
        b[q] = getnext(q);
        Adjust(ls,b,q);
    }
}
int main()
{
    int ls[5];
    KMerge(ls);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值