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

来源:互联网 发布:电信免流软件 编辑:程序博客网 时间:2024/06/05 05:36

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

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

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

#include <iostream>#define MAXKEY 10000000using 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;}


0 0
原创粉丝点击