外部排序

这是个外部排序的算法课作业

首先GenerateData()函数生成一个包含10*MAXN个随机int数据的文件data.txt。
然后Part()函数将其分为10个小文件。
接下来FileSort()函数分别对每一个小文件进行排序,并将排序以后的数据存入该小文件。
最后Merge()函数将各小文件中的数据归并到大文件finalsort.txt中。

几点说明:
1.本程序会自动生成数据文件,无需附属数据文件。
2.由于rand()函数只能生成32767以下的随机数,不能满足要求,我从网上找了一个产生随机数的程序。
3.MAXN是事先定义好的内存最大容量,我这里采用的是100万。
4.小文件排序采用的是快速排序。
5.Merge()的具体方法是每次从排序好的10小文件中取出最前面的数,放入优先队列中,从优先队列中拿出最小的放入finalsort.txt,并从该小文件中继续取出最前面的数放入优先队列中,如此反复直到最终优先队列为空。
6.本程序在i7-4790 CPU 3.60GHz 8G内存 64位台式机上运行时间为20.122秒。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define MAXN 1000000
FILE *f[15];
char name[15][15];
int a[MAXN+5];
struct num
{
    int id;
    int n;
    bool operator< (const num &num1) const
    {
        return n>num1.n;
    }
};
priority_queue<num> que;
/*************************** 以下为产生随机数的程序 ****************************************/
#define NN 624
#define MM 397
#define MATRIX_A 0x9908b0df   /* constant vector a */
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
#define LOWER_MASK 0x7fffffff /* least significant r bits */
#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y)  (y >> 11)
#define TEMPERING_SHIFT_S(y)  (y << 7)
#define TEMPERING_SHIFT_T(y)  (y << 15)
#define TEMPERING_SHIFT_L(y)  (y >> 18)

static unsigned long mt[NN]; /* the array for the state vector  */
static int mti=NN+1; /* mti==NN+1 means mt[NN] is not initialized */
void sgenrand(unsigned long seed)
{
    int i;
    for (i=0;i<NN;i++)
    {
        mt[i] = seed & 0xffff0000;
        seed = 69069 * seed + 1;
        mt[i] |= (seed & 0xffff0000) >> 16;
        seed = 69069 * seed + 1;
    }
    mti = NN;
}
void lsgenrand(unsigned long seed_array[])
{
    int i;
    for (i=0;i<NN;i++)
    mt[i] = seed_array[i];
    mti=NN;
}
double genrand()
{
    unsigned long y;
    static unsigned long mag01[2]={0x0, MATRIX_A};
    if (mti >= NN)
    {
        int kk;
        if (mti == NN+1) sgenrand(4357);
        for (kk=0;kk<NN-MM;kk++) {
            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+MM] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        for (;kk<NN-1;kk++) {
            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+(MM-NN)] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        y = (mt[NN-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
        mt[NN-1] = mt[MM-1] ^ (y >> 1) ^ mag01[y & 0x1];
        mti = 0;
    }
    y = mt[mti++]; y ^= TEMPERING_SHIFT_U(y); y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
    y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; y ^= TEMPERING_SHIFT_L(y);
    return y;
}

double randf(){ return ( (double)genrand() * 2.3283064370807974e-10 ); }
long long randi(unsigned long LIM){ return((unsigned long)genrand() % LIM); }

/********************** 以上为产生随机数的程序 ************************************/
//int RandInt(int maxvalue)
//{
//    int randvalue;
//    if(maxvalue<=0) return 0;
//    randvalue = (int)randi(maxvalue); //产生一个0到maxvalue-1的整数
//    return randvalue;
//}
void GenerateData()
{
    FILE *p;
    p=fopen("data.txt","w");
    for(int i=0; i<MAXN*10; i++)
        fprintf(p,"%d\n",randi(65535));
    fclose(p);
}
void Openfile()
{

    for(int i=0; i<10; i++)
    {
        for(int j=0; j<14; j++) name[i][j]='\0';
        strcpy(name[i],"file");
        name[i][4]=i+'0';
        strcat(name[i],".txt");
    }

//    for (int i = 0; i < 10; i++)
//    {
//        fprintf(f[i], "%d ", 34);
//    }
}
void Sort(int a[], int s, int t)
{

    if(s>=t) return ;
    int p=a[s],i=s,j=t;
    while(i<j)
    {
        //cout<<j<<endl;
        while(i<j&&a[j]>=p) j--;
        if(i<j) a[i++]=a[j];
        while(i<j&&a[i]<=p) i++;
        if(i<j) a[j--]=a[i];
    }
    a[i]=p;
    //cout<<s<<" "<<j<<" "<<t<<endl;
    Sort(a,s,i-1);
    Sort(a,i+1,t);

}
void FileSort(int i)
{

    int n=MAXN-1;

    f[i] = fopen(name[i], "r");
    //freopen(name[i],"r",stdin);
    //cout<<name[i]<<endl;
    for(int j=0; j<=n; j++)
    {
        fscanf(f[i],"%d",&a[j]);
        //cout<<a[j]<<endl;
    }
    //cout<<a[n-100]<<endl;
    fclose(f[i]);
    f[i] = fopen(name[i], "w");
    Sort(a,0,n);
    //cout<<a[n]<<endl;
    for(int j=0; j<=n; j++)
    {
        //cout<<a[j]<<endl;
        fprintf(f[i],"%d\n",a[j]);
    }

    fclose(f[i]);
}
void Part()
{
    int x;
    FILE *p;
    p=fopen("data.txt","r");
    for(int i=0; i<10; i++)
        f[i] = fopen(name[i], "w");
    for (int i = 0; i < 10; i++)
    {
        for(int j=0; j<MAXN; j++)
        {
            fscanf(p,"%d",&x);
            fprintf(f[i], "%d\n", x);
        }

    }
    fclose(p);
    for(int i=0; i<10; i++)
        fclose(f[i]);
}
void Merge()
{
    int x;
    FILE *p;
    num a;
    p=fopen("finalsort.txt","w");
    for(int i=0; i<10; i++)
        f[i] = fopen(name[i], "r");
    for (int i = 0; i < 10; i++)
    {
        fscanf(f[i],"%d",&x);
        a.id=i;
        a.n=x;
        que.push(a);

    }
    while(!que.empty())
    {
        a=que.top();
        que.pop();
        fprintf(p, "%d\n", a.n);

        int i=a.id;
        if(!feof(f[i]))
        {
            fscanf(f[i],"%d",&x);
            a.n=x;
            que.push(a);
        }

    }


    fclose(p);
    for(int i=0; i<10; i++)
        fclose(f[i]);
}
int main()
{
    srand((unsigned)time(0));
    Openfile();
    GenerateData();
    Part();
    for(int i=0; i<10; i++)
        FileSort(i);
    Merge();
    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值