1.算法思想
归并排序的思想 将已经排序的文件进行合并 得到完全排序的文件 合并时只要比较各个子文件的第一个记录的排序码最小的那个记录就是排序后的第1个记录 取出这记录然后继续比较各子文件的第1个记录 便可找出排序后的第二个记录 如此反复 对每个文件经过一趟扫描 便可得到最终的排序结果
2.算法实现
sort.h
struct forSort
{
int key[3];
struct forSort *next;
};
typedef struct forSort ForSort;
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sort.h"
void MergeSort(ForSort A[],int n)
{
int k;
ForSort *B =(ForSort * ) malloc(n*sizeof(ForSort));
//初始化子文件长度为1*/
k=1;
while(k<n)
{
//将A 中的子文件经过一趟归并存储到数组 B*/
//k 文件长度
//n 待排序文件记录数
OnePassMerge(B,A,k,n);
//归并后文件增加一倍
k<<1;
if(k<=n)
//已归并排序完毕 ,单结果在临时数组B中调用标准函数memcpy()将其复制到A 中。memcpy() 包含在头文件<memory.h> 或者<string.h> 中
memcpy(A,B,n*sizeof(ForSort));
else
{
//将B 中的子文件经过一趟归并存储到数组A 中
OnePassMerge(A,B,k,n);
//归并后文件长度增加1倍
k<<=1;
}
}
}
//一趟两组归并
// 一趟归并函数 将src中部分排序的多个文件归并到Dst中 子文件的长度为Len */
void OnePassMerge(ForSort Dst[],ForSort Src[],int Len,int n)
{
int i;
for(i=0; i<n-2*Len; i+=2*Len)
//执行两两归并 将Src 中长度为Len 的子文件归并成长度为2*Len的子文件,结果存放在Dst 中*/
TwoWayMerge(Dst,Src,i,i+Len-1,i+2*Len-1);
if(i<n-Len)
//尾部至多还有两个子文件
TwoWayMerge(Dst,Src,i,i+Len-1,n-1);
else
/*尾部可能还有一个子文件,直接复制到Dst中*/
memcpy(&Dst[i],&Src,(n-i)*sizeof(ForSort));
}
/* 两两归并函数,将 Src 中从s到s1 的子文件和从e1+1 到e2的子文件进行归并 结果存放Dst中 从s开始的位置*/
void TwoWayMerge(ForSort Dst[],ForSort Src[],int s,int e1,int e2)
{
int s1,s2;
for(s1=s,s2=e1+1; s1<=e1 && s2<=e2;)
if(Src[s1].key<=Src[s2].key)
/*第一个子文件最前面记录其排序码小,将其归并到Dst */
Dst[s++]=Src[s++];
else
// 第二个子文件最前面记录其排序码小 将其归并到Dst
Dst[s++]=Src[s2++];
if(s1<=e1)
//第一个子文件未归并完,将其直接复制到Dst中
memcpy(&Dst[s],&Src[s1],(e1-s1+1)*sizeof(ForSort));
else
//从第二个子文件未归并完 将其直接复制到Dst中
memcpy(&Dst[s],&Src[s1],(e2-s2+1)*sizeof(ForSort));
}
int main()
{
return 0;
}