用败者树做的多路归并程序

本文介绍了一种使用败者树实现的多路归并算法,通过构造败者树并结合多路归并策略,实现了对多个有序序列的有效合并。文中详细解释了程序设计思路,并给出具体实现代码,包括数据结构定义、关键函数实现及主函数测试流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 这个程序目前只考虑到是完全二叉树的叶子节点的情况。

2.每个有序序列的末尾都加上了一个MAX_BIG来表示最终的结束,这样做是为了简化程序设计,不然当一个序列的最后一个元素被合并到目的序列时候,不知道该往败者树里面加什么。

0  1  2  3  4  5  6  7  8  999999999 
1  2  3  4  5  6  7  8  9  999999999 
4  5  6  7  8  9  10  11  12  999999999 
9  10  11  12  13  14  15  16  17  999999999 
 0   1   1   2   2   3   3   4   4   4   5   5   5   6   6   6   7   7   7   8   8   8   9   9   9   10   10   11   11   12   12   13   14   15   16   17 

 

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

#include  <stdio.h>
#include <stdlib.h>

typedef  struct  wrap_data
{
        int  offset;
        int  path;
        int  *data;
}wrap_data;


int choosevec(int path)
{
        if(path<=4)
        {
                return 4;
        }
        else if (path<=8)
        {
                return 8;
        }
        else if(path<=16)
        {
                return  16;
        }
        else
        {
                return 32;
        }
}

wrap_data **vec;
int  vecsize;

wrap_data  *  up ( int num )
{
        int  i,j,k;
        wrap_data  *first,*second;
        i=num;
        second=vec[i];
        while(i)
        {
                j=i/2;
                first=vec[j];

                if(!first)
                {
                        vec[j]=second;
                        if (!j)
                        {
                                return second;
                        }
                        else
                        {
                                return NULL;
                        }
                }
                if ( first->path==second->path)
                {
                        i=j;
                }
                else if ( *( second->data + second->offset )>  *( first->data + first->offset ))
                {
                        vec[j]=second;
                        second=first;
                        i=j;

                }
                else
                {
                        i=j;
                }
        }
        return  second;
}

int  main()
{
#define  PATH  4
#define  LENGTH  10
#define   MAX_BIG   999999999

        wrap_data *result;
        int i=0,j=0,k=0;
        wrap_data a[PATH]={0};

        vecsize=2*    choosevec(PATH);
        vec=(wrap_data **)calloc( vecsize ,sizeof (wrap_data*));

        for(i=0;i<PATH;i++)
        {
                a[i].data=(int*) calloc (LENGTH , sizeof (int ));
                a[i].offset=0;
                a[i].path=i;
                for(j=0;j<LENGTH;j++)
                {

                        *(a[i].data+j)=(i*i+j)%40;

                }
                *(a[i].data+LENGTH-1)=MAX_BIG;
        }
        for(i=0;i<PATH;i++)
        {
                for(j=0;j<LENGTH;j++)
                {
                        printf("%d  ", *(a[i].data+j));
                }
                printf("\n");
        }
        k=vecsize/2;
        for(i=0;i<PATH;i++)
        {
                vec[k+i]=&a[i];
        }
        for(i=0;i<PATH;i++)
        {
                result=up(i+k);
                if(!result)
                {
                }
                else
                {
                        break;
                }
        }
        while(result)
        {
                if (MAX_BIG == *(result->data+result->offset))
                {
                        break;
                }
                printf(" %d  ", *(result->data+result->offset));  
                result->offset++; 
                result=up(result->path+k);
        }
        printf("\n");

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值