多路归并排序的实现

来源:互联网 发布:淘宝男休闲运动皮鞋 编辑:程序博客网 时间:2024/06/07 05:00

为了更好地测试程序,首先利用以下方法生成了1000000个整数,每个整数均不相同:

//生成随机排列的1000000个数字,每个数字都不相同    const int size = 1000000;    int num[size];    void produce(){        int i,x,y;        FILE *f = fopen("data.txt","w");        assert(f);        for(i=0;i<size;++i){            num[i] = i;        }        srand((unsigned)time(NULL));        //随机交换随机的两个数字        for(i=0;i<size;++i){                 x = (rand()*RAND_MAX+rand())%size;            y = (rand()*RAND_MAX+rand())%size;            swap(num[x],num[y]);        }        for(i=0;i<size;++i){            fprintf(f,"%d ",num[i]);        }        fclose(f);    }

多路归并的主要包括两个步骤,第一个步骤是对划分好的小数据块进行内部排序,第二步是归并所有的小数据块:

首先是内部排序,在此将1000000个数据分成十份,利用库函数qsort()进行排序,将排好序的子数据块分别写入是个文件中:

const int fcount = 100000;int tmp[fcount];      //内存中临时数组int compare(const void *first_num, const void *second_num){    return *(int *)first_num - *(int *)second_num;}void innersort(string infname,int filenum){    clock_t begin = clock();    FILE *fin = fopen(infname.c_str(),"r");    int i,j,filecount=0;    char fileout[20];    while(filecount<filenum){        ++filecount;        sprintf(fileout,"tmp%d.txt",filecount);        FILE* fout = fopen(fileout,"w");        for(i=0;i<fcount;++i){            fscanf(fin,"%d",&tmp[i]);        }        qsort(tmp,fcount,sizeof(int),compare);    //调用系统函数快排        for(i=0;i<fcount;++i){            fprintf(fout,"%d ",tmp[i]);        }        fclose(fout);    }    fclose(fin);    clock_t end = clock();    cout<<"内排时间用去: "<<end-begin<<"ms"<<endl;}

然后是归并多个子数据块:

void externsort(int filenum){    clock_t begin = clock();    FILE **fin = new FILE*[filenum];    FILE* fout = fopen("sorted_result.txt","w");    int i,j,min;    char finname[20];    int *first_num = new int[filenum];    bool *finish = new bool[filenum];        //若当前文件读取完毕则为true    for(i=1;i<=filenum;++i){        sprintf(finname,"tmp%d.txt",i);        fin[i-1] = fopen(finname,"r");        fscanf(fin[i-1],"%d",&first_num[i-1]);    //读取每个文件中的第一个数字        finish[i-1] = false;                    //初始化    }    while(true){        j=0;        while(j<filenum && finish[j])            ++j;        if(j == filenum)            break;                //全部文件读取完毕        min = first_num[j];          //j用于记录最小值对应的文件号        for(i = j+1;i<filenum && !finish[i];++i)        {            if(min > first_num[i]){                min = first_num[i];                j = i;                            }        }        fprintf(fout,"%d ",min);        if(fscanf(fin[j],"%d",&first_num[j])==EOF){            finish[j] = true;        }    }    fclose(fout);    delete[] first_num;    delete[] finish;    for(i=0;i<filenum;++i){            fclose(fin[i]);    }    delete [] fin;    clock_t end = clock();    cout<<"外排时间用去: "<<end-begin<<"ms"<<endl;}

最后在我的渣渣机器上跑的时间:
这里写图片描述

原创粉丝点击